diff --git a/app/build.gradle b/app/build.gradle
index facb8d416d92e3c366df573a29ac9acb5fe1c683..7439189f8504b1600e2f475171f8afbd9fd5a88b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -632,6 +632,7 @@ dependencies {
//RecyclerView header
implementation 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
+ implementation 'com.android.support:recyclerview-v7:23.28.0.0'
//navigation
implementation 'ru.terrakok.cicerone:cicerone:3.0.0'
@@ -676,8 +677,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Conference, Calls mobile SDK
- implementation 'com.nynja.sdk:NynjaSdk:1.20.7@aar'
- //implementation(name: 'NynjaSdk-1.20.6', ext: 'aar')
+ implementation 'com.nynja.sdk:NynjaSdk:1.21@aar'
+ //implementation(name: 'NynjaSdk-1.21', ext: 'aar')
//ExoPlayer
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.6'
diff --git a/app/src/Superapp/res/values-en/strings.xml b/app/src/Superapp/res/values-en/strings.xml
index 4fa5447bdcab516d52d50c7618f80315de2519aa..fd4bc8680eb67cc2e7160f75b5944055bc82e220 100644
--- a/app/src/Superapp/res/values-en/strings.xml
+++ b/app/src/Superapp/res/values-en/strings.xml
@@ -5,9 +5,9 @@
Introducing an amazing new platform called NYNJA! It is a productivity and communications aggregator platform. Download it here: https://www.nynja.io/mobile and add me as a contact with my NYNJA user ID: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/Superapp/res/values-es/strings.xml b/app/src/Superapp/res/values-es/strings.xml
index 78812d62f36c19ce48f6a9d2551cf42156654d72..3cb971897dbd9f849b1a94ad1c74f5b31fb4e965 100644
--- a/app/src/Superapp/res/values-es/strings.xml
+++ b/app/src/Superapp/res/values-es/strings.xml
@@ -5,9 +5,9 @@
¡Presentamos una nueva y sorprendente plataforma llamada NYNJA! Es una plataforma agregadora de comunicaciones y productividad. Descárgala aquí: https://www.nynja.io/mobile y agrégame como contacto con mi ID de usuario NYNJA: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/Superapp/res/values-ko/strings.xml b/app/src/Superapp/res/values-ko/strings.xml
index e7d0c196c28baaba3d883e8b63fda65cd0523e1c..7d4eb06e4601b351064e6463e17a2a2edee97b92 100644
--- a/app/src/Superapp/res/values-ko/strings.xml
+++ b/app/src/Superapp/res/values-ko/strings.xml
@@ -5,9 +5,9 @@
새로운 플랫폼 NYNJA를 소개합니다! 다양한 커뮤니케이션 웹사이트 플랫폼입니다. https://www.nynja.io/mobile 여기에서 다운로드 후, NYNJA 사용자 ID: %1$s 연락처로 저를 추가하세요
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/Superapp/res/values-zh-rCN/strings.xml b/app/src/Superapp/res/values-zh-rCN/strings.xml
index e11af5132360de7c42456221db7fbdd330d46e97..66e01815f8e7fc7672c0b0e2fd3cdffde60d16c4 100644
--- a/app/src/Superapp/res/values-zh-rCN/strings.xml
+++ b/app/src/Superapp/res/values-zh-rCN/strings.xml
@@ -5,9 +5,9 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/Superapp/res/values-zh/strings.xml b/app/src/Superapp/res/values-zh/strings.xml
index e11af5132360de7c42456221db7fbdd330d46e97..66e01815f8e7fc7672c0b0e2fd3cdffde60d16c4 100644
--- a/app/src/Superapp/res/values-zh/strings.xml
+++ b/app/src/Superapp/res/values-zh/strings.xml
@@ -5,9 +5,9 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/Superapp/res/values/strings.xml b/app/src/Superapp/res/values/strings.xml
index 4fa5447bdcab516d52d50c7618f80315de2519aa..fd4bc8680eb67cc2e7160f75b5944055bc82e220 100644
--- a/app/src/Superapp/res/values/strings.xml
+++ b/app/src/Superapp/res/values/strings.xml
@@ -5,9 +5,9 @@
Introducing an amazing new platform called NYNJA! It is a productivity and communications aggregator platform. Download it here: https://www.nynja.io/mobile and add me as a contact with my NYNJA user ID: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/auth/AppSignatureHelper.java b/app/src/main/java/com/nynja/mobile/communicator/data/auth/AppSignatureHelper.java
index ee914486f0e18bfbed59affeeb0bfb14d0064378..412c56cc4defed54c3932051c973866c84124c24 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/auth/AppSignatureHelper.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/auth/AppSignatureHelper.java
@@ -66,10 +66,10 @@ public class AppSignatureHelper extends ContextWrapper {
String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);
- Timber.v("sms_sample_test pkg: %s -- hash: %s", packageName, base64Hash);
+ Timber.v("Nynja pkg: %s -- hash: %s", packageName, base64Hash);
return base64Hash;
} catch (NoSuchAlgorithmException e) {
- Timber.v("sms_sample_test hash:NoSuchAlgorithm");
+ Timber.v("Nynja hash:NoSuchAlgorithm");
}
return null;
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/calls/ActiveCallBase.java b/app/src/main/java/com/nynja/mobile/communicator/data/conference/ActiveCallBase.java
similarity index 81%
rename from app/src/main/java/com/nynja/mobile/communicator/data/calls/ActiveCallBase.java
rename to app/src/main/java/com/nynja/mobile/communicator/data/conference/ActiveCallBase.java
index ed56871a44cbe51b6234e276b27c96b85fc608e5..fce484df70291f732c2b534815501c5316c692a3 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/calls/ActiveCallBase.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/conference/ActiveCallBase.java
@@ -1,4 +1,4 @@
-package com.nynja.mobile.communicator.data.calls;
+package com.nynja.mobile.communicator.data.conference;
import com.nynja.mobile.communicator.utils.StringUtils;
@@ -27,15 +27,12 @@ public abstract class ActiveCallBase {
public boolean isSpeakerOn;
public AudioRouteType mAudioRouteType;
public boolean isCallInProgress;
- public boolean isOwnStreamActive;
public boolean isRinging;
public boolean isSwitchToAudio;
public boolean isVideoEnabled;
public boolean isVideoFullScreen;
public boolean isScreenShareEnabled;
public long mCallStartTime; // in miliseconds
- public boolean hasRemoteVideoTrack;
- public boolean hasRemoteScreenShareTrack;
public boolean mIsAdHock;
public ActiveCallBase(String endPointId, CallType callType, boolean videoEnabled, boolean outgoingCall) {
@@ -43,10 +40,8 @@ public abstract class ActiveCallBase {
mCallType = callType;
mEndPointId = (endPointId == null) ? "" : endPointId;
mCallStartTime = -1;
- isVideoEnabled = (callType == CallType.P2PCall);
+ isVideoEnabled = true;//(callType == CallType.P2PCall);
isVideoFullScreen = false;
- hasRemoteVideoTrack = false;
- isOwnStreamActive = videoEnabled;
isOutgoingCall = outgoingCall;
isMuted = false;
isSpeakerOn = false;
@@ -54,7 +49,6 @@ public abstract class ActiveCallBase {
isRinging = false;
isCallInProgress = false;
isSwitchToAudio = false;
- hasRemoteScreenShareTrack = false;
isScreenShareEnabled = true;
mIsAdHock = (isOutgoingCall &&
(callType == CallType.ConferenceCall) &&
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/conference/ConferenceVideoModule.java b/app/src/main/java/com/nynja/mobile/communicator/data/conference/ConferenceVideoModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf856e2b93332c0dc9fa952904291d57ee56aef3
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/conference/ConferenceVideoModule.java
@@ -0,0 +1,232 @@
+package com.nynja.mobile.communicator.data.conference;
+
+import com.nynja.mobile.communicator.NynjaApp;
+import com.nynja.mobile.communicator.data.DataManager;
+import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
+import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+import com.nynja.mobile.communicator.utils.StringUtils;
+import com.nynja.sdk.NYNCallParticipant;
+
+import org.webrtc.SurfaceViewRenderer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+import kotlin.jvm.Synchronized;
+
+public class ConferenceVideoModule {
+
+ private static ConferenceVideoModule mInstance = null;
+ public static final int MAX_VIDEO_FEEDS_COLUIMN_SIZE = 2;
+ public static final int MAX_VIDEO_FEEDS_ROW_SIZE = 2;
+ public static final int MAX_VIDEO_FEEDS_COUNT_PER_PAGE = MAX_VIDEO_FEEDS_COLUIMN_SIZE*MAX_VIDEO_FEEDS_ROW_SIZE;
+
+ private DataManager mDataManager;
+ // Call worker object
+ private ActiveConferenceCall mCurrentActiveCall;
+
+ public int mActiveVideoParticipantsCount = 0;
+ public HashMap mActiveVideoParticipantsMap= new HashMap<>();
+
+
+ private ConferenceVideoModule() {
+ init();
+ }
+
+ public static ConferenceVideoModule getInstance() {
+ if (mInstance == null) {
+ mInstance = new ConferenceVideoModule();
+ }
+ return mInstance;
+ }
+
+ private void init() {
+ // ToDo:...
+ mCurrentActiveCall = null;
+ mDataManager = NynjaApp.getComponent().dataManager();
+ mActiveVideoParticipantsCount = 0;
+ }
+
+ public void reset() {
+ // ToDo:...
+ mActiveVideoParticipantsMap.clear();
+ mCurrentActiveCall = null;
+ }
+
+ public void setCurrentActiveCall(ActiveConferenceCall currentActiveCall) {
+ if (mCurrentActiveCall != currentActiveCall) {
+ mCurrentActiveCall = currentActiveCall;
+ }
+ }
+
+ public void setVideoRendererForTrack(SurfaceViewRenderer videoFeed, String trackId, boolean isLocal) {
+ if (mCurrentActiveCall != null && mCurrentActiveCall.mConference != null) {
+ if (isLocal) {
+ mCurrentActiveCall.mConference.setLocalVideoRenderer(videoFeed);
+ } else {
+ mCurrentActiveCall.mConference.setRemoteVideoRenderer(videoFeed, trackId);
+ }
+ }
+ }
+
+ public void enableVideoForTrack(String participantId, boolean enable) {
+ if (mCurrentActiveCall != null && mCurrentActiveCall.mConference != null) {
+ mCurrentActiveCall.mConference.enableVideoForTrack(participantId, enable);
+ }
+ }
+
+ public String getTrackIdByParticipantId(String participantId) {
+ String trackId = "";
+ if (mCurrentActiveCall != null) {
+ trackId = mCurrentActiveCall.mData.getTrackIdForParticipant(participantId);
+ }
+ return trackId;
+ }
+
+ @Synchronized
+ public ArrayList getConferenceVideoMembers(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall == null) return new ArrayList<>();
+ Set participatIds = mActiveVideoParticipantsMap.keySet();
+ mActiveVideoParticipantsMap.clear();
+ synchronized (activeConferenceCall.mData.mParticipantArray) {
+ if (activeConferenceCall.mData.mParticipantArray != null) {
+ for (int index = 0; index < activeConferenceCall.mData.mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = activeConferenceCall.mData.mParticipantArray.get(index);
+ if (participant.hasVideo() || (participant.isMe() && activeConferenceCall.mData.isOwnStreamActive)) {
+ ConferenceListItem item = conferenceParticipant(participant, participant.isOwner(), activeConferenceCall.mData.isOwnStreamActive);
+ mActiveVideoParticipantsMap.put(item.participantId, item);
+ }
+ }
+ }
+ }
+
+ for (String participantId : participatIds) {
+ if (!mActiveVideoParticipantsMap.containsKey(participantId)) {
+ enableVideoForTrack(participantId, false);
+ String trackId = getTrackIdByParticipantId(participantId);
+ setVideoRendererForTrack(null, trackId, StringUtils.isEmpty(trackId));
+ }
+ }
+ ArrayList items = new ArrayList<>(mActiveVideoParticipantsMap.values());
+ mActiveVideoParticipantsCount = items.size();
+ return items;
+ }
+
+ @Synchronized
+ public ArrayList getUpdatedActiveSpeakersParticipants(ArrayList participantIds) {
+ ArrayList items = new ArrayList<>(mActiveVideoParticipantsMap.values());
+ for (ConferenceListItem item : items) {
+ item.isSpeaking = false;
+ for (String participandId : participantIds) {
+ if (participandId.contentEquals(item.participantId)) {
+ item.isSpeaking = true;
+ }
+ }
+ }
+ return items;
+ }
+
+ public float getSpanSize(int position) {
+ if (getWidthDiv(position) == 1 && getHeightDiv(position) == 1) return 1;
+ return MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+ }
+
+ public int getWidthDividerLength(int position) {
+ if (mActiveVideoParticipantsCount/MAX_VIDEO_FEEDS_COLUIMN_SIZE <= MAX_VIDEO_FEEDS_ROW_SIZE) {
+ return mActiveVideoParticipantsCount / MAX_VIDEO_FEEDS_COLUIMN_SIZE + 1; //MAX_VIDEO_FEEDS_ROW_SIZE + 1;
+ }
+ int lastPageBeginer = ((mActiveVideoParticipantsCount / MAX_VIDEO_FEEDS_COUNT_PER_PAGE) * MAX_VIDEO_FEEDS_COUNT_PER_PAGE);
+ if (mActiveVideoParticipantsCount == lastPageBeginer) {
+ lastPageBeginer = mActiveVideoParticipantsCount - MAX_VIDEO_FEEDS_COUNT_PER_PAGE;
+ }
+
+ if (position < lastPageBeginer) {
+ return MAX_VIDEO_FEEDS_COUNT_PER_PAGE / MAX_VIDEO_FEEDS_COLUIMN_SIZE - 1;
+ }
+
+ int row = (mActiveVideoParticipantsCount - lastPageBeginer)/MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+ if (row <= MAX_VIDEO_FEEDS_ROW_SIZE) {
+ int rest = (mActiveVideoParticipantsCount - lastPageBeginer)%MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+ if (rest == 0) {
+ if (row < MAX_VIDEO_FEEDS_ROW_SIZE) return row;
+ if (position/lastPageBeginer == 1) return row + 1;
+ return row - 1;
+ }
+ return row + 1;
+ }
+
+ return row-1;
+ }
+
+ private int widthDivider(int count) {
+ if (count <= MAX_VIDEO_FEEDS_COUNT_PER_PAGE) {
+ if ((count % MAX_VIDEO_FEEDS_COLUIMN_SIZE) == 0) {
+ return count / MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+ }
+ }
+ return count / MAX_VIDEO_FEEDS_COLUIMN_SIZE + 1;
+ }
+
+ private int lastPageWidthDivider(int position) {
+ switch (position % MAX_VIDEO_FEEDS_COUNT_PER_PAGE) {
+ case 0: {
+ if (position == mActiveVideoParticipantsCount - 1) return 1;
+ if (position == mActiveVideoParticipantsCount - 2) return 1;
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+ case 1: {
+ if (position == mActiveVideoParticipantsCount - 1) return 1;
+ if (position == mActiveVideoParticipantsCount - 2) return MAX_VIDEO_FEEDS_ROW_SIZE;
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+ case 2: {
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+ // next 3 items span 2 columns each
+ case 3: {
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+ }
+
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+
+ private int lastPageWidthDivider2(int lastPageCount) {
+ if (lastPageCount < MAX_VIDEO_FEEDS_COLUIMN_SIZE) return 1;
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+
+ public int getWidthDiv(int position) {
+ if (mActiveVideoParticipantsCount <= MAX_VIDEO_FEEDS_COLUIMN_SIZE) return 1;
+ if (mActiveVideoParticipantsCount <= MAX_VIDEO_FEEDS_COUNT_PER_PAGE) {
+ return widthDivider(mActiveVideoParticipantsCount);
+ }
+ int lastPageBeginer = ((mActiveVideoParticipantsCount / MAX_VIDEO_FEEDS_COUNT_PER_PAGE)
+ * MAX_VIDEO_FEEDS_COUNT_PER_PAGE);
+ if (position < lastPageBeginer) {
+ return MAX_VIDEO_FEEDS_ROW_SIZE;
+ }
+ return lastPageWidthDivider2(mActiveVideoParticipantsCount - lastPageBeginer);
+ }
+
+ public int getHeightDiv(int position) {
+ if (mActiveVideoParticipantsCount < MAX_VIDEO_FEEDS_COLUIMN_SIZE) return 1;
+ return MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+ }
+
+ protected ConferenceListItem conferenceParticipant(NYNCallParticipant participant,
+ boolean isModerator,
+ boolean isOwnStreamActive) {
+ ContactModel user = mDataManager.getContactsByPhoneId(participant.getAddress());
+ ConferenceListItem conferenceListItem = ConferenceListItem.fromSdkParticipant(participant, (user != null), isOwnStreamActive);
+ if (user != null) {
+ conferenceListItem.avatar = user.avatar;
+ }
+ if (isModerator) conferenceListItem.type = ConferenceListItem.ConferenceItemType.Moderator;
+
+ return conferenceListItem;
+ }
+
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/ConferenceSDKPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/ConferenceSDKPresenter.java
index 2072ed2aa5ce2d036fb8cc28b0e472c027bc864a..9c1ae7305cc79a10464f28039f47b09147fe0dd1 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/ConferenceSDKPresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/ConferenceSDKPresenter.java
@@ -1,6 +1,6 @@
package com.nynja.mobile.communicator.data.sdk;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
import com.nynja.mobile.communicator.data.sdk.calls.ConferenceSDKListener;
import com.nynja.mobile.communicator.data.sdk.calls.RejoinConferenceCallData;
@@ -9,6 +9,8 @@ import com.nynja.mobile.communicator.mvp.view.ErrorMvpView;
import com.nynja.sdk.NYNCall;
import com.nynja.sdk.NYNCallHistoryCode;
+import java.util.ArrayList;
+
/**
* Created by Ergyun Syuleyman on 4/25/18.
*/
@@ -53,6 +55,8 @@ public abstract class ConferenceSDKPresenter extends Bas
@Override public void onScreenShareState(boolean active) {}
+ @Override public void onStartCapturerFailed(int msgResId, boolean isCamera) {}
+
@Override public void onRemoteScreenShareTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) {}
@Override public void onRemoteScreenShareTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) {}
@@ -73,7 +77,7 @@ public abstract class ConferenceSDKPresenter extends Bas
@Override public void tryCallCameraStateChange(boolean pause) {}
- @Override public void onActiveSpeakersUpdate(String activeSpeakers) {}
+ @Override public void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds) {}
@Override public void onMuteStateChangedByHost(boolean isMuted) {}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java
index d9777cef7070c7f84e012b80c60e74bdab2571fc..d613e9b7b8eed76bf948cd2c044940e4505a2c56 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java
@@ -1,16 +1,14 @@
package com.nynja.mobile.communicator.data.sdk.calls;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
import com.nynja.mobile.communicator.utils.Consts;
import com.nynja.mobile.communicator.utils.StringUtils;
import com.nynja.sdk.NYNCall;
import com.nynja.sdk.NYNCallParticipant;
-import com.nynja.sdk.NYNCallParticipantArray;
import com.nynja.sdk.NYNCallRoomType;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* Created by Ergyun Syuleyman on 4/19/18.
@@ -20,39 +18,36 @@ public class ActiveConferenceCall extends ActiveCallBase {
private ArrayList mMembers;
public NYNCall mConference;
- public NYNCallParticipantArray mParticipantArray;
public String mMyDisplayName;
- public String mMyPhoneId;
public boolean mIsSpeakerForceStopped;
public boolean mPartial;
- public int mParticipantsCountLimit;
public boolean mInitialStartCapturer;
- public String mRemoteSSTrackId;
- public String mRemoteVideoTrackId;
public boolean mWaiting;
public boolean mAutoCreateAndStart;
- public HashMap mActiveTracks;
+ public ConferenceCallData mData;
- public static final int CONFERENCE_PARTICIPANTS_COUNT_LIMIT = 1000;
public static final int ANDROID_10_PUSH_CALL_NTFN_ID = 1234567890;
public ActiveConferenceCall(NYNCall conference, String endPointId,
CallType callType, boolean isVideoEnabled, boolean outgoingCall) {
super(endPointId, callType, isVideoEnabled, outgoingCall);
+ mData = new ConferenceCallData((callType == CallType.P2PCall), isVideoEnabled);
mConference = conference;
mMembers = new ArrayList();
mMyDisplayName = "";
- mMyPhoneId = "";
mIsSpeakerForceStopped = false;
mPartial = false;
- mParticipantsCountLimit = CONFERENCE_PARTICIPANTS_COUNT_LIMIT; // default limit - if cannot get from sdk
mInitialStartCapturer = isVideoEnabled;
- mRemoteSSTrackId = "";
- mRemoteVideoTrackId = "";
mWaiting = false;
mAutoCreateAndStart = false;
- mActiveTracks = new HashMap<>();
+ }
+
+ void setInternalCall(NYNCall conference) {
+ mConference = conference;
+ if (conference != null) {
+ mData.mParticipantArray = conference.getParticipants();
+ }
}
public void setMembers(ArrayList members) {
@@ -103,7 +98,7 @@ public class ActiveConferenceCall extends ActiveCallBase {
public boolean isCameraRunning() {
return (mConference != null
- && isOwnStreamActive
+ && mData.isOwnStreamActive
&& isCallInProgress()
&& mConference.isCameraRunning());
}
@@ -127,10 +122,10 @@ public class ActiveConferenceCall extends ActiveCallBase {
public boolean isParticipateInConference(String memberId) {
if (memberId == null) return false;
- if (mParticipantArray == null) return false;
+ if (mData.mParticipantArray == null) return false;
- for (int index = 0; index < mParticipantArray.size(); index++) {
- NYNCallParticipant participant = mParticipantArray.get(index);
+ for (int index = 0; index < mData.mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = mData.mParticipantArray.get(index);
if (participant.getMemberId().contentEquals(memberId)) {
return true;
}
@@ -145,7 +140,8 @@ public class ActiveConferenceCall extends ActiveCallBase {
}
public boolean isConference() {
- return (mConference != null && mConference.isConference());
+ return (mConference != null &&
+ (mConference.isConference() || mCallType == CallType.ConferenceCall));
}
public String getConferenceRoomId() {
@@ -161,24 +157,7 @@ public class ActiveConferenceCall extends ActiveCallBase {
return null;
}
- public String getConferenceModeratorName() {
- if (mParticipantArray != null) {
- for (int index = 0; index < mParticipantArray.size(); index++) {
- NYNCallParticipant participant = mParticipantArray.get(index);
- if (participant.isOwner()) {
- return participant.getName();
- }
- }
- }
- return "";
-
- }
-
public String getConferenceSSOwner() {
- String participanId = "";
- if (mActiveTracks.containsKey(mRemoteSSTrackId)) {
- participanId = mActiveTracks.get(mRemoteSSTrackId);
- }
boolean isP2P = (mConference != null && !mConference.isConference());
if (isP2P) {
if (mConference.isOutgoing()) {
@@ -187,17 +166,8 @@ public class ActiveConferenceCall extends ActiveCallBase {
return mConference.caller();
}
} else {
- if (mParticipantArray != null ) {
- for (int index = 0; index < mParticipantArray.size(); index++) {
- NYNCallParticipant participant = mParticipantArray.get(index);
- if (participanId.contentEquals(participant.getParticipantId())) {
- return participant.getName();
- }
- }
- }
+ return mData.getConferenceSSOwner();
}
-
- return getConferenceModeratorName();
}
@@ -225,9 +195,9 @@ public class ActiveConferenceCall extends ActiveCallBase {
", isSpeakerOn=" + isSpeakerOn +
", mAudioRouteType=" + mAudioRouteType.toString() +
", mConference=" + mConference +
- ", isOwnStreamActive=" + isOwnStreamActive +
- ", hasRemoteVideoTrack=" + hasRemoteVideoTrack +
- ", hasRemoteScreenShareTrack=" + hasRemoteScreenShareTrack +
+ ", isOwnStreamActive=" + mData.isOwnStreamActive +
+ ", hasRemoteVideoTrack=" + mData.hasRemoteVideoTrack +
+ ", hasRemoteScreenShareTrack=" + mData.hasRemoteScreenShareTrack +
", isVideoEnabled=" + isVideoEnabled +
", isCallInProgress=" + isCallInProgress +
", isRinging=" + isRinging +
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceCallData.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceCallData.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f4042828852457c7412b222bb685a3a82509465
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceCallData.java
@@ -0,0 +1,148 @@
+package com.nynja.mobile.communicator.data.sdk.calls;
+
+import com.nynja.mobile.communicator.utils.StringUtils;
+import com.nynja.sdk.NYNCallParticipant;
+import com.nynja.sdk.NYNCallParticipantArray;
+
+import java.util.HashMap;
+
+/**
+ * Created by Ergyun Syuleyman on 04/03/2020.
+ */
+
+public class ConferenceCallData {
+
+ public static final int CONFERENCE_PARTICIPANTS_COUNT_LIMIT = 1000;
+
+ public NYNCallParticipantArray mParticipantArray;
+ public int mParticipantsCountLimit;
+ public String mRemoteSSTrackId;
+ public String mRemoteVideoTrackId;
+ public HashMap mActiveTracks;
+ public HashMap mActiveParticipanTracks;
+ public HashMap mActiveParticipanSSTracks;
+ public boolean hasRemoteVideoTrack;
+ public boolean hasRemoteScreenShareTrack;
+ public boolean mIsConference;
+ public boolean isOwnStreamActive;
+
+ public ConferenceCallData() {
+ init();
+ mIsConference = false;
+ }
+
+ public ConferenceCallData(boolean isConference, boolean videoEnabled) {
+ init();
+ mIsConference = isConference;
+ isOwnStreamActive = videoEnabled;
+ }
+
+ private void init() {
+ mParticipantsCountLimit = CONFERENCE_PARTICIPANTS_COUNT_LIMIT; // default limit - if cannot get from sdk
+ mRemoteSSTrackId = "";
+ mRemoteVideoTrackId = "";
+ mActiveTracks = new HashMap<>();
+ mActiveParticipanTracks = new HashMap<>();
+ mActiveParticipanSSTracks = new HashMap<>();
+ hasRemoteVideoTrack = false;
+ hasRemoteScreenShareTrack = false;
+ }
+
+ public void onRemoteVideoAdded(String trackId, String participantId) {
+ hasRemoteVideoTrack = true;
+ mActiveTracks.put(trackId, participantId);
+ mActiveParticipanTracks.put(participantId, trackId);
+ mRemoteVideoTrackId = trackId;
+ }
+
+ public void onRemoteVideoRemoved(String trackId, String participantId) {
+ mActiveTracks.remove(trackId);
+ mActiveParticipanTracks.remove(participantId);
+ hasRemoteVideoTrack = !isRemoteVideoTracksEmpty();
+ mRemoteVideoTrackId = "";
+ }
+
+ public void onRemoteSSAdded(String trackId, String participantId) {
+ hasRemoteScreenShareTrack = true;
+ mActiveTracks.put(trackId, participantId);
+ mActiveParticipanSSTracks.put(participantId, trackId);
+ mRemoteSSTrackId = trackId;
+ }
+
+ public void onRemoteSSRemoved(String trackId, String participantId) {
+ hasRemoteScreenShareTrack = false;
+ mActiveTracks.remove(trackId);
+ mActiveParticipanSSTracks.remove(participantId);
+ mRemoteSSTrackId = "";
+ }
+
+ public String getParticipantIdForTrack(String trackId) {
+ if (StringUtils.isEmpty(trackId)) return "";
+ if (mActiveTracks.containsKey(trackId)) {
+ return mActiveTracks.get(trackId);
+ }
+
+ return "";
+ }
+
+ public String getTrackIdForParticipant(String participantId) {
+ return getTrackIdForParticipant(participantId, true);
+ }
+
+ public String getScreenTrackIdForParticipant(String participantId) {
+ return getTrackIdForParticipant(participantId, false);
+ }
+
+ protected String getTrackIdForParticipant(String participantId, boolean isVideo) {
+ if (StringUtils.isEmpty(participantId)) return "";
+ if (isVideo) {
+ if (mActiveParticipanTracks.containsKey(participantId)) {
+ return mActiveParticipanTracks.get(participantId);
+ }
+ } else {
+ if (mActiveParticipanSSTracks.containsKey(participantId)) {
+ return mActiveParticipanSSTracks.get(participantId);
+ }
+ }
+
+ return "";
+ }
+
+ public String getConferenceSSOwner() {
+ if (mParticipantArray != null ) {
+ String participanId = getParticipantIdForTrack(mRemoteSSTrackId);
+ if (StringUtils.isEmpty(participanId)) return "";
+ for (int index = 0; index < mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = mParticipantArray.get(index);
+ if (participanId.contentEquals(participant.getParticipantId())) {
+ return participant.getName();
+ }
+ }
+ }
+
+ return getConferenceModeratorName();
+ }
+
+ public String getConferenceModeratorName() {
+ if (mParticipantArray != null) {
+ for (int index = 0; index < mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = mParticipantArray.get(index);
+ if (participant.isOwner()) {
+ return participant.getName();
+ }
+ }
+ }
+
+ return "";
+ }
+
+ public boolean isRemoteVideoTracksEmpty() {
+ return !(mActiveParticipanTracks.size() > 0 &&
+ mActiveTracks.size() > 0);
+ }
+
+ public boolean hasRemoteVideoTrack() {
+ return (hasRemoteVideoTrack &&
+ !isRemoteVideoTracksEmpty());
+ }
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceListItem.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceListItem.java
index 980d2a4e947d9fe30b8c02627fd0917d3aa778e8..e44ee8610cdb0882da1e30bde6e954d364740698 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceListItem.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceListItem.java
@@ -1,9 +1,8 @@
package com.nynja.mobile.communicator.data.sdk.calls;
-import android.content.Context;
-
import com.nynja.mobile.communicator.R;
import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
+import com.nynja.mobile.communicator.utils.StringUtils;
import com.nynja.sdk.NYNCallParticipant;
import java.util.ArrayList;
@@ -14,7 +13,7 @@ import io.reactivex.annotations.NonNull;
* Created by Ergyun Syuleyman on 5/27/18.
*/
-public class ConferenceListItem {
+public class ConferenceListItem extends Object {
// Conference items in Grid view type
public enum ConferenceItemType {
Plus,
@@ -39,6 +38,9 @@ public class ConferenceListItem {
public boolean hasScreen;
public boolean isVideoPaused;
public boolean isScreenPaused;
+ public int isTrackActive;
+ public boolean isVideoFullScreen;
+ public boolean isSpeaking;
protected ConferenceListItem() {
phoneId = "";
@@ -53,6 +55,9 @@ public class ConferenceListItem {
hasScreen = false;
isVideoPaused = false;
isScreenPaused = false;
+ isTrackActive = 0;
+ isVideoFullScreen = false;
+ isSpeaking = false;
}
protected ConferenceListItem(ConferenceItemType type, String phoneId, String memberId,
@@ -73,9 +78,14 @@ public class ConferenceListItem {
this.hasScreen = false;
this.isVideoPaused = false;
this.isScreenPaused = false;
+ this.isTrackActive = 0;
+ this.isVideoFullScreen = false;
+ this.isSpeaking = false;
}
- protected ConferenceListItem(ConferenceItemType type, NYNCallParticipant participant, boolean isFriend) {
+ protected ConferenceListItem(ConferenceItemType type, NYNCallParticipant participant,
+ boolean isFriend,
+ boolean isOwnStreamActive) {
this.type = type;
this.phoneId = participant.getAddress();
this.memberId = participant.getMemberId();
@@ -87,10 +97,32 @@ public class ConferenceListItem {
this.isMuted = participant.isMuted();
this.isFriend = isFriend;
this.memberActions = new ArrayList<>();
- this.hasVideo = participant.hasVideo();
+ this.hasVideo = (participant.hasVideo() || (isMe && isOwnStreamActive));
this.hasScreen = participant.hasScreen();
this.isVideoPaused = participant.isVideoPaused();
this.isScreenPaused = participant.isScreenPaused();
+ this.isSpeaking = participant.isSpeaking();
+ this.isTrackActive = 0;
+ this.isVideoFullScreen = false;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ConferenceListItem item = (ConferenceListItem) o;
+ return (StringUtils.isEqual(phoneId, item.phoneId)
+ && StringUtils.isEqual(memberId, item.memberId)
+ && StringUtils.isEqual(participantId, item.participantId));
+ }
+
+
+ @Override
+ public int hashCode() {
+ int result = phoneId != null ? phoneId.hashCode() : 0;
+ result = 31 * result + (memberId != null ? memberId.hashCode() : 0);
+ result = 31 * result + (participantId != null ? participantId.hashCode() : 0);
+ return result;
}
public void update(ConferenceListItem participant) {
@@ -103,6 +135,12 @@ public class ConferenceListItem {
this.hasScreen = participant.hasScreen;
this.isVideoPaused = participant.isVideoPaused;
this.isScreenPaused = participant.isScreenPaused;
+ this.isTrackActive = 0;
+ this.isMe = participant.isMe;
+ this.isFriend = participant.isFriend;
+ this.isMuted = participant.isMuted;
+ this.isSpeaking = participant.isSpeaking;
+ this.isVideoFullScreen = false;
}
private void setActions(ArrayList itemActions) {
@@ -246,10 +284,11 @@ public class ConferenceListItem {
return item;
}
- public static ConferenceListItem fromSdkParticipant(NYNCallParticipant participant, boolean isFriend) {
+ public static ConferenceListItem fromSdkParticipant(NYNCallParticipant participant,
+ boolean isFriend,
+ boolean isOwnStreamActive) {
ConferenceListItem item = new ConferenceListItem(
- ConferenceItemType.Participant,
- participant, isFriend);
+ ConferenceItemType.Participant, participant, isFriend, isOwnStreamActive);
return item;
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKListener.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKListener.java
index cb29ab18c46e86bb1e126d0ad9c775044ff4ee56..4710d6de072de19ab699bc03f4a91bb56dd74d0b 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKListener.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKListener.java
@@ -1,9 +1,11 @@
package com.nynja.mobile.communicator.data.sdk.calls;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.sdk.NYNCall;
import com.nynja.sdk.NYNCallHistoryCode;
+import java.util.ArrayList;
+
/**
* Created by Ergyun Syuleyman on 4/19/18.
*/
@@ -38,6 +40,8 @@ public interface ConferenceSDKListener {
void onScreenShareState(boolean active);
+ void onStartCapturerFailed(int msgResId, boolean isCamera);
+
void onRemoteScreenShareTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) ;
void onRemoteScreenShareTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) ;
@@ -58,7 +62,7 @@ public interface ConferenceSDKListener {
void tryCallCameraStateChange(boolean pause);
- void onActiveSpeakersUpdate(String activeSpeakers);
+ void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds);
void onMuteStateChangedByHost(boolean isMuted);
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java
index 18ccff2c405198a6cef5a44ee89363eccc7822f5..b00746dd8364d2bf498f808c26a93411eb64171a 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java
@@ -1,7 +1,6 @@
package com.nynja.mobile.communicator.data.sdk.calls;
import android.Manifest;
-import android.app.Notification;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -26,9 +25,9 @@ import com.nynja.mobile.communicator.NynjaApp;
import com.nynja.mobile.communicator.R;
import com.nynja.mobile.communicator.data.ProfileSyncManager;
import com.nynja.mobile.communicator.data.audio.NynjaSoundManager;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule;
import com.nynja.mobile.communicator.data.db.DbHelper;
-import com.nynja.mobile.communicator.data.db.PreferenceHelper;
import com.nynja.mobile.communicator.data.models.SettingNotifications;
import com.nynja.mobile.communicator.data.models.StateDevice;
import com.nynja.mobile.communicator.data.models.mqtt.Conference;
@@ -37,7 +36,6 @@ import com.nynja.mobile.communicator.data.models.nynjamodels.MemberModel;
import com.nynja.mobile.communicator.data.sdk.BaseSDKModule;
import com.nynja.mobile.communicator.ui.activities.MainActivity;
import com.nynja.mobile.communicator.utils.Consts;
-import com.nynja.mobile.communicator.utils.DialogFactory;
import com.nynja.mobile.communicator.utils.MobileSDKConstants;
import com.nynja.mobile.communicator.utils.NotificationHelper;
import com.nynja.mobile.communicator.utils.StringUtils;
@@ -376,8 +374,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
stopCallAllActiions();
clearConference();
if (fireEvent) {
- for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
- conferenceSDKListener.conferenceEnded();
+ synchronized (mConferenceSDKListener) {
+ for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
+ conferenceSDKListener.conferenceEnded();
+ }
}
}
if (delayed) {
@@ -395,8 +395,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
mConferenceDetails = null;
isSpeakerPhoneForced = false;
if (fireEvent) {
- for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
- conferenceSDKListener.conferenceEnded();
+ synchronized (mConferenceSDKListener) {
+ for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
+ conferenceSDKListener.conferenceEnded();
+ }
}
}
if (delayed) {
@@ -657,6 +659,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
//addCallHistoryListener();
////////////////////////////////////////////////////////////////////////////////////////////////////////
mConferenceAudioManager = AppRTCAudioManager.create(getContext());
+ //ConferenceVideoModule.getInstance();
try {
mCallsLooper = Looper.myLooper();
@@ -755,7 +758,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
&& StringUtils.isNotEmpty(chatRoomId)) {
mActiveConference.mEndPointId = chatRoomId;
}
- if (mHandler != null) mHandler.post( () -> {
+ runOnUIThread( () -> {
onConferenceParticipantsUpdated(callId);
});
}
@@ -802,12 +805,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
Timber.d("onRemoteVideoTrackAdded(): callId=" + call.callId() +
"; trackId=" + trackId + "; participantId=" + participantId
+ "; isConference=" + (isConference ? "true" : "false"));
- if (isConference) {
- mActiveConference.hasRemoteVideoTrack = true;
- onRemoteScreenShareAdded(call.callId(), trackId, participantId);
- } else {
- onRemoteVideoAdded(call.callId(), trackId, participantId, isConference);
- }
+ onRemoteVideoAdded(call.callId(), trackId, participantId, isConference);
}
}
@@ -818,12 +816,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
Timber.d("onRemoteVideoTrackRemoved(): callId=" + call.callId() +
"; trackId=" + trackId + "; participantId=" + participantId
+ "; isConference=" + (isConference ? "true" : "false"));
- if (isConference) {
- onRemoteScreenShareRemoved(call.callId(), trackId, participantId);
- mActiveConference.hasRemoteVideoTrack = false;
- } else {
- onRemoteVideoRemoved(call.callId(), trackId, participantId, isConference);
- }
+ onRemoteVideoRemoved(call.callId(), trackId, participantId, isConference);
}
}
@@ -872,10 +865,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
}
@Override
- public void startScreenShareFailed(NYNCall call) {
+ public void startScreenShareFailed(NYNCall call, int code) {
if (call != null) {
Timber.d("startScreenShareFailed(): callId=" + call.callId());
- onOwnScreenShareStopped(call);
+ onStartCapturerFailed(call, code, false);
}
}
@@ -886,6 +879,14 @@ public class ConferenceSDKModule extends BaseSDKModule {
onOwnScreenShareStopped(call);
}
}
+
+ @Override
+ public void startCameraFailed(NYNCall call, int code) {
+ if (call != null) {
+ Timber.d("startCameraFailed(): callId=" + call.callId());
+ onStartCapturerFailed(call, code, true);
+ }
+ }
};
}
@@ -899,8 +900,8 @@ public class ConferenceSDKModule extends BaseSDKModule {
mConferenceDetails.mCallId = conferenceId;
NYNCall conference = mCallManager.getCallById(conferenceId);
if (conference != null) {
- mConferenceDetails.mActiveConference.mConference = conference;
- mConferenceDetails.mActiveConference.mParticipantsCountLimit = conference.getParticipantsCountLimit();
+ mConferenceDetails.mActiveConference.setInternalCall(conference);
+ mConferenceDetails.mActiveConference.mData.mParticipantsCountLimit = conference.getParticipantsCountLimit();
onGetConferenceRoomLimitsFinished(null, mConferenceDetails.mActiveConference.mEndPointId,
conference.getParticipantsCountLimit());
addConferenceCallListener(mConferenceDetails.mActiveConference.mConference);
@@ -1024,10 +1025,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
conferenceId != null &&
conferenceId.contentEquals(mConferenceDetails.mCallId) &&
mActiveConference.isWaiting()) {
- mActiveConference.mConference = mCallManager.getCallById(mConferenceDetails.mCallId);
+ mActiveConference.setInternalCall(mCallManager.getCallById(mConferenceDetails.mCallId));
if (mActiveConference.mConference != null) {
// todo: for limits use the new logic - local hashMap
- mActiveConference.mParticipantsCountLimit = mActiveConference.mConference.getParticipantsCountLimit();
+ mActiveConference.mData.mParticipantsCountLimit = mActiveConference.mConference.getParticipantsCountLimit();
addConferenceCallListener(mActiveConference.mConference);
onCallReady(conferenceId, mActiveConference.isVideoEnabled, true);
}
@@ -1072,11 +1073,13 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (!hasCreatedActiveCall()) return;
Timber.d("Request conference member with \'ConferenceId\'=\'" +
conferenceId + "\' " + (result ? "succeed" : "failed!!!"));
- mActiveConference.mParticipantArray = mActiveConference.mConference.getParticipants();
+ synchronized (mActiveConference.mData) {
+ mActiveConference.mData.mParticipantArray = mActiveConference.mConference.getParticipants();
+ }
// update chatRoomId
- if (mActiveConference.mParticipantArray != null &&
- mActiveConference.mParticipantArray.size() > 0 &&
+ if (mActiveConference.mData.mParticipantArray != null &&
+ mActiveConference.mData.mParticipantArray.size() > 0 &&
StringUtils.isEmpty(mActiveConference.mEndPointId)) {
mActiveConference.mEndPointId = mActiveConference.mConference.getChatRoomId();
}
@@ -1131,6 +1134,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (call == null) return;
if (!mActiveConference.mConference.callId().contentEquals(call.callId())) return;
String activeSpeakers = "";
+ ArrayList participantIds = new ArrayList<>();
NYNCallParticipantArray participantArray = call.getParticipants();
for (int index = 0; index < participantArray.size(); index++) {
NYNCallParticipant participant = participantArray.get(index);
@@ -1141,9 +1145,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
}
if (!activeSpeakers.isEmpty()) activeSpeakers += ", ";
activeSpeakers += participant.getName();
+ participantIds.add(participant.getParticipantId());
}
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener)
- conferenceSDKListener.onActiveSpeakersUpdate(activeSpeakers);
+ conferenceSDKListener.onActiveSpeakersUpdate(activeSpeakers, participantIds);
}
private synchronized void onMuteStateChangedByHost(NYNCall call, boolean isMuted) {
@@ -1429,7 +1434,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
@Override
public void createCallFinished(String requestId, String callId, boolean success) {
if (!hasCreatedActiveCall()) return;
- mActiveConference.mConference = mCallManager.getCallById(callId);
+ mActiveConference.setInternalCall(mCallManager.getCallById(callId));
Timber.d("Request create call with \'CallId\'=\'" +
callId + "\' " + (success ? "succeed" : "failed!!!"));
if (mActiveConference.isOutgoingCall) {
@@ -1568,7 +1573,9 @@ public class ConferenceSDKModule extends BaseSDKModule {
initConferenceCall(false);
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mActiveConference.isCallInProgress = true;
- mActiveConference.mParticipantArray = mActiveConference.mConference.getParticipants();
+ synchronized (mActiveConference.mData) {
+ mActiveConference.mData.mParticipantArray = mActiveConference.mConference.getParticipants();
+ }
startConferenceActivityImpl(NynjaNavigator.MAIN_NEW_CALL, true);
}, Consts.DELAY_100);
}
@@ -1602,61 +1609,96 @@ public class ConferenceSDKModule extends BaseSDKModule {
private void onRemoteScreenShareAdded(String callId, String trackId, String participantId) {
if (!hasCreatedActiveCall()) return;
- mActiveConference.mActiveTracks.put(trackId, participantId);
+ mActiveConference.mData.onRemoteSSAdded(trackId, participantId);
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.mRemoteSSTrackId = trackId;
- mActiveConference.hasRemoteScreenShareTrack = true;
for (ConferenceSDKListener conferenceListener : mConferenceSDKListener) {
conferenceListener.onRemoteScreenShareTrackAdded(mActiveConference, trackId);
}
}
+// mActiveConference.mData.mActiveTracks.put(trackId, participantId);
+// if (mActiveConference.mConference == null) return;
+// if (mActiveConference.mConference.callId().contentEquals(callId)) {
+// mActiveConference.mData.mRemoteSSTrackId = trackId;
+// mActiveConference.mData.hasRemoteScreenShareTrack = true;
+// for (ConferenceSDKListener conferenceListener : mConferenceSDKListener) {
+// conferenceListener.onRemoteScreenShareTrackAdded(mActiveConference, trackId);
+// }
+// }
}
private void onRemoteScreenShareRemoved(String callId, String trackId, String participantId) {
if (!hasCreatedActiveCall()) return;
- mActiveConference.mActiveTracks.remove(trackId);
+ mActiveConference.mData.onRemoteSSRemoved(trackId, participantId);
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.hasRemoteScreenShareTrack = false;
for (ConferenceSDKListener conferenceListener : mConferenceSDKListener) {
conferenceListener.onRemoteScreenShareTrackRemoved(mActiveConference, trackId);
}
- mActiveConference.mRemoteSSTrackId = "";
}
+// mActiveConference.mData.mActiveTracks.remove(trackId);
+// if (mActiveConference.mConference == null) return;
+// if (mActiveConference.mConference.callId().contentEquals(callId)) {
+// mActiveConference.mData.hasRemoteScreenShareTrack = false;
+// for (ConferenceSDKListener conferenceListener : mConferenceSDKListener) {
+// conferenceListener.onRemoteScreenShareTrackRemoved(mActiveConference, trackId);
+// }
+// mActiveConference.mData.mRemoteSSTrackId = "";
+// }
}
private void onRemoteVideoAdded(String callId, String trackId, String participantId, boolean isConference) {
if (!hasCreatedActiveCall()) return;
- mActiveConference.mActiveTracks.put(trackId, participantId);
+ mActiveConference.mData.onRemoteVideoAdded(trackId, participantId);
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.mRemoteVideoTrackId = trackId;
- mActiveConference.hasRemoteVideoTrack = true;
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
conferenceSDKListener.onRemoteVideoTrackAdded(mActiveConference, trackId);
}
}
+// if (isConference) {
+// mActiveConference.mData.hasRemoteVideoTrack = true;
+// onRemoteScreenShareAdded(callId, trackId, participantId);
+// } else {
+// mActiveConference.mData.mActiveTracks.put(trackId, participantId);
+// if (mActiveConference.mConference == null) return;
+// if (mActiveConference.mConference.callId().contentEquals(callId)) {
+// mActiveConference.mData.mRemoteVideoTrackId = trackId;
+// mActiveConference.mData.hasRemoteVideoTrack = true;
+// }
+// }
}
private void onRemoteVideoRemoved(String callId, String trackId, String participantId, boolean isConference) {
if (!hasCreatedActiveCall()) return;
- mActiveConference.mActiveTracks.remove(trackId);
+ mActiveConference.mData.onRemoteVideoRemoved(trackId, participantId);
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.hasRemoteVideoTrack = false;
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
conferenceSDKListener.onRemoteVideoTrackRemoved(mActiveConference, trackId);
}
- mActiveConference.mRemoteVideoTrackId = "";
}
+// if (isConference) {
+// onRemoteScreenShareRemoved(callId, trackId, participantId);
+// mActiveConference.mData.hasRemoteVideoTrack = false;
+// } else {
+// mActiveConference.mData.mActiveTracks.remove(trackId);
+// if (mActiveConference.mConference == null) return;
+// if (mActiveConference.mConference.callId().contentEquals(callId)) {
+// mActiveConference.mData.hasRemoteVideoTrack = false;
+// for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
+// conferenceSDKListener.onRemoteVideoTrackRemoved(mActiveConference, trackId);
+// }
+// mActiveConference.mData.mRemoteVideoTrackId = "";
+// }
+// }
}
private void onLocalVideoStarted(String callId) {
if (!hasCreatedActiveCall()) return;
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.isOwnStreamActive = true;
+ mActiveConference.mData.isOwnStreamActive = true;
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
conferenceSDKListener.onLocalVideoCapturerStarted(mActiveConference);
}
@@ -1667,7 +1709,12 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (!hasCreatedActiveCall()) return;
if (mActiveConference.mConference == null) return;
if (mActiveConference.mConference.callId().contentEquals(callId)) {
- mActiveConference.isOwnStreamActive = false;
+ mActiveConference.mData.isOwnStreamActive = false;
+ if (mActiveConference.isConference()) {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ mActiveConference.mConference.setLocalVideoRenderer(null);
+ });
+ }
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
conferenceSDKListener.onLocalVideoCapturerStopped(mActiveConference);
}
@@ -1708,6 +1755,28 @@ public class ConferenceSDKModule extends BaseSDKModule {
}
}
+ private void onStartCapturerFailed(NYNCall call, int code, boolean isCamera) {
+ if (call != null &&
+ hasCreatedActiveCall() && mActiveConference.mConference != null
+ && mActiveConference.mConference.callId().contentEquals(call.callId())) {
+ for (ConferenceSDKListener conferenceListener : mConferenceSDKListener) {
+ if (code == -47) {
+ if (isCamera) {
+ conferenceListener.onStartCapturerFailed(R.string.call_start_camera_failed_busy, isCamera);
+ } else {
+ conferenceListener.onStartCapturerFailed(R.string.call_start_ss_failed_busy, isCamera);
+ }
+ } else {
+ if (isCamera) {
+ conferenceListener.onStartCapturerFailed(R.string.call_start_camera_failed_invalid_state, isCamera);
+ } else {
+ conferenceListener.onStartCapturerFailed(R.string.call_start_ss_failed_invalid_state, isCamera);
+ }
+ }
+ }
+ }
+ }
+
private void onChangeCallState(NYNCall call, NYNCallState newState) {
for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) {
conferenceSDKListener.onConferenceStateChanged(mActiveConference);
@@ -2083,13 +2152,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
mConferenceDetails = new ConferenceDetails(getDeviceId());
mActiveConference = createActiveConference(null, contact.phoneId, true,
isVideoEnabled, ActiveCallBase.CallType.P2PCall);
- mActiveConference.isOwnStreamActive = isVideoEnabled;
+ mActiveConference.mData.isOwnStreamActive = isVideoEnabled;
mActiveConference.addMember(contact);
setConferenceCallName(mActiveConference, contact.getFullName());
AppsTrackerUtils.getCleverTapInstance().trackEvent(getContext(), AppsTrackerConsts.ATEventMakeP2PCall);
- if (StringUtils.isNotEmpty(phoneId)) {
- mActiveConference.mMyPhoneId = phoneId;
- }
startConferenceActivityImpl(NynjaNavigator.ACTIVE_CALL);
}
}
@@ -2563,10 +2629,10 @@ public class ConferenceSDKModule extends BaseSDKModule {
private void updateConferenceNameIfNeeds() {
if (mConferenceDetails != null && mConferenceDetails.mMembersCounter < 0) {
if (mActiveConference == null) return;
- if (mActiveConference.mParticipantArray == null) return;
- if (mActiveConference.mParticipantArray.size() > 0 && TEMP_ALLOW_UPDATE_CONF_CALLS_NAME) {
+ if (mActiveConference.mData.mParticipantArray == null) return;
+ if (mActiveConference.mData.mParticipantArray.size() > 0 && TEMP_ALLOW_UPDATE_CONF_CALLS_NAME) {
tryUpdateConferenceCallName(mActiveConference,
- generateGroupConferenceName(mActiveConference.mParticipantArray.size() - 1));
+ generateGroupConferenceName(mActiveConference.mData.mParticipantArray.size() - 1));
}
}
@@ -2585,11 +2651,11 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (mActiveConference.mConference != null) {
mActiveConference.mConference.setListener(null);
}
- mActiveConference.mConference = mCallManager.getCallById(mConferenceDetails.mCallId);
+ mActiveConference.setInternalCall(mCallManager.getCallById(mConferenceDetails.mCallId));
}
if (mActiveConference.mConference != null) {
// todo: for limits use the new logic - local hashMap
- mActiveConference.mParticipantsCountLimit = mActiveConference.mConference.getParticipantsCountLimit();
+ mActiveConference.mData.mParticipantsCountLimit = mActiveConference.mConference.getParticipantsCountLimit();
addConferenceCallListener(mActiveConference.mConference);
}
}
@@ -2844,7 +2910,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
mConferenceDetails = new ConferenceDetails(getDeviceId(), iConference.callId());
mActiveConference = createActiveConference(iConference);
if (!hasCreatedActiveCall()) return false;
- mActiveConference.isOwnStreamActive = false;
+ mActiveConference.mData.isOwnStreamActive = false;
initConferenceCall(startActivity);
if (startActivity) {
if (Consts.SHOW_INCOMING_CALLS_AS_POPUP_NOTIFICATIONS) {
@@ -2913,8 +2979,8 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (mConferenceDetails.mCallId != null &&
mConferenceDetails.mCallId.contentEquals(conferenceId)) {
// @TODO: request update server side conference name .....
- for (int index = 0; index < mActiveConference.mParticipantArray.size(); index++) {
- NYNCallParticipant participant = mActiveConference.mParticipantArray.get(index);
+ for (int index = 0; index < mActiveConference.mData.mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = mActiveConference.mData.mParticipantArray.get(index);
if (!participant.getMemberId().contentEquals(memberId)) {
continue;
}
@@ -2924,10 +2990,12 @@ public class ConferenceSDKModule extends BaseSDKModule {
break;
}
}
- if (mActiveConference.mParticipantArray.size() > 1 && TEMP_ALLOW_UPDATE_CONF_CALLS_NAME) {
- mActiveConference.mParticipantArray.remove(index);
+ if (mActiveConference.mData.mParticipantArray.size() > 1 && TEMP_ALLOW_UPDATE_CONF_CALLS_NAME) {
+ synchronized (mActiveConference.mData) {
+ mActiveConference.mData.mParticipantArray.remove(index);
+ }
tryUpdateConferenceCallName(mActiveConference,
- generateGroupConferenceName(mActiveConference.mParticipantArray.size() - 1));// exclude me
+ generateGroupConferenceName(mActiveConference.mData.mParticipantArray.size() - 1));// exclude me
}
break;
}
@@ -3045,7 +3113,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
return;
}
if (!mActiveConference.isOutgoingCall) {
- mActiveConference.isVideoEnabled = videoEnabled;
+ //mActiveConference.isVideoEnabled = videoEnabled;
}
mActiveConference.isCallInProgress = true;
mActiveConference.isRinging = false;
@@ -3186,6 +3254,13 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (!activeConferenceCall.mConference.isCameraRunning()) return;
activeConferenceCall.mConference.stopCamera();
+ if (mActiveConference.isConference()) {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ if (mActiveConference != null && mActiveConference.mConference != null) {
+ mActiveConference.mConference.setLocalVideoRenderer(null);
+ }
+ });
+ }
}
public boolean hasRemoteScreenShare() {
@@ -3193,7 +3268,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (mActiveConference.mConference == null) return false;
return (mActiveConference.mConference.hasRemoteScreenShare()
- || !mActiveConference.mActiveTracks.isEmpty());
+ || !mActiveConference.mData.mActiveTracks.isEmpty());
}
public boolean isScreenSharing() {
@@ -3295,13 +3370,13 @@ public class ConferenceSDKModule extends BaseSDKModule {
}
public int getActiveConferenceParticipantsLimit() {
- if (!hasCreatedActiveCall()) return ActiveConferenceCall.CONFERENCE_PARTICIPANTS_COUNT_LIMIT;
+ if (!hasCreatedActiveCall()) return ConferenceCallData.CONFERENCE_PARTICIPANTS_COUNT_LIMIT;
if (mActiveConference.mConference != null &&
mActiveConference.mCallType == ActiveCallBase.CallType.P2PCall &&
mConferenceDetails != null && mConferenceDetails.mActiveConference != null) {
- return mConferenceDetails.mActiveConference.mParticipantsCountLimit;
+ return mConferenceDetails.mActiveConference.mData.mParticipantsCountLimit;
}
- return mActiveConference.mParticipantsCountLimit;
+ return mActiveConference.mData.mParticipantsCountLimit;
}
private void playConnecting() {
@@ -3425,7 +3500,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
replaceCallEx(subject, deleteGroupIfNoMessages,
deleteAfterCall, isVideoConference,
mActiveConference.mConference.callId(),
- contacts);
+ contacts, mActiveConference.mData.isOwnStreamActive);
} else {
createAndStartConferenceEx(subject, chatRoomId, deleteGroupIfNoMessages,
deleteAfterCall, isVideoConference, contacts);
@@ -3460,7 +3535,7 @@ public class ConferenceSDKModule extends BaseSDKModule {
if (limits >= 0) return limits;
// set the default value
- limits = ActiveConferenceCall.CONFERENCE_PARTICIPANTS_COUNT_LIMIT;
+ limits = ConferenceCallData.CONFERENCE_PARTICIPANTS_COUNT_LIMIT;
mConferenceRoomLimits.put(defRoomId, limits);
return limits;
@@ -3511,7 +3586,8 @@ public class ConferenceSDKModule extends BaseSDKModule {
boolean deleteAfterCall,
boolean isVideoConference,
String replaceRef,
- ArrayList contacts) {
+ ArrayList contacts,
+ boolean isVideo) {
if (StringUtils.isEmpty(replaceRef)) return;
if (!(hasCreatedActiveCall() && isP2P())) return;
@@ -3524,7 +3600,8 @@ public class ConferenceSDKModule extends BaseSDKModule {
subject,
!deleteGroupIfNoMessages,
deleteAfterCall ? DELETE_CONFERENCE_CALL_AFTER_END : DELETE_CONFERENCE_CALL_AFTER_1_DAY,
- members );
+ members,
+ isVideoConference || isVideo);
AppsTrackerUtils.getCleverTapInstance().trackEvent(getContext(), AppsTrackerConsts.ATEventMakeGroupCall);
});
}
@@ -3549,7 +3626,8 @@ public class ConferenceSDKModule extends BaseSDKModule {
!deleteGroupIfNoMessages,
deleteAfterCall ? DELETE_CONFERENCE_CALL_AFTER_END : DELETE_CONFERENCE_CALL_AFTER_1_DAY,
"",
- members );
+ members,
+ isVideoConference);
AppsTrackerUtils.getCleverTapInstance().trackEvent(getContext(), AppsTrackerConsts.ATEventMakeGroupCall);
});
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_impl/SocialLoginDetailsImpl.kt b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_impl/SocialLoginDetailsImpl.kt
index e203b51184c362b7fbe1b6ccbee20558a049090f..4b035926a28298b5ff4338c92f3a70d34166ce3e 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_impl/SocialLoginDetailsImpl.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_impl/SocialLoginDetailsImpl.kt
@@ -15,17 +15,22 @@ class SocialLoginDetailsImpl() : ISocialLoginDetails {
override var avatar: String? = null
override var firstName: String? = null
override var lastName: String? = null
+ override var isPending: Boolean = true
+ override var isSocial: Boolean = false
constructor(parcel: Parcel) : this() {
avatar = parcel.readString()
firstName = parcel.readString()
lastName = parcel.readString()
+ isPending = (parcel.readInt() > 0)
+ isSocial = (parcel.readInt() > 0)
}
constructor(data: NYNSocialLoginDetails?) : this() {
avatar = data?.pictureUrl
firstName = data?.firstName
lastName = data?.lastName
+ isSocial = true
}
constructor(data: IAccount?) : this() {
@@ -48,6 +53,8 @@ class SocialLoginDetailsImpl() : ISocialLoginDetails {
parcel.writeString(avatar)
parcel.writeString(firstName)
parcel.writeString(lastName)
+ parcel.writeInt(if (isPending) 1 else 0)
+ parcel.writeInt(if (isSocial) 1 else 0)
}
override fun describeContents(): Int {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_interfaces/ISocialLoginDetails.kt b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_interfaces/ISocialLoginDetails.kt
index 07eabbea4152007e1bbe3ac9ad6833092d92dd51..f149f4248a9795a97e69a0a6e1b7d02e11b90152 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_interfaces/ISocialLoginDetails.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/data/data_interfaces/ISocialLoginDetails.kt
@@ -10,5 +10,6 @@ interface ISocialLoginDetails :Parcelable{
var firstName: String?
var lastName: String?
var avatar: String?
-
+ var isPending: Boolean
+ var isSocial: Boolean
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nynja/mobile/communicator/interfaces/OnConferenceVideoFeedClickListener.java b/app/src/main/java/com/nynja/mobile/communicator/interfaces/OnConferenceVideoFeedClickListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..a707d0639e3182770cc62cf4b71f1abf7a98d1aa
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/interfaces/OnConferenceVideoFeedClickListener.java
@@ -0,0 +1,9 @@
+package com.nynja.mobile.communicator.interfaces;
+
+/**
+ * Created by Ergyun Syuleyman on 4/25/18.
+ */
+
+public interface OnConferenceVideoFeedClickListener extends OnConferenceItemClickListener {
+ void onSwitchCameraClick(T item);
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BaseLoginPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BaseLoginPresenter.java
index 6606a4d82088a9bbb6d12f1c1325e92e9c9f6669..5e88205d4a9156e90a5acf066d15b03f05881982 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BaseLoginPresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BaseLoginPresenter.java
@@ -1,6 +1,7 @@
package com.nynja.mobile.communicator.mvp.presenters;
import com.nynja.mobile.communicator.data.sdk.data.data_impl.AccountImpl;
+import com.nynja.mobile.communicator.data.sdk.data.data_impl.SocialLoginDetailsImpl;
import com.nynja.mobile.communicator.data.sdk.data.data_interfaces.ISocialLoginDetails;
import com.nynja.mobile.communicator.mvp.view.ErrorMvpView;
import com.nynja.mobile.communicator.utils.StringUtils;
@@ -23,6 +24,9 @@ public class BaseLoginPresenter extends BaseErrorPresent
mDataManager.getAuthCodeReceiverClient().stop();
if (pending) {
mDataProvider.saveAccount(account);
+ if (socialLoginDetails == null) {
+ socialLoginDetails = new SocialLoginDetailsImpl(account);
+ }
mRouter.backToAndNavigate(new Screen(SignInNavigator.SIGN_IN),
new Screen[]{ new Screen(SignInNavigator.INFO, socialLoginDetails)});
} else {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BasePresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BasePresenter.java
index b7a5129ff4333d8330b1021b05a77156e4026e64..fd01699566b77cf3c4cd164b78315bbf9406a1a3 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BasePresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/BasePresenter.java
@@ -9,7 +9,7 @@ import com.nynja.mobile.communicator.data.DataManager;
import com.nynja.mobile.communicator.data.FragmentTransferObject;
import com.nynja.mobile.communicator.data.GooglePlacesService;
import com.nynja.mobile.communicator.data.NynjaKeyboardManager;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.models.events.ServerData;
import com.nynja.mobile.communicator.data.models.events.ServerMessage;
import com.nynja.mobile.communicator.data.models.events.local.AccountAuthFailedEvent;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallActivityPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallActivityPresenter.java
index 416edcc81415ccfb4eca973945b0b7cb58c13d9a..53640f1f51a6c6a1773602892176bea7896c7476 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallActivityPresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallActivityPresenter.java
@@ -1,14 +1,12 @@
package com.nynja.mobile.communicator.mvp.presenters;
import com.arellomobile.mvp.InjectViewState;
-import com.nynja.mobile.communicator.NynjaApp;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.models.events.local.Event;
import com.nynja.mobile.communicator.data.models.events.local.SimpleEvent;
import com.nynja.mobile.communicator.data.sdk.ConferenceSDKPresenter;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
import com.nynja.mobile.communicator.mvp.view.CallActivityView;
-import com.nynja.mobile.communicator.utils.navigation.navigators.NynjaNavigator;
/**
* Created by Ergyun Syuleyman on 7/19/19.
@@ -36,6 +34,37 @@ public class CallActivityPresenter extends ConferenceSDKPresenter {
return;
}
if (mRoom.isGroupOrCalllChat()) {
- getViewState().showAlertNotSupportedFeature();
-// FragmentTransferObject fto = new FragmentTransferObject(null, mRoom, OpenVideoConferenceCreate);
-// mRouter.navigateTo(HomeNavigator.CHOOSE_USER, fto);
+ if (Consts.CLIENT_ALLOWED_VIDEO_CONFERENCE) {
+ navigateToStartGroupCall(true, mRoom);
+// FragmentTransferObject fto = new FragmentTransferObject(null, mRoom, OpenVideoConferenceCreate);
+// mRouter.navigateTo(HomeNavigator.CHOOSE_USER, fto);
+ } else {
+ getViewState().showMessage(R.string.call_start_video_conference_alert);
+ }
} else {
mDataManager.startCall(new ContactModel(mRoom.getOnlyMembers().get(0)), true);
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceCallPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceCallPresenter.java
index 09ed005c481169a421b6d02fc6434a77eadd2ac7..f4bb992891edc05a899a794d3e695f626c802ae3 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceCallPresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceCallPresenter.java
@@ -5,7 +5,7 @@ import android.support.annotation.Nullable;
import com.arellomobile.mvp.InjectViewState;
import com.nynja.mobile.communicator.R;
import com.nynja.mobile.communicator.data.FragmentTransferObject;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.models.events.local.Event;
import com.nynja.mobile.communicator.data.models.events.local.SimpleEvent;
import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
@@ -69,6 +69,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void switchCamera() {
+ if (getAttachedViews().size() == 0) return;
ActiveConferenceCall activeConferenceCall = mDataManager.getConferenceSDK().
getActiveConference();
if (activeConferenceCall != null && activeConferenceCall.mConference != null) {
@@ -91,6 +92,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void showProfile(ConferenceListItem item) {
+ if (getAttachedViews().size() == 0) return;
getViewState().closenConference();
if (!item.isMe) {
ContactModel contact = mDataManager.getContactByChatId(item.phoneId);
@@ -184,6 +186,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void goToHome() {
+ if (getAttachedViews().size() == 0) return;
getViewState().closenConference();
openHome();
}
@@ -191,6 +194,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
public void openChatWithParticipant(String participantPhoneId) {
ContactModel contactByChatId = mDataManager.getContactByChatId(participantPhoneId);
if (contactByChatId != null) {
+ if (getAttachedViews().size() == 0) return;
getViewState().closenConference();
RoomModel room = new RoomModel(contactByChatId);
FragmentTransferObject fto = new FragmentTransferObject(room, null);
@@ -199,6 +203,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void navigateToChatRoom(RoomModel room) {
+ if (getAttachedViews().size() == 0) return;
if (mDataManager.isMainActivityIsActive()) {
getViewState().closenConference();
FragmentTransferObject fto = null;
@@ -213,6 +218,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void loadUser(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
ContactModel user = mDataManager.getContactByChatId(activeConferenceCall.mEndPointId);
getViewState().setUser(user);
if (user == null) {
@@ -225,6 +231,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void onLeaveCall() {
+ if (getAttachedViews().size() == 0) return;
if (isConferenceActive()) {
if (isP2PCall()) {
getViewState().showLeaveCallConfirmation();
@@ -244,6 +251,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Override
public void timeAway(boolean videoEnabled, String time) {
+ if (getAttachedViews().size() == 0) return;
getViewState().conferenceTimeUpdated(videoEnabled, time);
}
@@ -254,17 +262,19 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Override
public void conferenceEnded() {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
getViewState().onConferenceEnded();
}
@Override
public void onConferenceRinging() {
+ if (getAttachedViews().size() == 0) return;
getViewState().onConferenceRinging();
}
@Override
public void onConferenceConnected(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
if (!activeConferenceCall.mConference.isConference()) {
String personId = activeConferenceCall.isOutgoingCall ?
activeConferenceCall.mEndPointId : activeConferenceCall.mConference.caller();
@@ -276,32 +286,34 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Override
public void onConferenceFailed(String reason) {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
getViewState().onConferenceFailed(reason);
}
@Override
public void onConferenceJoinFailed(String reason) {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
getViewState().onConferenceJoinFailed(reason);
}
@Override
public void onCallFailed(String reason) {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
getViewState().onCallFailed(reason);
}
@Override
public void onConferenceStateChanged(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onConferenceStateChanged(activeConferenceCall);
}
protected ConferenceListItem conferenceParticipant(NYNCallParticipant participant,
- boolean isModerator) {
+ boolean isModerator,
+ boolean isOwnStreamActive) {
ContactModel user = mDataManager.getContactsByPhoneId(participant.getAddress());
- ConferenceListItem conferenceListItem = ConferenceListItem.fromSdkParticipant(participant, (user != null));
+ ConferenceListItem conferenceListItem = ConferenceListItem.fromSdkParticipant(participant, (user != null), isOwnStreamActive);
if (user != null) {
conferenceListItem.avatar = user.avatar;
}
@@ -312,12 +324,13 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Override
public void onConferenceMembersUpdate(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
if (activeConferenceCall == null) return;
ArrayList members = new ArrayList<>();
- if (activeConferenceCall.mParticipantArray != null) {
- for (int index = 0; index < activeConferenceCall.mParticipantArray.size(); index++) {
- NYNCallParticipant participant = activeConferenceCall.mParticipantArray.get(index);
- members.add(conferenceParticipant(participant, participant.isOwner()));
+ if (activeConferenceCall.mData.mParticipantArray != null) {
+ for (int index = 0; index < activeConferenceCall.mData.mParticipantArray.size(); index++) {
+ NYNCallParticipant participant = activeConferenceCall.mData.mParticipantArray.get(index);
+ members.add(conferenceParticipant(participant, participant.isOwner(), activeConferenceCall.mData.isOwnStreamActive));
}
} else {
for (int index = 0; index < activeConferenceCall.getMembers().size(); index++) {
@@ -334,66 +347,84 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Override
public void onCreateVideoCallReady(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onCreateVideoCallReady(activeConferenceCall);
}
@Override
public void onScreenShareState(boolean active) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onScreenShareStateChanged(active && isScreenSharing());
}
+ @Override public void onStartCapturerFailed(int msgResId, boolean isCamera) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onStartCapturerFailed(msgResId, isCamera);
+ }
+
@Override
public void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall,
String trackId) {
+ if (getAttachedViews().size() == 0) return;
+ if (activeConferenceCall == null) return;
+ if (activeConferenceCall.isConference()) return;
getViewState().onRemoteVideoTrackAdded(activeConferenceCall, trackId);
}
@Override
public void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall,
String trackId) {
+ if (getAttachedViews().size() == 0) return;
+ if (activeConferenceCall == null) return;
+ if (activeConferenceCall.isConference()) return;
getViewState().onRemoteVideoTrackRemoved(activeConferenceCall, trackId);
}
@Override
public void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onLocalVideoCapturerStarted(activeConferenceCall);
}
@Override
public void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onLocalVideoCapturerStopped(activeConferenceCall);
}
@Override
public void onMicrophoneStateChanged(boolean isMuted) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onMicrophoneStateChanged(isMuted);
}
@Override
public void onSpeakerStateChanged(boolean isSpeakerOn) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onSpeakerStateChanged(isSpeakerOn);
}
@Override
public void onAudioRouteChange(ActiveCallBase.AudioRouteType audioRouteType) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onAudioRouteChange(audioRouteType);
}
@Override
public void tryCallCameraStateChange(boolean pause) {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
getViewState().tryCallCameraStateChange(pause);
}
@Override
- public void onActiveSpeakersUpdate(String activeSpeakers) {
- if (getViewState() == null) return;
+ public void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds) {
+ if (getAttachedViews().size() == 0) return;
getViewState().onActiveSpeakersUpdate(activeSpeakers);
}
@Override
public void onMuteStateChangedByHost(boolean isMuted) {
- if (getViewState() == null) return;
+ if (getAttachedViews().size() == 0) return;
int stringResId = isMuted ? R.string.call_mute_by_host : R.string.call_unmute_by_host;
getViewState().showInfoBanner(stringResId);
getViewState().updateMicrophonState(isMuted);
@@ -412,6 +443,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void onClickScreenShare(boolean isShareOn) {
+ if (getAttachedViews().size() == 0) return;
ActiveConferenceCall call = mDataManager.getConferenceSDK().getActiveConference();
if (call != null && !call.isModerator() && !mDataManager.getConferenceSDK().isP2P()) {
if (!isScreenSharing() && hasRemoteScreenShare()) {
@@ -439,10 +471,10 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
@Nullable
private ArrayList getConferenceParticipants() {
if (mDataManager.getConferenceSDK().
- getActiveConference().mParticipantArray != null) {
+ getActiveConference().mData.mParticipantArray != null) {
ArrayList currentContacts = new ArrayList<>();
long count = mDataManager.getConferenceSDK().
- getActiveConference().mParticipantArray.size();
+ getActiveConference().mData.mParticipantArray.size();
String roomId = mDataManager.getConferenceSDK().getConferenceRoomId();
RoomModel room = mDataManager.getRoomById(roomId);
List membersList = new ArrayList<>();
@@ -452,7 +484,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
for (int index = 0; index < count; index++) {
NYNCallParticipant participant = mDataManager.getConferenceSDK().
- getActiveConference().mParticipantArray.get(index);
+ getActiveConference().mData.mParticipantArray.get(index);
if (!participant.isMe()) {
String memberAddress = participant.getAddress();
if (memberAddress == null) continue;
@@ -515,7 +547,9 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
if (type != null) {
- getViewState().closenConference();
+ if (getAttachedViews().size() > 0) {
+ getViewState().closenConference();
+ }
FragmentTransferObject fto = new FragmentTransferObject(currentContacts, room, type);
mRouter.backOrNavigateTo(HomeNavigator.CHOOSE_USER, fto);
}
@@ -562,6 +596,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void showInviteDialog() {
+ if (getAttachedViews().size() == 0) return;
if (mDataManager.getConferenceSDK().isConferenceModerator()) {
int addParticipantStringResId = isCallCreatedFromHome() ? R.string.contacts_contacts : R.string.group_participants;
getViewState().showInviteOptionsModerator(addParticipantStringResId);
@@ -575,6 +610,7 @@ public class ConferenceCallPresenter extends ConferenceSDKPresenter
}
public void copyLinkToClipboard() {
+ if (getAttachedViews().size() == 0) return;
getViewState().showCopyLinkMessage();
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceVideoPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceVideoPresenter.java
new file mode 100644
index 0000000000000000000000000000000000000000..93ff6234b0e3ebb4d30a1f03899aace87af3a940
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/ConferenceVideoPresenter.java
@@ -0,0 +1,206 @@
+package com.nynja.mobile.communicator.mvp.presenters;
+
+import com.arellomobile.mvp.InjectViewState;
+import com.nynja.mobile.communicator.data.FragmentTransferObject;
+import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule;
+import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
+import com.nynja.mobile.communicator.data.models.nynjamodels.RoomModel;
+import com.nynja.mobile.communicator.data.sdk.ConferenceSDKPresenter;
+import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceSDKListener;
+import com.nynja.mobile.communicator.mvp.view.ConferenceVideoView;
+import com.nynja.mobile.communicator.utils.navigation.navigators.HomeNavigator;
+import com.nynja.sdk.NYNCallParticipant;
+
+import java.util.ArrayList;
+
+@InjectViewState
+public class ConferenceVideoPresenter extends ConferenceSDKPresenter
+ implements ConferenceSDKListener {
+
+ @Override
+ protected void onFirstViewAttach() {
+ super.onFirstViewAttach();
+ ActiveConferenceCall activeConferenceCall = mDataManager.getConferenceSDK().
+ getActiveConference();
+ if (activeConferenceCall != null) {
+ getViewState().initConferenceStates(activeConferenceCall);
+ }
+ }
+
+ public void removeFromCall(ConferenceListItem item) {
+ if (item != null) {
+ mDataManager.getConferenceSDK().removeParticipant(item.memberId, item.participantId);
+ }
+ }
+
+ public void muteParticipant(ConferenceListItem item) {
+ if (!item.isMe) {
+ mDataManager.getConferenceSDK().muteParticipant(item.participantId);
+ } else {
+ mDataManager.getConferenceSDK().mute();
+ }
+ }
+
+ public void unMuteParticipant(String participantId) {
+ mDataManager.getConferenceSDK().unMuteParticipant(participantId);
+ }
+
+ public void stopParticipantSS(ConferenceListItem item) {
+ if (!item.isMe) {
+ mDataManager.getConferenceSDK().stopParticipantSS(item.participantId);
+ } else {
+ mDataManager.getConferenceSDK().stopScreenCapture();
+ }
+ }
+
+ public void stopParticipantVideo(ConferenceListItem item) {
+ if (!item.isMe) {
+ mDataManager.getConferenceSDK().stopParticipantVideo(item.participantId);
+ } else {
+ mDataManager.getConferenceSDK().stopCameraCapture();
+ }
+ }
+
+ public void mute() {
+ mDataManager.getConferenceSDK().mute();
+ }
+
+ public void endCall() {
+ mDataManager.getConferenceSDK().endCall();
+ }
+
+ public boolean isConferenceModerator() {
+ return mDataManager.getConferenceSDK().isConferenceModerator();
+ }
+
+ public void showProfile(ConferenceListItem item) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().closenConference();
+ if (!item.isMe) {
+ ContactModel contact = mDataManager.getContactByChatId(item.phoneId);
+ if (contact == null) {
+ contact = new ContactModel();
+ contact.phoneId = item.phoneId;
+ }
+ mRouter.backOrNavigateTo(HomeNavigator.USER_PROFILE, contact);
+ } else {
+ mRouter.backToRoot();
+// mRouter.backOrNavigateTo(HomeNavigator.HOME); //todo my profile ??
+ }
+ }
+
+ public void openChatWithParticipant(String participantPhoneId) {
+ ContactModel contactByChatId = mDataManager.getContactByChatId(participantPhoneId);
+ if (contactByChatId != null) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().closenConference();
+ RoomModel room = new RoomModel(contactByChatId);
+ FragmentTransferObject fto = new FragmentTransferObject(room, null);
+ navigateToChat(fto, FragmentTransferObject.Type.P2pList);
+ }
+ }
+
+ public void loadConferenceParticipants(ActiveConferenceCall activeConferenceCall) {
+ onConferenceMembersUpdate(activeConferenceCall);
+ }
+
+ public void updateActiveSpeakersState(ArrayList participantIds) {
+ if (getAttachedViews().size() == 0) return;
+ ArrayList members = ConferenceVideoModule
+ .getInstance().getUpdatedActiveSpeakersParticipants(participantIds);
+ getViewState().onConferenceMembersUpdate(members);
+ }
+
+ @Override
+ public void onConferenceMembersUpdate(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
+ ArrayList members = getConferenceVideoMembers(activeConferenceCall);
+ getViewState().onConferenceMembersUpdate(members);
+ }
+
+ @Override
+ public void onScreenShareState(boolean active) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onScreenShareStateChanged(active && isScreenSharing());
+ }
+
+ @Override
+ public void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall,
+ String trackId) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onRemoteVideoTrackAdded(activeConferenceCall, trackId);
+ }
+
+ @Override
+ public void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall,
+ String trackId) {
+ getViewState().onRemoteVideoTrackRemoved(activeConferenceCall, trackId);
+ }
+
+ @Override
+ public void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onLocalVideoCapturerStarted(activeConferenceCall);
+ }
+
+ @Override
+ public void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onLocalVideoCapturerStopped(activeConferenceCall);
+ }
+
+ @Override
+ public void onMicrophoneStateChanged(boolean isMuted) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onMicrophoneStateChanged(isMuted);
+ }
+
+ @Override
+ public void onSpeakerStateChanged(boolean isSpeakerOn) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onSpeakerStateChanged(isSpeakerOn);
+ }
+
+ @Override
+ public void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().onActiveSpeakersUpdate(activeSpeakers, participantIds);
+ }
+
+ @Override
+ public void onMuteStateChangedByHost(boolean isMuted) {
+ if (getAttachedViews().size() == 0) return;
+ getViewState().updateMicrophonState(isMuted);
+ }
+
+
+ public void callBackPerson(ConferenceListItem item) {
+ mDataManager.getConferenceSDK().callBackMember(item.memberId, item.phoneId, item.name);
+ }
+
+ public void pauseCallVideoCapturer() {
+ mDataManager.getConferenceSDK().setCallCameraPauseState(true);
+ }
+
+ public void resumeCallVideoCapturer() {
+ mDataManager.getConferenceSDK().setCallCameraPauseState(false);
+ }
+
+ public ArrayList getConferenceVideoMembers(ActiveConferenceCall activeConferenceCall) {
+ return ConferenceVideoModule.getInstance().getConferenceVideoMembers(activeConferenceCall);
+ }
+
+
+ public void switchCamera() {
+ if (getAttachedViews().size() == 0) return;
+ ActiveConferenceCall activeConferenceCall = mDataManager.getConferenceSDK().
+ getActiveConference();
+ if (activeConferenceCall != null && activeConferenceCall.mConference != null) {
+ activeConferenceCall.mConference.switchCamera();
+ }
+ }
+
+}
+
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/InfoPresenter.kt b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/InfoPresenter.kt
index b8464bd52912d6994aa4da44569f15217d7f1935..832d5025b78c07706c829aa01f271ca2b789f95d 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/InfoPresenter.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/InfoPresenter.kt
@@ -56,6 +56,10 @@ class InfoPresenter : BaseLoginPresenter() {
mRouter.newRootScreen(NynjaNavigator.MAIN)
}
+ fun backToLogin() {
+ mRouter.exit();
+ }
+
private var userAvatar: String? = null
private val mResultListener = ResultListener { resultData ->
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/LoginPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/LoginPresenter.java
index 4e494a069e90941b73816ac625faabb47a46f132..50c80fff47a69978fc8437a7696be72279d2564a 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/LoginPresenter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/LoginPresenter.java
@@ -171,13 +171,13 @@ public class LoginPresenter extends BaseLoginPresenter implements Soc
if (mDataManager.invalidProtocol) getViewState().showErrorUpdateVersionDialog();
mDataManager.getAccountSDK().attachLoginCallback(this);
- mDataManager.getAccountSDK().attachCodeCallback(this);
+// mDataManager.getAccountSDK().attachCodeCallback(this);
}
@Override
public void detachView(LoginView view) {
// mDataManager.getAccountSDK().detachLoginCallback(this);
-// mDataManager.getAccountSDK().detachCodeCallback(this);
+ mDataManager.getAccountSDK().detachCodeCallback(this);
mDataManager.getAccountSDK().detachManageProfileCallback(mAccountListener);
super.detachView(view);
}
@@ -192,7 +192,7 @@ public class LoginPresenter extends BaseLoginPresenter implements Soc
public void attachView(LoginView view) {
super.attachView(view);
// mDataManager.getAccountSDK().attachLoginCallback(this);
-// mDataManager.getAccountSDK().attachCodeCallback(this);
+ mDataManager.getAccountSDK().attachCodeCallback(this);
mDataManager.getAccountSDK().attachManageProfileCallback(mAccountListener);
//addDisposable(mDataManager.subscribeToProfile()
// .filter(profile -> profile.getRoster() != null)
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/MainActivityPresenter.kt b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/MainActivityPresenter.kt
index 720b14e1ec4b6b1764cb175a3b060d54c99fb316..923269e60c835f11fd894ff153ce673b40f38637 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/MainActivityPresenter.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/MainActivityPresenter.kt
@@ -364,8 +364,16 @@ class MainActivityPresenter : ConferenceSDKPresenter() {
}
HomeActions.VideoCallAction -> {
- viewState.showAlertNotSupportedFeature()
-// tryStartCall(true, true, true, null)
+// viewState.showAlertNotSupportedFeature()
+// val fto = FragmentTransferObject(null,
+// FragmentTransferObject.Type.OpenGroupVideoConferenceCreate,
+// null)
+// mRouter.navigateTo(HomeNavigator.CHOOSE_USER, fto)
+ if (Consts.CLIENT_ALLOWED_VIDEO_CONFERENCE) {
+ tryStartCall(true, true, true, null)
+ } else {
+ viewState.showAlertMessage(R.string.call_start_video_conference_alert)
+ }
viewState.closeWheel()
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallActivityView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallActivityView.java
index 4769faf639d3d877b981b82a0838f11abbf86f4c..2ffd3c3131984c1da4d6b928efec1fa6e6293908 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallActivityView.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallActivityView.java
@@ -18,6 +18,14 @@ public interface CallActivityView extends ErrorMvpView {
void onRemoteScreenShareTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) ;
+ void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId);
+
+ void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId);
+
+ void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall);
+
+ void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall);
+
void showPurchaseDialog(boolean isModerator, final String message);
void closeActivity();
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallTapToSpeakView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallTapToSpeakView.java
index 8d39df5902d93c5355f6e21a9d8ec13d1571ec60..2f87ef02936c472c23948bb3063edeabafb6e755 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallTapToSpeakView.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallTapToSpeakView.java
@@ -1,6 +1,6 @@
package com.nynja.mobile.communicator.mvp.view;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
/**
* Created by Ergyun Syuleyman on 9/14/18.
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallView.java
index d891294e743879f7f47fe07bf611cf2605ea2ee8..d718d095ffe79e3494a69ddd827a6afee6314c79 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallView.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/CallView.java
@@ -2,7 +2,7 @@ package com.nynja.mobile.communicator.mvp.view;
import android.support.annotation.StringRes;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
@@ -42,6 +42,8 @@ public interface CallView extends ErrorMvpView {
void onCreateVideoCallReady(ActiveConferenceCall activeConferenceCall);
+ void onStartCapturerFailed(int msgResId, boolean isCamera);
+
void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) ;
void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) ;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/ConferenceVideoView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/ConferenceVideoView.java
new file mode 100644
index 0000000000000000000000000000000000000000..50d0d40f89a6e81ba154fdc38b068836ccdf2538
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/ConferenceVideoView.java
@@ -0,0 +1,35 @@
+package com.nynja.mobile.communicator.mvp.view;
+
+import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+
+import java.util.ArrayList;
+
+public interface ConferenceVideoView extends ErrorMvpView {
+
+ void initConferenceStates(ActiveConferenceCall activeConferenceCall);
+
+ void onConferenceMembersUpdate(ArrayList members);
+
+ void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) ;
+
+ void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) ;
+
+ void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall) ;
+
+ void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall) ;
+
+ void onScreenShareStateChanged(boolean isSharing);
+
+ void onMicrophoneStateChanged(boolean isMuted);
+
+ void onSpeakerStateChanged(boolean isSpeakerOn);
+
+ void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds);
+
+ void updateMicrophonState(boolean isMuted);
+
+ void closenConference();
+
+}
+
diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/MainActivityView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/MainActivityView.java
index e2b7a3e30956aa0e99f7ee7869e3d587f7e56fbf..4ecb0e41d9a0887eab0044780ce2142157d5960c 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/MainActivityView.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/MainActivityView.java
@@ -74,4 +74,6 @@ public interface MainActivityView extends JoinGroupView {
void showPurchaseDialog(boolean isModerator, final String message);
void tryStartCall(boolean createNew, boolean isGroup, boolean isVideo, Parcelable prevModel);
+
+ void showAlertMessage(int res);
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/MainActivity.java b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/MainActivity.java
index 5ecff4d479cb1ec6ba94c835ed023fd7d9785e98..cc4a659d4112f93443722db0a4b11e8a5bc7a3da 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/MainActivity.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/MainActivity.java
@@ -629,17 +629,17 @@ public class MainActivity extends BaseActivity implements MainActivityView,
chatAudioLayout.setVisibility(View.VISIBLE);
mPresenter.requestUser();
//TODO: video feeds support in next features
- //if (!activeConferenceCall.isOwnStreamActive || !activeConferenceCall.hasRemoteVideoTrack) {
+ //if (!activeConferenceCall.mData.isOwnStreamActive || !activeConferenceCall.hasRemoteVideoTrack) {
// video.setVisibility(View.GONE);
// chatAudioLayout.setVisibility(View.VISIBLE);
// mPresenter.requestUser();
// if (activeConferenceCall.mConference != null)
- // activeConferenceCall.mConference.setRemoteVideoRenderer(video);
+ // activeConferenceCall.mConference.setVideoRendererForTrack(video);
//} else {
// video.setVisibility(View.VISIBLE);
// chatAudioLayout.setVisibility(View.GONE);
// if (activeConferenceCall.mConference != null) {
- // activeConferenceCall.mConference.setRemoteVideoRenderer(null);
+ // activeConferenceCall.mConference.setVideoRendererForTrack(null);
// }
//}
}
@@ -668,6 +668,14 @@ public class MainActivity extends BaseActivity implements MainActivityView,
onCallPermission(false, isVideo, createNew, isGroup, prevModel);
}
+ @Override
+ public void showAlertMessage(int res) {
+ DialogFactory.showAlertDialog(this,
+ getString(res),
+ getString(R.string.signin_text_ok),
+ (dialog, which) -> dialog.dismiss());
+ }
+
@Override
public void openActiveConference() {
mPresenter.navigateToActiveCall();
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/CallActivity.java b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/CallActivity.java
index 4346ba422c430ff9f0cad7263f23b2a0b7a189ac..f8f34f2abd68951c176cda409e577528c8be2b77 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/CallActivity.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/CallActivity.java
@@ -5,26 +5,22 @@ import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
-import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.media.projection.MediaProjectionManager;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.provider.Settings;
import android.support.v4.view.ViewPager;
-import android.widget.LinearLayout;
import com.arellomobile.mvp.presenter.InjectPresenter;
import com.nynja.mobile.communicator.R;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
import com.nynja.mobile.communicator.mvp.presenters.CallActivityPresenter;
import com.nynja.mobile.communicator.mvp.view.CallActivityView;
-import com.nynja.mobile.communicator.ui.adapters.ActiveCallPagerAdapter;
+import com.nynja.mobile.communicator.ui.adapters.conference.ActiveCallPagerAdapter;
import com.nynja.mobile.communicator.ui.base.BaseActivity;
import com.nynja.mobile.communicator.ui.views.CirclePageIndicator;
import com.nynja.mobile.communicator.ui.views.CustomViewPager;
@@ -35,6 +31,7 @@ import org.webrtc.ContextUtils;
import org.webrtc.VideoSourceUtility;
import butterknife.BindView;
+import kotlin.jvm.Synchronized;
import ru.terrakok.cicerone.Navigator;
import timber.log.Timber;
@@ -42,10 +39,11 @@ public class CallActivity extends BaseActivity implements CallActivityView {
private static final int CAPTURE_PERMISSION_REQUEST_CODE = 1;
- public boolean isScreenShareActive;
@BindView(R.id.active_call_viewpager) CustomViewPager mViewPager;
@BindView(R.id.active_call_indicator) CirclePageIndicator mIndicator;
+// @BindView(R.id.active_call_rv) RecyclerView mRecyclerView;
+
@InjectPresenter CallActivityPresenter mPresenter;
public interface BluetoothConnectivityListener {
@@ -56,6 +54,7 @@ public class CallActivity extends BaseActivity implements CallActivityView {
private ActiveCallPagerAdapter mPagerAdapter;
+ private int mSelectedPage = -1;
public static Intent getLaunchIntent(Context context) {
Intent intent = new Intent(context, CallActivity.class);
@@ -76,6 +75,12 @@ public class CallActivity extends BaseActivity implements CallActivityView {
mPresenter.bluetoothConnected();
}
+ initUI();
+
+ registerBluetoothReceiver();
+ }
+
+ private void initUI() {
mPagerAdapter = new ActiveCallPagerAdapter(this);
mViewPager.setAdapter(mPagerAdapter);
addPageViewListener();
@@ -83,7 +88,27 @@ public class CallActivity extends BaseActivity implements CallActivityView {
mIndicator.setSaveEnabled(false);
mIndicator.setViewPager(mViewPager, ActiveCallPagerAdapter.CallPages.CallPageActiveCallFragment.ordinal());
mIndicator.notifyDataSetChanged();
- registerBluetoothReceiver();
+ }
+
+ private void initUIRv() {
+// final DefaultItemAnimator itemAnimator = new DefaultItemAnimator();
+// itemAnimator.setSupportsChangeAnimations(false);
+// mRecyclerView.setItemAnimator(itemAnimator);
+// mRecyclerView.setNestedScrollingEnabled(false);
+// mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));
+// mRecyclerView.setHasFixedSize(true);
+// //mRecyclerView.setAdapter(ActiveCallAdapter);
+// mRecyclerView.addItemDecoration(new CirclePagerIndicatorDecoration(R.dimen.rv_indicator_radius,
+// R.dimen.rv_indicator_padding,
+// R.dimen.rv_indicator_height,
+// R.color.wheel_unselected_corner_bg,
+// R.color.colorAccent));
+// new PagerSnapHelper().attachToRecyclerView(mRecyclerView);
+ }
+
+ public boolean isScreenShareActive() {
+ if (mPagerAdapter != null) return mPagerAdapter.isScreenShareActive;
+ return false;
}
@Override
@@ -93,39 +118,48 @@ public class CallActivity extends BaseActivity implements CallActivityView {
mPagerAdapter.onConfigurationChanged(newConfig, mViewPager.getCurrentItem());
}
- protected void addPageViewListener() {
- if (mViewPager == null) return;
- mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- Timber.d("CallActivity::onPageScrolled(): position=%d, positionOffset=%f, " +
- "positionOffsetPixels=%d", position, positionOffset, positionOffsetPixels);
- }
+ protected ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ Timber.d("CallActivity::onPageScrolled(): position=%d, positionOffset=%f, " +
+ "positionOffsetPixels=%d", position, positionOffset, positionOffsetPixels);
+ }
- @Override
- public void onPageSelected(int position) {
- Timber.d("CallActivity::onPageSelected(): page=%d", position);
+ @Override
+ public void onPageSelected(int position) {
+ Timber.d("CallActivity::onPageSelected(): page=%d", position);
// if (position == ActiveCallPagerAdapter.CallPages.CallPageActiveCallFragment.ordinal()) {
// mIndicator.setVisibility(View.GONE);
// } else {
// mIndicator.setVisibility(View.VISIBLE);
// }
- synchronized (mPagerAdapter) {
- mPagerAdapter.setFragmentActiveByPosition(position);
+ synchronized (mPagerAdapter) {
+// mPagerAdapter.setFragmentActiveByPosition(position);
+ if (mSelectedPage >= 0) {
+ mPagerAdapter.setFragmentActiveByPosition(mSelectedPage, false);
}
+ mPagerAdapter.setFragmentActiveByPosition(position, true);
+ mSelectedPage = position;
}
+ }
- @Override
- public void onPageScrollStateChanged(int state) {
- Timber.d("CallActivity::onPageScrollStateChanged(): state=%d", state);
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ Timber.d("CallActivity::onPageScrollStateChanged(): state=%d", state);
- }
- });
+ }
+ };
+
+ protected void addPageViewListener() {
+ if (mViewPager == null) return;
+ mViewPager.addOnPageChangeListener(mOnPageChangeListener);
}
- public void showShareScreen(boolean show) {
- isScreenShareActive = show;
+ protected void showShareScreen(boolean show) {
+ int currentItem = mIndicator.getCurrentItem();
+ ActiveCallPagerAdapter.CallPages page = mPagerAdapter.getPageByPosition(currentItem);
synchronized (mPagerAdapter) {
+ mViewPager.removeOnPageChangeListener(mOnPageChangeListener);
mViewPager.setAdapter(null);
if (show) {
mPagerAdapter.showShareScreen();
@@ -133,11 +167,12 @@ public class CallActivity extends BaseActivity implements CallActivityView {
mPagerAdapter.hideShareScreen();
}
+ mViewPager.addOnPageChangeListener(mOnPageChangeListener);
mViewPager.setAdapter(mPagerAdapter);
}
// addPageViewListener();
// set to position 1
- mIndicator.setViewPager(mViewPager, ActiveCallPagerAdapter.CallPages.ShareScreenFragment.ordinal());
+ mIndicator.setViewPager(mViewPager, mPagerAdapter.getFragmentPositionByType(page));
mIndicator.notifyDataSetChanged();
}
@@ -149,9 +184,11 @@ public class CallActivity extends BaseActivity implements CallActivityView {
@Override
protected void onDestroy() {
unregisterReceiver(mBluetoothReceiver);
- releaseWakeLockActivity();
- mViewPager.removeAllViews();
mPagerAdapter.reset();
+ mViewPager.removeAllViews();
+ ContextUtils.releaseRootEglBase();
+ ContextUtils.releaseSSEglBase();
+ releaseWakeLockActivity();
super.onDestroy();
}
@@ -181,6 +218,10 @@ public class CallActivity extends BaseActivity implements CallActivityView {
return mIndicator;
}
+ public void goToPage(ActiveCallPagerAdapter.CallPages page) {
+ mIndicator.setCurrentItem(mPagerAdapter.getFragmentPositionByType(page));
+ }
+
@TargetApi(21)
private void prepareScreenCapture() {
MediaProjectionManager mediaProjectionManager =
@@ -210,8 +251,10 @@ public class CallActivity extends BaseActivity implements CallActivityView {
@Override
public void initConferenceStates(ActiveConferenceCall activeConferenceCall) {
- if (activeConferenceCall != null && activeConferenceCall.hasRemoteScreenShareTrack) {
- showShareScreen(true);
+ if (activeConferenceCall == null) return;
+ if (mPagerAdapter != null) {
+ mPagerAdapter.initFlags(activeConferenceCall.mData.hasRemoteScreenShareTrack,
+ (activeConferenceCall.mData.hasRemoteVideoTrack() || activeConferenceCall.mData.isOwnStreamActive));
}
}
@@ -302,24 +345,104 @@ public class CallActivity extends BaseActivity implements CallActivityView {
@Override
public void onRemoteScreenShareTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) {
- final boolean hasRemoteScreenShareTrack = (activeConferenceCall != null && activeConferenceCall.hasRemoteScreenShareTrack);
- runOnUiThread(() -> {
+ final boolean hasRemoteScreenShareTrack = (activeConferenceCall != null && activeConferenceCall.mData.hasRemoteScreenShareTrack);
+ mHandler.postDelayed(() -> {
if (hasRemoteScreenShareTrack) {
showShareScreen(true);
}
- });
+ }, Consts.DELAY_100);
}
@Override
public void onRemoteScreenShareTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) {
- runOnUiThread(() -> {
+ mHandler.postDelayed(() -> {
showShareScreen(false);
- });
+ }, Consts.DELAY_100);
+ }
+
+ @Override
+ public void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) {
+ mHandler.postDelayed(() -> {
+ tryUpdateConferenceVideoScreen(activeConferenceCall, true, false);
+ }, Consts.DELAY_100);
+ }
+
+ @Override
+ public void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) {
+ mHandler.postDelayed(() -> {
+ tryUpdateConferenceVideoScreen(activeConferenceCall, false, false);
+ }, Consts.DELAY_100);
}
+ @Override
+ public void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall) {
+ mHandler.postDelayed(() -> {
+ tryUpdateConferenceVideoScreen(activeConferenceCall, true, true);
+ }, Consts.DELAY_100);
+ }
+
+ @Override
+ public void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall) {
+ mHandler.postDelayed(() -> {
+ tryUpdateConferenceVideoScreen(activeConferenceCall, false, true);
+ }, Consts.DELAY_200);
+ }
@Override public Navigator getActivityNavigator() {
return null;
}
+ @Synchronized
+ private void tryUpdateConferenceVideoScreen(ActiveConferenceCall activeConferenceCall,
+ boolean show, boolean isMyVideo) {
+ if (activeConferenceCall == null) {
+ return;
+ }
+ if (!activeConferenceCall.isConference()) {
+ return;
+ }
+ int currentItem = mIndicator.getCurrentItem();
+ ActiveCallPagerAdapter.CallPages page = mPagerAdapter.getPageByPosition(currentItem);
+ boolean goToMyFeed = (show && isMyVideo && page != ActiveCallPagerAdapter.CallPages.ConferenceVideoFragment);
+ if (show && mPagerAdapter.isConferenceVideoActive) {
+ if (goToMyFeed) {
+ mPagerAdapter.tryToGoTooMyVideoFeed();
+ goToPage(ActiveCallPagerAdapter.CallPages.ConferenceVideoFragment);
+ }
+ return;
+ }
+
+ boolean updated = false;
+ synchronized (mPagerAdapter) {
+ if (show && (activeConferenceCall.mData.hasRemoteVideoTrack() || activeConferenceCall.mData.isOwnStreamActive)) {
+ mViewPager.removeOnPageChangeListener(mOnPageChangeListener);
+ mViewPager.setAdapter(null);
+ mPagerAdapter.showConferenceVideoScreen();
+ mViewPager.addOnPageChangeListener(mOnPageChangeListener);
+ mViewPager.setAdapter(mPagerAdapter);
+ updated = true;
+ } else if (!activeConferenceCall.mData.hasRemoteVideoTrack() && !activeConferenceCall.mData.isOwnStreamActive){
+ mViewPager.removeOnPageChangeListener(mOnPageChangeListener);
+ mViewPager.setAdapter(null);
+ mPagerAdapter.hideConferenceVideoScreen();
+ mViewPager.addOnPageChangeListener(mOnPageChangeListener);
+ mViewPager.setAdapter(mPagerAdapter);
+ updated = true;
+ }
+ }
+ // set to position 1
+ if (updated) {
+
+ if (goToMyFeed) {
+ page = ActiveCallPagerAdapter.CallPages.ConferenceVideoFragment;
+ }
+ mIndicator.setViewPager(mViewPager, mPagerAdapter.getFragmentPositionByType(page));
+ mIndicator.notifyDataSetChanged();
+
+ mHandler.postDelayed(() -> {
+ mPagerAdapter.tryToGoTooMyVideoFeed();
+ }, Consts.DELAY_200);
+ }
+ }
+
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChatLanguageAdapter.kt b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChatLanguageAdapter.kt
index fa8edda924bf9e0eb9f9a402bd51526a050b3b57..7425f187a6d97c071053afecb6b0bdbc46cd249a 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChatLanguageAdapter.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChatLanguageAdapter.kt
@@ -38,7 +38,7 @@ class ChatLanguageAdapter(list: List, val onItemClickListener: On
}
override fun onBindHeaderViewHolder(holder: CountryPickerLetterViewHolder, position: Int) {
- holder.bind(getCellChar(position).toString())
+ holder.bind(getCellChar(position).toString(), position)
}
private fun getCellChar(position: Int): Char {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChooseUserVerticalAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChooseUserVerticalAdapter.java
index 1fdc9cc31d4aeac978c78540b63b104a4d583dfe..1a7a4f64ed57e84b2b4000411cf3fdc71d49e33c 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChooseUserVerticalAdapter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ChooseUserVerticalAdapter.java
@@ -71,7 +71,7 @@ public class ChooseUserVerticalAdapter extends BaseSelectableModelAdapter contacts) {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ContactsAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ContactsAdapter.java
index 355bf7891b01e34cce2a02ff6b94661af9e8fc70..1620eccd6eba59c3bf177a0db4d50ca1a4f9958e 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ContactsAdapter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ContactsAdapter.java
@@ -46,7 +46,7 @@ public class ContactsAdapter extends BaseAdapter implem
}
@Override public void onBindHeaderViewHolder(ContactHeaderVh holder, int position) {
- holder.bind(String.valueOf(getCellChar(position)));
+ holder.bind(String.valueOf(getCellChar(position)), position);
}
private char getCellChar(int position) {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/CountryPickerAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/CountryPickerAdapter.java
index 147cd34646c272cc954625b3a0b52449e041b4c2..660b7389c46e59d4a9198388bb2cb6dd7a2ed79a 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/CountryPickerAdapter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/CountryPickerAdapter.java
@@ -50,7 +50,7 @@ public class CountryPickerAdapter extends BaseAdapter mAdapterPages = new HashMap<>();
private List callPages = new ArrayList<>();
+ public boolean isScreenShareActive = false;
+ public boolean isConferenceVideoActive = false;
private CallActivity callActivity;
+ public enum CallPages {
+ CallPageTapToSpeak,
+ ShareScreenFragment,
+ CallPageActiveCallFragment,
+ ConferenceVideoFragment
+
+ }
+
+ public ActiveCallPagerAdapter(CallActivity callActivity) {
+ super(callActivity);
+ this.callActivity = callActivity;
+ preparePages();
+ }
+
+ public void initFlags(boolean isScreenShareActive, boolean isConferenceVideoActive) {
+ this.isScreenShareActive = isScreenShareActive;
+ this.isConferenceVideoActive = isConferenceVideoActive;
+ preparePages();
+ }
+
+ @Synchronized
public void reset() {
for (CallPages callPage : CallPages.values()) {
final String itemId = makeFragmentId(getItemId(callPage.ordinal()));
@@ -39,40 +64,65 @@ public class ActiveCallPagerAdapter extends NynjaViewPagerAdapter {
}
this.callActivity = null;
callPages.clear();
+ notifyDataSetChanged();
}
- public void hideShareScreen() {
- final String itemId = makeFragmentId(getItemId(CallPages.ShareScreenFragment.ordinal()));
+ @Synchronized
+ private void preparePages() {
+
+ for (CallPages callPage : callPages) {
+ if (callPage == CallPages.ShareScreenFragment && !isScreenShareActive) {
+ final String itemId = makeFragmentId(getItemId(callPage.ordinal()));
+ BaseFragment fragment = mAdapterPages.get(itemId);
+ if (fragment != null) {
+ destroyView(fragment);
+ }
+ mAdapterPages.remove(itemId);
+ }
+// if (callPage == CallPages.ConferenceVideoFragment && !isConferenceVideoActive) {
+// final String itemId = makeFragmentId(getItemId(callPage.ordinal()));
+// BaseFragment fragment = mAdapterPages.get(itemId);
+// if (fragment != null) {
+// destroyView(fragment);
+// }
+// mAdapterPages.remove(itemId);
+// }
+ }
callPages.clear();
for (CallPages callPage : CallPages.values()) {
- if (callPage == CallPages.ShareScreenFragment) {
+ if (callPage == CallPages.ShareScreenFragment && !isScreenShareActive) {
+ continue;
+ }
+ if (callPage == CallPages.ConferenceVideoFragment && !isConferenceVideoActive) {
continue;
}
callPages.add(callPage);
}
- mAdapterPages.remove(itemId);
notifyDataSetChanged();
}
+ public void hideShareScreen() {
+ isScreenShareActive = false;
+ preparePages();
+ }
+
public void showShareScreen() {
- callPages.clear();
- callPages.addAll(Arrays.asList(CallPages.values()));
- notifyDataSetChanged();
+ isScreenShareActive = true;
+ preparePages();
}
- public enum CallPages {
- CallPageTapToSpeak,
- ShareScreenFragment,
- CallPageActiveCallFragment
+ public void hideConferenceVideoScreen() {
+ isConferenceVideoActive = false;
+ preparePages();
}
- public ActiveCallPagerAdapter(CallActivity callActivity) {
- super(callActivity);
- this.callActivity = callActivity;
- hideShareScreen();
+ public void showConferenceVideoScreen() {
+ isConferenceVideoActive = true;
+ preparePages();
}
+ @Synchronized
public BaseFragment getItem(int position) {
final String itemId = makeFragmentId(getItemId(position));
BaseFragment fragment = mAdapterPages.get(itemId);
@@ -99,6 +149,12 @@ public class ActiveCallPagerAdapter extends NynjaViewPagerAdapter {
((ScreenShareFragment) fragment).setCallActivity(callActivity);
((ScreenShareFragment)fragment).setIsActive(false);
}
+ } else if (callPages.get(position) == CallPages.ConferenceVideoFragment) {
+ fragment = new ConferenceVideoFragment();
+ if (callActivity != null) {
+ ((ConferenceVideoFragment) fragment).setCallActivity(callActivity);
+ ((ConferenceVideoFragment)fragment).setIsActive(false);
+ }
}
// if (position == CallPages.CallPageTapToSpeak.ordinal()) {
@@ -162,21 +218,30 @@ public class ActiveCallPagerAdapter extends NynjaViewPagerAdapter {
return mAdapterPages.get(itemId);
}
- protected void setFragmentActiveByPosition(int position, boolean active) {
+ public void setFragmentActiveByPosition(int position, boolean active) {
BaseFragment fragment = getItemByPosition(position);
if (fragment == null) return;
if (position == CallPages.CallPageTapToSpeak.ordinal()
&& fragment instanceof CallTapToSpeakFragment) {
((CallTapToSpeakFragment)fragment).setActiveState(active);
- } else if (position == CallPages.ShareScreenFragment.ordinal()
- && fragment instanceof ScreenShareFragment) {
- ((ScreenShareFragment)fragment).setActiveState(active);
- } else if (position == CallPages.CallPageActiveCallFragment.ordinal()
- && fragment instanceof ConferenceCallFragment) {
- ((ConferenceCallFragment)fragment).setActiveState(active);
- } else if (position == CallPages.ShareScreenFragment.ordinal()
- && fragment instanceof ConferenceCallFragment) {
- ((ConferenceCallFragment)fragment).setActiveState(active);
+ } else if (position == CallPages.ShareScreenFragment.ordinal()) {
+ if (fragment instanceof ScreenShareFragment) {
+ ((ScreenShareFragment)fragment).setActiveState(active);
+ } else if (fragment instanceof ConferenceCallFragment) {
+ ((ConferenceCallFragment) fragment).setActiveState(active);
+ } else if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).setActiveState(active);
+ }
+ } else if (position == CallPages.CallPageActiveCallFragment.ordinal()) {
+ if (fragment instanceof ConferenceCallFragment) {
+ ((ConferenceCallFragment)fragment).setActiveState(active);
+ } else if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).setActiveState(active);
+ }
+ } else if (position == CallPages.ConferenceVideoFragment.ordinal()) {
+ if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).setActiveState(active);
+ }
}
}
@@ -186,6 +251,27 @@ public class ActiveCallPagerAdapter extends NynjaViewPagerAdapter {
}
}
+ @Synchronized
+ public int getFragmentPositionByType(CallPages page) {
+ int index = 0;
+ for (CallPages p : callPages) {
+ if (p == page) {
+ return index;
+ }
+ ++index;
+ }
+ return page.ordinal();
+ }
+
+ @Synchronized
+ public CallPages getPageByPosition( int position) {
+ CallPages page = CallPages.CallPageActiveCallFragment;
+ if (position < callPages.size()) {
+ page = callPages.get(position);
+ }
+ return page;
+ }
+
public void onConfigurationChanged(Configuration newConfig, int position) {
BaseFragment fragment = getItemByPosition(position);
if (fragment == null) return;
@@ -193,11 +279,46 @@ public class ActiveCallPagerAdapter extends NynjaViewPagerAdapter {
&& fragment instanceof CallTapToSpeakFragment)
|| (position == CallPages.ShareScreenFragment.ordinal()
&& fragment instanceof ScreenShareFragment)
+ || (position == CallPages.ShareScreenFragment.ordinal()
+ && fragment instanceof ConferenceVideoFragment)
+ || (position == CallPages.ShareScreenFragment.ordinal()
+ && fragment instanceof ConferenceCallFragment)
|| (position == CallPages.CallPageActiveCallFragment.ordinal()
&& fragment instanceof ConferenceCallFragment)
- || (position == CallPages.ShareScreenFragment.ordinal()
- && fragment instanceof ConferenceCallFragment)) {
+ || (position == CallPages.CallPageActiveCallFragment.ordinal()
+ && fragment instanceof ConferenceVideoFragment)
+ || (position == CallPages.ConferenceVideoFragment.ordinal()
+ && fragment instanceof ConferenceVideoFragment)
+ ) {
fragment.onConfigurationChanged(newConfig);
}
}
+
+ public void tryToGoTooMyVideoFeed() {
+ int position = 0;
+ for (; position < callPages.size(); position++ ) {
+ if (position == CallPages.ShareScreenFragment.ordinal()) {
+ final String itemId = makeFragmentId(getItemId(position));
+ BaseFragment fragment = mAdapterPages.get(itemId);
+ if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).tryToGoTooMyVideoFeed();;
+ return;
+ }
+ } else if (position == CallPages.CallPageActiveCallFragment.ordinal()) {
+ final String itemId = makeFragmentId(getItemId(position));
+ BaseFragment fragment = mAdapterPages.get(itemId);
+ if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).tryToGoTooMyVideoFeed();;
+ return;
+ }
+ } else if (position == CallPages.ConferenceVideoFragment.ordinal()) {
+ final String itemId = makeFragmentId(getItemId(position));
+ BaseFragment fragment = mAdapterPages.get(itemId);
+ if (fragment instanceof ConferenceVideoFragment) {
+ ((ConferenceVideoFragment)fragment).tryToGoTooMyVideoFeed();;
+ return;
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ConferenceParticipantsAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceParticipantsAdapter.java
similarity index 94%
rename from app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ConferenceParticipantsAdapter.java
rename to app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceParticipantsAdapter.java
index 3f978282a5160313fe70242d748ffdb3deb5231d..f1e40fff287e6ab5169c06e7cbc485b8e02f502f 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/ConferenceParticipantsAdapter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceParticipantsAdapter.java
@@ -1,4 +1,4 @@
-package com.nynja.mobile.communicator.ui.adapters;
+package com.nynja.mobile.communicator.ui.adapters.conference;
import android.content.Context;
import android.support.annotation.NonNull;
@@ -10,7 +10,7 @@ import android.widget.ArrayAdapter;
import com.nynja.mobile.communicator.R;
import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
import com.nynja.mobile.communicator.interfaces.OnConferenceItemClickListener;
-import com.nynja.mobile.communicator.ui.adapters.viewholders.ConferenceContactVh;
+import com.nynja.mobile.communicator.ui.adapters.viewholders.conference.ConferenceContactVh;
import java.util.ArrayList;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceVideoAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceVideoAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..0956d049d755aed605485fe7afe2ad6796d11640
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/conference/ConferenceVideoAdapter.java
@@ -0,0 +1,149 @@
+package com.nynja.mobile.communicator.ui.adapters.conference;
+
+import android.content.Context;
+import android.graphics.Insets;
+import android.support.annotation.NonNull;
+import android.util.DisplayMetrics;
+import android.util.Size;
+import android.view.Display;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.nynja.mobile.communicator.NynjaApp;
+import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+import com.nynja.mobile.communicator.interfaces.OnConferenceVideoFeedClickListener;
+import com.nynja.mobile.communicator.ui.activities.calls.CallActivity;
+import com.nynja.mobile.communicator.ui.adapters.viewholders.conference.ConferenceVideoItemVh;
+import com.nynja.mobile.communicator.ui.base.BaseAdapter;
+import com.nynja.mobile.communicator.ui.base.BaseVH;
+
+import java.util.HashSet;
+import java.util.List;
+
+import static com.nynja.mobile.communicator.data.conference.ConferenceVideoModule.MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+import static com.nynja.mobile.communicator.data.conference.ConferenceVideoModule.MAX_VIDEO_FEEDS_ROW_SIZE;
+
+public class ConferenceVideoAdapter> extends BaseAdapter {
+
+ private OnConferenceVideoFeedClickListener mOnConferenceVideoFeedClickListener;
+ private boolean mIsModerator = false;
+ private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+ private int mScreenWidth = 0;
+ private int mScreenHeight = 0;
+ HashSet mHoldersSet;
+
+ public ConferenceVideoAdapter(List list,
+ OnConferenceVideoFeedClickListener onConferenceItemClickListener) {
+ super(list);
+ this.mOnConferenceVideoFeedClickListener = onConferenceItemClickListener;
+ mHoldersSet = new HashSet<>();
+ setHasStableIds(true);
+ }
+
+ public void setOnItemClickListener(OnConferenceVideoFeedClickListener onConferenceItemClickListener) {
+ this.mOnConferenceVideoFeedClickListener = onConferenceItemClickListener;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ if (position < getItemCount()) {
+ return getItem(position).hashCode();
+ }
+ return -1L;
+ }
+
+ public void setIsModerator(boolean isModerator) {
+ this.mIsModerator = isModerator;
+ }
+
+ public boolean isModerator() {
+ return this.mIsModerator;
+ }
+
+ public void releaseVideoCallRrenderers() {
+ for (ConferenceVideoItemVh vh : mHoldersSet) {
+ vh.onViewRecycled();
+ vh.releaseVideoCallRrenderers();
+ }
+ mHoldersSet.clear();
+
+ clear();
+ }
+
+ public int getoMyVideoFeedPostion() {
+ int pos = 0;
+ for (ConferenceListItem item : getItems()) {
+ if (item.isMe) return pos;
+ ++pos;
+ }
+ return -1;
+ }
+
+ @NonNull
+ @Override
+ public T onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
+ ConferenceVideoItemVh viewHolder = new ConferenceVideoItemVh(viewGroup, mIsModerator);
+ viewHolder.setOnClickListener(mOnConferenceVideoFeedClickListener);
+ if (viewGroup.getContext() instanceof CallActivity) {
+ WindowManager wm = (WindowManager) NynjaApp.getComponent().context().getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ display.getMetrics(mDisplayMetrics);
+ mScreenWidth = mDisplayMetrics.widthPixels;
+ mScreenHeight = (int) (mDisplayMetrics.heightPixels - mDisplayMetrics.densityDpi/mDisplayMetrics.density);
+ }
+ mHoldersSet.add(viewHolder);
+ return (T) viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(T holder, int position) {
+ super.onBindViewHolder(holder, position);
+ if (mScreenWidth > 0) {
+ float divWidth = ConferenceVideoModule.getInstance().getWidthDiv(position);
+ float divHeight = ConferenceVideoModule.getInstance().getHeightDiv(position);
+ ////////////////////////////////////////////////////
+ //if (position == 2) ((ConferenceVideoItemVh) holder).getItem().isVideoFullScreen = true;
+ //if (((ConferenceVideoItemVh) holder).getItem().isVideoFullScreen) {
+ // divH = 1f; divV = 1f;
+ //}
+ ////////////////////////////////////////////////////
+ int itemWidth = (int) (mScreenWidth / divWidth);
+ int itemHeight = (int) (mScreenHeight / divHeight);
+ ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
+ if (divHeight == MAX_VIDEO_FEEDS_COLUIMN_SIZE) {
+ layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ } else {
+ layoutParams.height = itemHeight;
+ }
+ if (divWidth == 1) {
+ layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ } else {
+ layoutParams.width = itemWidth - ConferenceVideoModule.getInstance().getWidthDividerLength(position);
+ }
+ holder.itemView.setLayoutParams(layoutParams);
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return super.getItemViewType(position);
+ }
+
+ @Override public void onViewAttachedToWindow(@NonNull T holder) {
+ super.onViewAttachedToWindow(holder);
+ ((ConferenceVideoItemVh) holder).onViewAttachedToWindow();
+ }
+
+ @Override public void onViewDetachedFromWindow(@NonNull T holder) {
+ super.onViewDetachedFromWindow(holder);
+ ((ConferenceVideoItemVh) holder).onViewDetachedFromWindow();
+ }
+
+ @Override
+ public void onViewRecycled(@NonNull T holder) {
+ super.onViewRecycled(holder);
+ ((ConferenceVideoItemVh)holder).onViewRecycled();
+ }
+}
+
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/ConferenceContactVh.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceContactVh.java
similarity index 98%
rename from app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/ConferenceContactVh.java
rename to app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceContactVh.java
index 7ea4d9ee01f67a3e7fc6435c513facfefd24456b..e97f58d1dbe92b33f2f06856aef59b5fcb97d491 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/ConferenceContactVh.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceContactVh.java
@@ -1,4 +1,4 @@
-package com.nynja.mobile.communicator.ui.adapters.viewholders;
+package com.nynja.mobile.communicator.ui.adapters.viewholders.conference;
import android.content.Context;
import android.view.LayoutInflater;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceVideoItemVh.java b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceVideoItemVh.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c4e0165619eed1659081743eda384ac3ee6596f
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/adapters/viewholders/conference/ConferenceVideoItemVh.java
@@ -0,0 +1,262 @@
+package com.nynja.mobile.communicator.ui.adapters.viewholders.conference;
+
+import android.graphics.Color;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.nynja.mobile.communicator.R;
+import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+import com.nynja.mobile.communicator.interfaces.OnConferenceVideoFeedClickListener;
+import com.nynja.mobile.communicator.ui.base.BaseVH;
+import com.nynja.mobile.communicator.ui.views.CheckableImageView;
+import com.nynja.mobile.communicator.utils.StringUtils;
+
+import org.webrtc.RendererCommon;
+import org.webrtc.SurfaceViewRenderer;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import kotlin.jvm.Synchronized;
+import timber.log.Timber;
+
+import static org.webrtc.ContextUtils.createRootEglBase;
+
+public class ConferenceVideoItemVh extends BaseVH {
+
+ @BindView(R.id.conf_video_muted) ImageView mMutedIndicator;
+ @BindView(R.id.conf_video_name) TextView mName;
+ @BindView(R.id.conf_video_ss) CheckableImageView mSS;
+ @BindView(R.id.conf_video_active) CheckableImageView mActiveVideo;
+ @BindView(R.id.conf_video_feed) SurfaceViewRenderer mVideoFeed;
+ @BindView(R.id.conf_video_holder_layout) FrameLayout mFeedFrameLayout;
+ //@BindView(R.id.conf_participant_item) RelativeLayout mFeedFrameLayout;
+ @BindView(R.id.video_active_switch_camera) ImageView mSwithCamera;
+
+ protected ConferenceListItem mItem;
+ private OnConferenceVideoFeedClickListener mListener;
+ private boolean mIsModerator;
+ private boolean mIsRenderersInitialized = false;
+
+ public ConferenceVideoItemVh(ViewGroup parent, boolean isModerator) {
+ super(parent, R.layout.li_conference_video);
+ mIsModerator = isModerator;
+ }
+
+ public void setOnClickListener(OnConferenceVideoFeedClickListener listener) {
+ this.mListener = listener;
+ }
+
+
+ @Override public void bind() {
+ //mUnbinder = ButterKnife.bind(this, itemView);
+ }
+
+ @Override public void bind(ConferenceListItem item, int position) {
+ mPosition = position;
+ if (mUnbinder != null) {
+ //mUnbinder.unbind();
+ } else {
+ mUnbinder = ButterKnife.bind(this, itemView);
+ }
+ setData(item);
+ }
+
+ public SurfaceViewRenderer getVideoFeed() {
+ return mVideoFeed;
+ }
+
+ public ConferenceListItem getItem() {
+ return mItem;
+ }
+
+ @Override public void setData(ConferenceListItem item) {
+ this.mItem = item;
+ mSS.setAutoToggle(false);
+ mActiveVideo.setAutoToggle(false);
+ mName.setText(item.name);
+ itemView.setOnClickListener(null);
+ itemView.setOnLongClickListener(null);
+ if (mListener != null) {
+ item.initActions(mIsModerator);
+ itemView.setOnClickListener(v -> mListener.onItemClick(item, mPosition));
+ itemView.setOnLongClickListener(v -> mListener.onItemLongClick(item, mPosition));
+ }
+ itemView.setTag(this);
+ if (item.type == ConferenceListItem.ConferenceItemType.Plus) {
+// mPhoto.setImageResource(R.drawable.v_add_member_voice_call);
+ } else {
+ // item.type == ConferenceListItem.ConferenceItemType.Participant
+ if (item.memberId == null || item.memberId.isEmpty()) {
+// mPhoto.setImageResource(R.drawable.participant_placeholder_grey);
+ } else {
+ // in Conference
+ setupInConference(item);
+ onViewAttachedToWindow();
+ }
+ }
+ }
+
+ public void onViewAttachedToWindow() {
+ initVideoCallRenderer();
+ setVideoRendererForTrack();
+ enableVideoForTrack(true);
+ }
+
+ public void onViewDetachedFromWindow() {
+ enableVideoForTrack(false);
+ //removeVideoRendererForTrack();
+ }
+
+ public void onViewRecycled() {
+ enableVideoForTrack(false);
+ }
+
+ @Synchronized
+ public void releaseVideoCallRrenderers() {
+ removeVideoRendererForTrack();
+ if (!mIsRenderersInitialized) return;
+ if (mVideoFeed != null) {
+ mVideoFeed.release();
+ }
+ mIsRenderersInitialized = false;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Internal Helpers
+ private void setupInConference(ConferenceListItem item) {
+ initVideoCallRenderer();
+ if (item.participantId == null || !item.isActive) {
+ // in Conference - but not joined yet
+ mMutedIndicator.setVisibility(View.GONE);
+// mPhoto.setImageResource(R.drawable.participant_placeholder_grey);
+ } else {
+ // already joined in Conference
+ drawIsMutedIfNeeded(item);
+ drawIsScfreenSharingIfNeeded(item);
+// drawIsActiveVideoIfNeeded(item);
+ drawIsFeedVideoIfNeeded(item.hasVideo);
+ if (mItem != null) {
+ if (mItem != null && mItem.isMe) {
+ mFeedFrameLayout.setBackgroundResource(R.drawable.video_feed_square_stroke_red);
+ mSwithCamera.setOnClickListener(null);
+ if (mListener != null) {
+ mSwithCamera.setOnClickListener(v -> mListener.onSwitchCameraClick(item));
+ mSwithCamera.setVisibility(View.VISIBLE);
+ }
+ } else if (mItem != null && mItem.isSpeaking) {
+ mFeedFrameLayout.setBackgroundResource(R.drawable.video_feed_square_stroke_green);
+ } else {
+ mFeedFrameLayout.setBackgroundColor(Color.TRANSPARENT);
+ }
+ } else {
+ mFeedFrameLayout.setBackgroundColor(Color.TRANSPARENT);
+ }
+ }
+ }
+
+ private void drawIsMutedIfNeeded(ConferenceListItem item) {
+ if(item.isMuted) {
+ mMutedIndicator.setVisibility(View.VISIBLE);
+ } else {
+ mMutedIndicator.setVisibility(View.GONE);
+// ImageUtils.loadAvatarImage(item.avatar, mPhoto);
+ }
+ }
+
+ private void drawIsActiveVideoIfNeeded(ConferenceListItem item) {
+ if(item.hasVideo) {
+ mActiveVideo.setChecked(true);
+ mActiveVideo.setVisibility(View.VISIBLE);
+ } else {
+ mActiveVideo.setVisibility(View.GONE);
+ }
+ }
+
+ private void drawIsScfreenSharingIfNeeded(ConferenceListItem item) {
+ if(item.hasScreen) {
+ mSS.setChecked(true);
+ mSS.setVisibility(View.VISIBLE);
+ } else {
+ mSS.setVisibility(View.GONE);
+ }
+ }
+
+ private void drawIsFeedVideoIfNeeded(boolean visible) {
+ if (visible) {
+ mVideoFeed.setVisibility(View.VISIBLE);
+ } else {
+ mVideoFeed.setVisibility(View.GONE);
+ }
+ refreshFeedVideo();
+ }
+
+ private void refreshFeedVideo() {
+ if (mVideoFeed != null) {
+ mVideoFeed.invalidate();
+ mVideoFeed.refreshDrawableState();
+ }
+ }
+
+ private void showHideItemView(boolean show) {
+ if (show) {
+ itemView.setVisibility(View.VISIBLE);
+ } else {
+ itemView.setVisibility(View.GONE);
+ }
+
+ }
+
+ @Synchronized
+ private void initVideoCallRenderer() {
+ if (mIsRenderersInitialized) return;
+ try {
+ mVideoFeed.init(createRootEglBase().getEglBaseContext(), null);
+ mVideoFeed.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
+ mVideoFeed.setEnableHardwareScaler(true);
+ if (mItem != null && mItem.isMe) {
+ mVideoFeed.setMirror(true);
+ }
+ mIsRenderersInitialized = true;
+ } catch (Exception ex) {
+ Timber.e(ex);
+ }
+ }
+
+ @Synchronized
+ private void setVideoRendererForTrack() {
+ if (!mIsRenderersInitialized) return;
+ if (mItem == null) return;
+ if (mItem.isTrackActive == 1) return;
+ String trackId = ConferenceVideoModule.getInstance().getTrackIdByParticipantId(mItem.participantId);
+ if (StringUtils.isNotEmpty(trackId) || mItem.isMe) {
+ mItem.isTrackActive = 1;
+ ConferenceVideoModule.getInstance().setVideoRendererForTrack(mVideoFeed, trackId, mItem.isMe);
+ }
+ }
+
+ @Synchronized
+ private void removeVideoRendererForTrack() {
+ if (!mIsRenderersInitialized) return;
+ if (mItem == null) return;
+ if (mItem.isTrackActive == 0) return;
+ String trackId = ConferenceVideoModule.getInstance().getTrackIdByParticipantId(mItem.participantId);
+ if (StringUtils.isNotEmpty(trackId) || mItem.isMe) {
+ ConferenceVideoModule.getInstance().setVideoRendererForTrack(null, trackId, mItem.isMe);
+ mItem.isTrackActive = 0;
+ }
+ }
+
+ @Synchronized
+ private void enableVideoForTrack(boolean enable) {
+ if (!mIsRenderersInitialized) return;
+ if (mItem == null) return;
+ if (StringUtils.isNotEmpty(mItem.participantId)) {
+ ConferenceVideoModule.getInstance().enableVideoForTrack(mItem.participantId, enable);
+ refreshFeedVideo();
+ }
+ }
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseAdapter.java b/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseAdapter.java
index 79e9e1fb861ec75cbfa8260792e577c84dd49071..fe33b3d069c80db66bad8104fff0acc37d53fa23 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseAdapter.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseAdapter.java
@@ -4,6 +4,8 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
+import com.nynja.mobile.communicator.ui.adapters.viewholders.conference.ConferenceVideoItemVh;
+
import java.util.ArrayList;
import java.util.List;
@@ -33,7 +35,7 @@ public abstract class BaseAdapter> extends RecyclerVie
}
@Override public void onBindViewHolder(Vh holder, int position) {
- holder.bind(getItem(position));
+ holder.bind(getItem(position), position);
}
@Override public int getItemCount() {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseVH.java b/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseVH.java
index 24db500d3b41078f460e388b26dbbda6f0cfa622..1023fe205e9b94deaa9aa9d604cd115dc7985828 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseVH.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/base/BaseVH.java
@@ -2,6 +2,7 @@ package com.nynja.mobile.communicator.ui.base;
import android.content.Context;
import android.support.annotation.LayoutRes;
+import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@@ -24,7 +25,8 @@ import butterknife.Unbinder;
public abstract class BaseVH extends RecyclerView.ViewHolder {
private Context mContext;
- private Unbinder mUnbinder;
+ protected Unbinder mUnbinder;
+ protected int mPosition = -1;
public BaseVH(ViewGroup parent, @LayoutRes int layoutId) {
this(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false));
@@ -33,10 +35,15 @@ public abstract class BaseVH extends RecyclerView.ViewHolder {
public BaseVH(View itemView) {
super(itemView);
mContext = itemView.getContext();
+ bind();
+ }
+
+ public void bind() {
mUnbinder = ButterKnife.bind(this, itemView);
}
- public void bind(I item) {
+ public void bind(I item, int position) {
+ mPosition = position;
if (mUnbinder != null) mUnbinder.unbind();
mUnbinder = ButterKnife.bind(this, itemView);
setData(item);
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/chats/ChatFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/chats/ChatFragment.java
index 6224cd2154fc1e89bdfeee9e2c69b4a1ae9c8cf3..cc4579d2c1408d6a609a6bfbef4478c599cd4c3a 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/chats/ChatFragment.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/chats/ChatFragment.java
@@ -414,7 +414,7 @@ public class ChatFragment extends BaseChatFragment implements ChatMvpView,
mPresenter.startAudioCall();
updateHeaderActionButtons();
});
- if (!mRoom.isGroupChat() && !mRoom.isChannel()) {
+ if (!mRoom.isChannel()) {
mNynjaHeaderView.showVideoCallButton();
mNynjaHeaderView.subscribeToVideoButtonEvent(v -> {
mPresenter.startVideoCall();
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/CallTapToSpeakFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/CallTapToSpeakFragment.java
index 9b81c77fa34882cb3bcfbe69067f99f1bb73a99d..d69f39b90e62c6d109d1c2d6afb63529340d6a79 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/CallTapToSpeakFragment.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/CallTapToSpeakFragment.java
@@ -20,7 +20,7 @@ import android.widget.Toast;
import com.arellomobile.mvp.presenter.InjectPresenter;
import com.nynja.mobile.communicator.R;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
import com.nynja.mobile.communicator.mvp.presenters.CallTapToSpeakPresenter;
import com.nynja.mobile.communicator.mvp.view.CallTapToSpeakView;
@@ -393,10 +393,10 @@ public class CallTapToSpeakFragment extends BaseFragment
if (isBluetoothHeadsetConnected()) {
onAudioRouteChange(audioRouteType);
} else {
- speaker.post(() -> {
+ if (speaker != null) {
speaker.setImageResource(R.drawable.speaker_selector);
speaker.setChecked(isSpeakerOn);
- });
+ };
}
speaker.setAutoToggle(!isBluetoothHeadsetConnected());
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceCallFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceCallFragment.java
index 0ccf2d283d1ba23f903a136d5117280416939c02..7122cc65bf9678aa41b01439eecc3349129269a6 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceCallFragment.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceCallFragment.java
@@ -7,6 +7,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
@@ -34,7 +35,7 @@ import android.widget.Toast;
import com.arellomobile.mvp.presenter.InjectPresenter;
import com.nynja.mobile.communicator.BuildConfig;
import com.nynja.mobile.communicator.R;
-import com.nynja.mobile.communicator.data.calls.ActiveCallBase;
+import com.nynja.mobile.communicator.data.conference.ActiveCallBase;
import com.nynja.mobile.communicator.data.models.nynjamodels.ContactModel;
import com.nynja.mobile.communicator.data.models.nynjamodels.RoomModel;
import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
@@ -43,8 +44,8 @@ import com.nynja.mobile.communicator.interfaces.OnConferenceItemClickListener;
import com.nynja.mobile.communicator.mvp.presenters.ConferenceCallPresenter;
import com.nynja.mobile.communicator.mvp.view.CallView;
import com.nynja.mobile.communicator.ui.activities.calls.CallActivity;
-import com.nynja.mobile.communicator.ui.adapters.ActiveCallPagerAdapter;
-import com.nynja.mobile.communicator.ui.adapters.ConferenceParticipantsAdapter;
+import com.nynja.mobile.communicator.ui.adapters.conference.ActiveCallPagerAdapter;
+import com.nynja.mobile.communicator.ui.adapters.conference.ConferenceParticipantsAdapter;
import com.nynja.mobile.communicator.ui.base.BaseFragment;
import com.nynja.mobile.communicator.ui.views.CheckableImageView;
import com.nynja.mobile.communicator.utils.ActionSheetDialog;
@@ -53,7 +54,6 @@ import com.nynja.mobile.communicator.utils.DialogFactory;
import com.nynja.mobile.communicator.utils.ImageUtils;
import com.nynja.mobile.communicator.utils.PermissionHelper;
import com.nynja.mobile.communicator.utils.StringUtils;
-import com.nynja.mobile.communicator.utils.Utils;
import org.webrtc.ContextUtils;
import org.webrtc.EglBase;
@@ -231,12 +231,12 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
@Override
public void onResume() {
super.onResume();
-// setRemoteVideoRenderer(mConferencePresenter.getActiveConference());
+// setVideoRendererForTrack(mConferencePresenter.getActiveConference());
// setLocalVideoRenderer(mConferencePresenter.getActiveConference());
// mConferencePresenter.resumeCallVideoCapturer();
isActive = true;
if (callActivity != null) {
- openShareScreenButton.setVisibility(callActivity.isScreenShareActive ? View.VISIBLE : View.GONE);
+ openShareScreenButton.setVisibility(callActivity.isScreenShareActive() ? View.VISIBLE : View.GONE);
}
if (mConferencePresenter.getActiveConference() != null) {
@@ -265,7 +265,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
// @Override
// public void onStart() {
// super.onStart();
-// setRemoteVideoRenderer(mConferencePresenter.getActiveConference(), "");
+// setVideoRendererForTrack(mConferencePresenter.getActiveConference(), "");
// setLocalVideoRenderer(mConferencePresenter.getActiveConference());
// mConferencePresenter.resumeCallVideoCapturer();
// isActive = true;
@@ -274,7 +274,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
@OnClick(R.id.open_share_screen)
void openShareScreen() {
if (callActivity != null) {
- callActivity.getPageIndicator().setCurrentItem(ActiveCallPagerAdapter.CallPages.ShareScreenFragment.ordinal());
+ callActivity.goToPage(ActiveCallPagerAdapter.CallPages.ShareScreenFragment);
+// callActivity.getPageIndicator().setCurrentItem(ActiveCallPagerAdapter.CallPages.ShareScreenFragment.ordinal());
}
}
@@ -294,25 +295,17 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
@OnClick(R.id.voice_call_active_video_layout)
//turn_video_on_off)
void turnVideoOnOff() {
- if (!videoOnOf.isEnabled()) return;
- if (!videoOnOf.isChecked()) {
- if (!mConferencePresenter.isCameraRunning()) {
- mRxPermissions.requestEachCombined(Manifest.permission.CAMERA)
- .subscribe(permission -> {
- if (permission.granted) {
- videoOnOf.setChecked(true);
- mConferencePresenter.startCameraCapture();
- } else if (!permission.shouldShowRequestPermissionRationale) {
- PermissionHelper.getInstance().showPermissionDialog(getActivity(),
- mConferencePresenter.getPermissionDialogListener(), Manifest.permission.CAMERA);
- }
- }, Timber::e);
+ if (mConferencePresenter.getActiveConference().isConference()) {
+ if (Consts.CLIENT_ALLOWED_VIDEO_CONFERENCE) {
+ onClickCameraButton();
+ } else {
+ DialogFactory.showAlertDialog(getContext(),
+ getString(R.string.call_start_video_conference_alert),
+ getString(R.string.signin_text_ok),
+ (dialog, which) -> dialog.dismiss());
}
- } else if (videoOnOf.isChecked() && mConferencePresenter.isCameraRunning()) {
- mConferencePresenter.stopCameraCapture();
- videoOnOf.setChecked(false);
} else {
- videoOnOf.setChecked(mConferencePresenter.isCameraRunning());
+ onClickCameraButton();
}
}
@@ -367,6 +360,31 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
}
}
+ private void onClickCameraButton() {
+ if (!videoOnOf.isEnabled()) return;
+ if (!videoOnOf.isChecked()) {
+ if (!mConferencePresenter.isCameraRunning()) {
+ mRxPermissions.requestEachCombined(Manifest.permission.CAMERA)
+ .subscribe(permission -> {
+ if (permission.granted) {
+ videoOnOf.setChecked(true);
+ mConferencePresenter.startCameraCapture();
+ } else if (!permission.shouldShowRequestPermissionRationale) {
+ PermissionHelper.getInstance().showPermissionDialog(getActivity(),
+ mConferencePresenter.getPermissionDialogListener(), Manifest.permission.CAMERA);
+ }
+ }, Timber::e);
+ } else {
+ videoOnOf.setChecked(mConferencePresenter.isCameraRunning());
+ }
+ } else if (videoOnOf.isChecked() && mConferencePresenter.isCameraRunning()) {
+ mConferencePresenter.stopCameraCapture();
+ videoOnOf.setChecked(false);
+ } else {
+ videoOnOf.setChecked(mConferencePresenter.isCameraRunning());
+ }
+ }
+
private void showAudioRoutActionSheet() {
if (getContext() != null) {
String bluetoothDeviceName = getString(R.string.bluetooth);
@@ -541,7 +559,9 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
mConfParticipantsAdapter.setIsModerator(activeConferenceCall.isModerator());
if (activeConferenceCall.isWaiting()) {
waitingConference(activeConferenceCall);
- } else if (activeConferenceCall.isVideoEnabled || activeConferenceCall.isOwnStreamActive) {
+ } else if ((activeConferenceCall.isVideoEnabled
+ || activeConferenceCall.mData.isOwnStreamActive)
+ && !activeConferenceCall.isConference()){
videoConference(activeConferenceCall);
//if (!activeConferenceCall.isSpeakerOn)
} else {
@@ -567,7 +587,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
@Override
public void onConferenceEnded() {
if (getActivity() == null || !isAdded()) return;
- getActivity().runOnUiThread(() -> getActivity().finish());
+ //getActivity().runOnUiThread(() -> getActivity().finish());
}
@Override
@@ -638,8 +658,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
activeUserNameSection.setVisibility(visible);
audioIncomeLayout.setVisibility(visible);
name.setVisibility(visible);
- callActivity.getPageIndicator().setVisibility(visible);
- if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) {
+ //callActivity.getPageIndicator().setVisibility(visible);
+ if (activeConferenceCall.isConference()) {
activeUserPhotoLayout.setVisibility(View.GONE);
conferenceParticipantsLayout.setVisibility(visible);
} else {
@@ -652,7 +672,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
protected void updateRendererUI(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall != null && activeConferenceCall.mConference != null) {
- if (activeConferenceCall.hasRemoteVideoTrack
+ if (activeConferenceCall.mData.hasRemoteVideoTrack
// && activeConferenceCall.mConference.hasRemoteVideo()
&& isActive) {
videoRemote.setVisibility(View.VISIBLE);
@@ -698,8 +718,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
name.setVisibility(visible);
conferenceParticipantsLayout.setVisibility(View.GONE);
activeUserNameSection.setVisibility(visible);
- callActivity.getPageIndicator().setVisibility(visible);
- if (activeConferenceCall != null && activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) {
+ //callActivity.getPageIndicator().setVisibility(visible);
+ if (activeConferenceCall != null && activeConferenceCall.isConference()) {
// TODO: for later Conference calls video support.
} else {
mConferencePresenter.loadUser(activeConferenceCall);
@@ -741,9 +761,16 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
}
}
- if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) {
+ if (activeConferenceCall.isConference()) {
mConferencePresenter.loadConferenceParticipants(activeConferenceCall);
addCallerLayout.setEnabled(activeConferenceCall.isModerator());
+ if (activeConferenceCall.mInitialStartCapturer &&
+ activeConferenceCall.mData.isOwnStreamActive) {
+ mHandler.postDelayed(() ->{
+ activeConferenceCall.mConference.startCamera();
+ }, Consts.DELAY_200);
+ activeConferenceCall.mInitialStartCapturer = false;
+ }
} else {
mConferencePresenter.loadUser(activeConferenceCall);
// TODO: update state after P2P upgrade to Group call support implemented !!!!
@@ -757,7 +784,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
if (callActivity != null && !activeConferenceCall.isCallInProgress()) {
callActivity.getViewPager().setPagingEnabled(false);
}
- mHandler.post(() -> initialConferenceStates(activeConferenceCall));
+ //mHandler.post(() -> initialConferenceStates(activeConferenceCall));
+ initialConferenceStates(activeConferenceCall);
////////////////////////////////////////////////////////////////////////////////////////////
// TEST TEST TEST
if (BuildConfig.DEBUG) {
@@ -783,6 +811,23 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
}
+ @Override public void onStartCapturerFailed(int msgResId, final boolean isCamera) {
+ getActivity().runOnUiThread(() -> DialogFactory.showAlert(getActivity(),
+ getString(msgResId),
+ getString(R.string.call_conference_alert_title),
+ new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialogInterface) {
+ if (isCamera) {
+ videoOnOf.setChecked(mConferencePresenter.isCameraRunning());
+ } else {
+ setScreenShareOn(false);
+ }
+ }
+ }));
+
+ }
+
@Override
public void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) {
if (getActivity() == null || !isAdded()) return;
@@ -891,7 +936,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
if (active) {
updateMicrophonState(activeConferenceCall.isMuted);
if (activeConferenceCall.isVideoEnabled) {
- if (activeConferenceCall.isOwnStreamActive) {
+ if (activeConferenceCall.mData.isOwnStreamActive) {
setLocalVideoRenderer(mConferencePresenter.getActiveConference());
mConferencePresenter.resumeCallVideoCapturer();
}
@@ -902,8 +947,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
muteMicHint.setVisibility(View.GONE);
mHandler.removeCallbacks(mShowMuteMicHintExpired);
if (activeConferenceCall.isVideoEnabled) {
- if (activeConferenceCall.isOwnStreamActive) {
- mConferencePresenter.pauseCallVideoCapturer();
+ if (activeConferenceCall.mData.isOwnStreamActive) {
+ //mConferencePresenter.pauseCallVideoCapturer();
removeLocalVideoRenderer(mConferencePresenter.getActiveConference());
}
removeRemoteVideoRenderer(mConferencePresenter.getActiveConference());
@@ -1128,7 +1173,8 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void requestPermissionIfNeeds(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall == null) return;
- boolean enableVideo = (activeConferenceCall.isOwnStreamActive && activeConferenceCall.mInitialStartCapturer);
+ boolean enableVideo = (activeConferenceCall.mData.isOwnStreamActive
+ && activeConferenceCall.mInitialStartCapturer);
ArrayList permissions = getPermissionsForCall(enableVideo);
String[] perms = new String[0];
@@ -1204,7 +1250,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void updateAddContact(ActiveConferenceCall activeConferenceCall) {
if (shouldCallActionsActive(activeConferenceCall)) {
- if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) {
+ if (activeConferenceCall.isConference()) {
addCallerLayout.setEnabled(activeConferenceCall.isModerator());
addContact.setEnabled(activeConferenceCall.isModerator());
} else {
@@ -1249,7 +1295,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void initVideoCallRrenderers(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall == null) return;
- if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return;
+ if (activeConferenceCall.isConference()) return;
if (!activeConferenceCall.isVideoEnabled) return;
try {
videoLocal.init(createRootEglBase().getEglBaseContext(), null);
@@ -1279,34 +1325,37 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void setRemoteVideoRenderer(ActiveConferenceCall activeConferenceCall) {
if (!mIsRenderersInitialized) return;
if (activeConferenceCall == null) return;
- //if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return;
+ if (activeConferenceCall.isConference()) return;
if (activeConferenceCall.mConference == null) return;
+ if (activeConferenceCall.mConference.isConference()) return;
if (!activeConferenceCall.isVideoEnabled) return;
- if (activeConferenceCall.hasRemoteVideoTrack) {
- activeConferenceCall.mConference.setRemoteVideoRenderer(videoRemote, activeConferenceCall.mRemoteVideoTrackId);
+ if (activeConferenceCall.mData.hasRemoteVideoTrack) {
+ activeConferenceCall.mConference.setRemoteVideoRenderer(videoRemote, activeConferenceCall.mData.mRemoteVideoTrackId);
}
}
private void removeRemoteVideoRenderer(ActiveConferenceCall activeConferenceCall, String trackId) {
if (activeConferenceCall == null) return;
- //if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return;
+ if (activeConferenceCall.isConference()) return;
if (activeConferenceCall.mConference == null) return;
+ if (activeConferenceCall.mConference.isConference()) return;
if (!activeConferenceCall.mConference.isRunning()) return;
if (!activeConferenceCall.isVideoEnabled) return;
- if (!activeConferenceCall.hasRemoteVideoTrack && StringUtils.isNotEmpty(trackId)) {
+ if (!activeConferenceCall.mData.hasRemoteVideoTrack && StringUtils.isNotEmpty(trackId)) {
activeConferenceCall.mConference.setRemoteVideoRenderer(null, trackId);
}
}
private void removeRemoteVideoRenderer(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall == null) return;
- removeRemoteVideoRenderer(activeConferenceCall, activeConferenceCall.mRemoteVideoTrackId);
+ if (activeConferenceCall.isConference()) return;
+ removeRemoteVideoRenderer(activeConferenceCall, activeConferenceCall.mData.mRemoteVideoTrackId);
}
private void setLocalVideoRenderer(ActiveConferenceCall activeConferenceCall) {
if (!mIsRenderersInitialized) return;
if (activeConferenceCall == null) return;
- //if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return;
+ if (activeConferenceCall.isConference()) return;
if (activeConferenceCall.mConference == null) return;
if (!activeConferenceCall.isVideoEnabled) return;
@@ -1315,7 +1364,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void removeLocalVideoRenderer(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall == null) return;
- //if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return;
+ if (activeConferenceCall.isConference()) return;
if (activeConferenceCall.mConference == null) return;
if (!activeConferenceCall.mConference.isRunning()) return;
if (!activeConferenceCall.isVideoEnabled) return;
@@ -1378,8 +1427,10 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
}
private void startConferenceCall() {
- mConferencePresenter.startConference();
- status.setText(R.string.call_connecting);
+ if (getActivity() != null) {
+ mConferencePresenter.startConference();
+ status.setText(R.string.call_connecting);
+ }
}
private void updateContactInfo() {
@@ -1392,8 +1443,9 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
private void setConferenceState(ActiveConferenceCall activeConferenceCall) {
if (activeConferenceCall.isWaiting()) {
waitingConference(activeConferenceCall);
- } else if (activeConferenceCall.isSwitchToAudio ||
- !activeConferenceCall.isVideoEnabled) {
+ } else if (activeConferenceCall.isSwitchToAudio
+ || !activeConferenceCall.isVideoEnabled
+ || activeConferenceCall.isConference()) {
audioConference(activeConferenceCall);
} else {
videoConference(activeConferenceCall);
@@ -1425,7 +1477,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
@Override
public void updateMicrophonState(boolean isMuted) {
if (audioMute != null && isActive) {
- audioMute.post(() -> audioMute.setChecked(isMuted));
+ audioMute.setChecked(isMuted);
}
}
@@ -1553,7 +1605,7 @@ public class ConferenceCallFragment extends BaseFragment implements CallView,
public void showFirstStopScreenSharingWarning(ActiveConferenceCall call){
if (call == null) return;
String message = getString(R.string.call_ask_to_stop_ss_first, call.getConferenceSSOwner());
- if (call.isConference() && call.hasRemoteVideoTrack) {
+ if (call.isConference() && call.mData.hasRemoteVideoTrack) {
message = getString(R.string.call_ask_to_stop_camera_first, call.getConferenceSSOwner());
}
final String msg = message;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceVideoFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceVideoFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..eaad10fb5cf52701faa81bdb171b3b389f0a756d
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ConferenceVideoFragment.java
@@ -0,0 +1,568 @@
+package com.nynja.mobile.communicator.ui.fragments.conference;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.DividerItemDecoration;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.LinearSnapHelper;
+import android.support.v7.widget.PagerSnapHelper;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.SnapHelper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import com.arellomobile.mvp.presenter.InjectPresenter;
+import com.nynja.mobile.communicator.R;
+import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule;
+import com.nynja.mobile.communicator.data.sdk.calls.ActiveConferenceCall;
+import com.nynja.mobile.communicator.data.sdk.calls.ConferenceListItem;
+import com.nynja.mobile.communicator.interfaces.OnConferenceItemClickListener;
+import com.nynja.mobile.communicator.interfaces.OnConferenceVideoFeedClickListener;
+import com.nynja.mobile.communicator.mvp.presenters.ConferenceVideoPresenter;
+import com.nynja.mobile.communicator.mvp.view.ConferenceVideoView;
+import com.nynja.mobile.communicator.ui.activities.calls.CallActivity;
+import com.nynja.mobile.communicator.ui.adapters.conference.ConferenceVideoAdapter;
+import com.nynja.mobile.communicator.ui.adapters.viewholders.conference.ConferenceVideoItemVh;
+import com.nynja.mobile.communicator.ui.base.BaseFragment;
+import com.nynja.mobile.communicator.utils.ActionSheetDialog;
+import com.nynja.mobile.communicator.utils.DialogFactory;
+import com.nynja.mobile.communicator.utils.StringUtils;
+
+import org.webrtc.ContextUtils;
+import org.webrtc.EglBase;
+
+import java.util.ArrayList;
+
+import butterknife.BindView;
+import timber.log.Timber;
+
+import static com.nynja.mobile.communicator.data.conference.ConferenceVideoModule.MAX_VIDEO_FEEDS_COLUIMN_SIZE;
+
+public class ConferenceVideoFragment extends BaseFragment implements ConferenceVideoView,
+ OnConferenceVideoFeedClickListener {
+
+ private static final int FRONT_CAMERA = 1;
+
+ // conference controls
+ @BindView(R.id.f_call_rv) RecyclerView mRecyclerView;
+
+ @InjectPresenter
+ ConferenceVideoPresenter mConferencePresenter;
+
+ private ConferenceVideoAdapter mConfParticipantsAdapter;
+ private boolean isActive;
+ private CallActivity callActivity;
+ private Handler mHandler;
+ GridLayoutManager mGridLayoutManager;
+ private ArrayList mMembersList = new ArrayList<>();
+ private boolean mTryToGoTooMyVideoFeed = false;
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mHandler = new Handler();
+ createRootEglBase();
+ ActiveConferenceCall activeConferenceCall = mConferencePresenter.getActiveConference();
+ ConferenceVideoModule.getInstance().setCurrentActiveCall(activeConferenceCall);
+ mConfParticipantsAdapter = new ConferenceVideoAdapter(mMembersList, this);
+ initUIRv();
+ }
+
+ @Override
+ public void onDestroyView() {
+ mRecyclerView.clearOnChildAttachStateChangeListeners();
+ mRecyclerView.clearOnScrollListeners();
+ mRecyclerView.setAdapter(null);
+ mConfParticipantsAdapter.releaseVideoCallRrenderers();
+ super.onDestroyView();
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_conference_video_call, container, false);
+ }
+
+ @Override
+ public void onDestroy() {
+ mConfParticipantsAdapter = null;
+ super.onDestroy();
+ ConferenceVideoModule.getInstance().setCurrentActiveCall(null);
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ isActive = true;
+ scrollToMyFeedPosition();
+ }
+
+ @Override
+ public void onPause() {
+ mConferencePresenter.pauseCallVideoCapturer();
+ isActive = false;
+ super.onPause();
+ }
+
+ @Override
+ public void onSwitchCameraClick(ConferenceListItem item) {
+ mConferencePresenter.switchCamera();
+ }
+
+ @Override
+ public void onItemClick(ConferenceListItem item, int position) {
+ Timber.d("On clicked position: %d contact: %s", position, item);
+ if (item == null) return;
+ // '+' item
+ }
+
+ @Override
+ public boolean onItemLongClick(ConferenceListItem item, int position) {
+ Timber.d("On long clicked position: %d contact: %s", position, item);
+ if (item == null) return false;
+ // '+' item
+ if (item.type == ConferenceListItem.ConferenceItemType.Plus) {
+ return false;
+ }
+
+ if (item.memberActions.size() == 0) return false;
+
+
+ ActionSheetDialog actionSheet = new ActionSheetDialog(getActivity());
+ actionSheet.isKeyPrevPressed = true;
+ actionSheet.setCancelButtonTitle(getString(R.string.cancel));
+ ArrayList itemsArray = new ArrayList<>();
+ for(int resId : item.memberActions) {
+ itemsArray.add(getString(resId));
+ }
+ actionSheet.addItems(itemsArray.toArray(new String[itemsArray.size()]));
+ actionSheet.setItemClickListener(
+ itemPosition -> {
+ if (item.isMe) {
+ onClickMyIconItem(item, itemPosition);
+ } else {
+ if (item.isFriend) {
+ onClickOthersFriendIconItem(item, itemPosition);
+ } else {
+ onClickOthersIconItem(item, itemPosition);
+ }
+ }
+ });
+ actionSheet.setCancelableOnTouchMenuOutside(true);
+// actionSheet.showMenu();
+ return true;
+ }
+
+ private void initUIRv() {
+ mRecyclerView.setNestedScrollingEnabled(false);
+ mGridLayoutManager = new GridLayoutManager(getActivity(),
+ MAX_VIDEO_FEEDS_COLUIMN_SIZE,
+ LinearLayoutManager.HORIZONTAL,
+ false);
+// mGridLayoutManager.setSpanCount(2);
+// mGridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
+// mGridLayoutManager.setReverseLayout(false);
+// mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+// @Override
+// public int getSpanSize(int position) {
+// return (int)ConferenceVideoModule.getInstance().getSpanSize(position);
+// }
+// });
+ mGridLayoutManager.setItemPrefetchEnabled(true);
+ mRecyclerView.setLayoutManager(mGridLayoutManager);
+ mRecyclerView.setHasFixedSize(true);
+ mRecyclerView.setAdapter(mConfParticipantsAdapter);
+ SnapHelper snapHelper = new LinearSnapHelper();
+ snapHelper.attachToRecyclerView(mRecyclerView);
+ mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL));
+ mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
+// mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
+// @Override
+// public void onChildViewAttachedToWindow(View view) {
+// ConferenceVideoItemVh holder = (ConferenceVideoItemVh)getChildViewHolderInternal(view);
+// if (holder != null) {
+// //holder.onViewAttachedToWindow();
+// }
+// }
+//
+// @Override
+// public void onChildViewDetachedFromWindow(View view) {
+// ConferenceVideoItemVh holder = (ConferenceVideoItemVh)getChildViewHolderInternal(view);
+// if (holder != null) {
+// //holder.onViewDetachedFromWindow();
+// }
+// }
+// });
+// mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+// @Override
+// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+// super.onScrolled(recyclerView, dx, dy);
+// }
+// });
+ }
+
+ private RecyclerView.ViewHolder getChildViewHolderInternal(View child) {
+ return child == null ? null : (RecyclerView.ViewHolder)(child.getTag());
+ }
+
+ protected void updateRendererUI(ActiveConferenceCall activeConferenceCall) {
+ if (mConfParticipantsAdapter != null) {
+ mConfParticipantsAdapter.notifyDataSetChanged();
+ }
+ }
+
+ protected void videoConference(ActiveConferenceCall activeConferenceCall) {
+ if (getActivity() == null || !isAdded()) return;
+ updateRendererUI(activeConferenceCall);
+ }
+
+ protected void initialConferenceStates(ActiveConferenceCall activeConferenceCall) {
+ setRemoteVideoRenderer(activeConferenceCall);
+ if (isActive) {
+ mConferencePresenter.resumeCallVideoCapturer();
+ }
+ }
+
+ @Override
+ public void initConferenceStates(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall.isConference()) {
+ mConferencePresenter.loadConferenceParticipants(activeConferenceCall);
+ }
+
+ // on first create time it is Active.
+ isActive = true;
+ mConfParticipantsAdapter.setIsModerator(activeConferenceCall.isModerator());
+ setConferenceState(activeConferenceCall);
+ mHandler.post(() -> initialConferenceStates(activeConferenceCall));
+ }
+
+ @Override
+ public void onConferenceMembersUpdate(ArrayList members) {
+ if (getActivity() == null || !isAdded()) return;
+ getActivity().runOnUiThread(() -> loadConferenceMembers(members));
+ }
+
+ @Override
+ public void onRemoteVideoTrackAdded(ActiveConferenceCall activeConferenceCall, String trackId) {
+ if (getActivity() == null || !isAdded()) return;
+ getActivity().runOnUiThread(() -> {
+ setRemoteVideoRenderer(activeConferenceCall);
+ setConferenceState(activeConferenceCall);
+ });
+ }
+
+ @Override
+ public void onRemoteVideoTrackRemoved(ActiveConferenceCall activeConferenceCall, String trackId) {
+ if (getActivity() == null || !isAdded()) return;
+ getActivity().runOnUiThread(() -> {
+ removeRemoteVideoRenderer(activeConferenceCall, trackId);
+ setConferenceState(activeConferenceCall);
+ });
+ }
+
+ @Override
+ public void onLocalVideoCapturerStarted(ActiveConferenceCall activeConferenceCall) {
+ if (getActivity() == null || !isAdded()) return;
+ mHandler.post(() -> {
+ setLocalVideoRenderer(activeConferenceCall);
+ setConferenceState(activeConferenceCall);
+ });
+ }
+
+ @Override
+ public void onLocalVideoCapturerStopped(ActiveConferenceCall activeConferenceCall) {
+ if (getActivity() == null || !isAdded()) return;
+ mHandler.post(() -> {
+ removeLocalVideoRenderer(activeConferenceCall);
+ setConferenceState(activeConferenceCall);
+ });
+ }
+
+ @Override
+ public void onScreenShareStateChanged(boolean isSharing) {
+ if (getActivity() == null || !isAdded()) return;
+ mHandler.post(() -> mConfParticipantsAdapter.notifyDataSetChanged());
+ }
+
+ @Override
+ public void onMicrophoneStateChanged(boolean isMuted) {
+ if (getActivity() == null || !isAdded()) return;
+ getActivity().runOnUiThread(() -> updateMicrophonState(isMuted));
+ }
+
+ @Override
+ public void onSpeakerStateChanged(boolean isSpeakerOn) {
+ if (getActivity() == null || !isAdded()) return;
+// getActivity().runOnUiThread(() -> updateSpeakerState(isSpeakerOn));
+ }
+
+ @Override
+ public void onActiveSpeakersUpdate(String activeSpeakers, ArrayList participantIds) {
+ if (getActivity() == null || !isAdded()) return;
+ getActivity().runOnUiThread(() -> {
+ if (getActivity() == null || !isAdded() || !isActive) return;
+ mConferencePresenter.updateActiveSpeakersState(participantIds);
+ });
+ }
+
+ @Override
+ public void showInternetError() {
+ if (isAdded()) {
+ Toast.makeText(getActivity(), R.string.error_no_internet_connection, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public boolean onBackPressed() {
+ return false;
+ }
+
+ public void setCallActivity(CallActivity activity) {
+ callActivity = activity;
+ }
+
+ public void setIsActive(boolean isActive) {
+ //this.isActive = isActive;
+ }
+
+ public void tryToGoTooMyVideoFeed() {
+ mTryToGoTooMyVideoFeed = true;
+ if (isActive) {
+ scrollToMyFeedPosition();
+ }
+ }
+
+ private void scrollToMyFeedPosition() {
+ if (mTryToGoTooMyVideoFeed) {
+ mTryToGoTooMyVideoFeed = false;
+ int myPos = mConfParticipantsAdapter.getoMyVideoFeedPostion();
+ if (myPos >= 0) mRecyclerView.scrollToPosition(myPos);
+ }
+ }
+
+ public void setActiveState(boolean active) {
+ ActiveConferenceCall activeConferenceCall = mConferencePresenter.getActiveConference();
+ isActive = active;
+ if (activeConferenceCall == null) return;
+ if (active) {
+ updateMicrophonState(activeConferenceCall.isMuted);
+ if (activeConferenceCall.isVideoEnabled) {
+ if (activeConferenceCall.mData.isOwnStreamActive) {
+ setLocalVideoRenderer(mConferencePresenter.getActiveConference());
+ mConferencePresenter.resumeCallVideoCapturer();
+ }
+ setRemoteVideoRenderer(mConferencePresenter.getActiveConference());
+ setConferenceState(activeConferenceCall);
+ }
+ scrollToMyFeedPosition();
+ } else {
+ if (activeConferenceCall.isVideoEnabled) {
+ if (activeConferenceCall.mData.isOwnStreamActive) {
+ mConferencePresenter.pauseCallVideoCapturer();
+ removeLocalVideoRenderer(mConferencePresenter.getActiveConference());
+ }
+ removeRemoteVideoRenderers(mConferencePresenter.getActiveConference());
+ setConferenceState(activeConferenceCall);
+ }
+ }
+ }
+
+ // Helpers
+ private void onClickMyIconItem(ConferenceListItem participant, Integer postion) {
+ if (postion >= participant.memberActions.size() || postion < 0) return;
+ switch (participant.memberActions.get(postion)) {
+// case R.string.call_my_profile:
+// mConferencePresenter.showProfile(participant);
+// break;
+// case R.string.call_leave_call):
+// leaveCall();
+// break;
+
+ default:
+ break;
+ }
+ }
+
+ private void onClickOthersFriendIconItem(ConferenceListItem participant, Integer postion) {
+ if (postion >= participant.memberActions.size() || postion < 0) return;
+ switch (participant.memberActions.get(postion)) {
+ case R.string.call_view_profile:
+ mConferencePresenter.showProfile(participant);
+ break;
+ case R.string.send_a_message:
+ mConferencePresenter.openChatWithParticipant(participant.phoneId);
+ break;
+
+ case R.string.call_remove_from_call:
+ showRemoveParticipantConfirmation(participant);
+ break;
+
+ case R.string.call_back:
+ mConferencePresenter.callBackPerson(participant);
+ break;
+
+ case R.string.call_unmute:
+ unMuteParticipant(participant);
+ break;
+ case R.string.call_mute:
+ muteParticipant(participant);
+ break;
+
+ case R.string.call_item_menu_stop_ss:
+ stopParticipantSS(participant);
+ break;
+
+ case R.string.call_item_menu_stop_video:
+ stopParticipantVideo(participant);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ private void onClickOthersIconItem(ConferenceListItem participant, Integer postion) {
+ if (postion >= participant.memberActions.size() || postion < 0) return;
+ switch (participant.memberActions.get(postion)) {
+ case R.string.call_view_profile:
+ mConferencePresenter.showProfile(participant);
+ break;
+
+ case R.string.call_remove_from_call:
+ showRemoveParticipantConfirmation(participant);
+ break;
+
+ case R.string.call_unmute:
+ unMuteParticipant(participant);
+ break;
+ case R.string.call_mute:
+ muteParticipant(participant);
+ break;
+ case R.string.call_item_menu_stop_ss:
+ stopParticipantSS(participant);
+ break;
+ case R.string.call_item_menu_stop_video:
+ stopParticipantVideo(participant);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ private void showRemoveParticipantConfirmation(ConferenceListItem participant) {
+ DialogFactory.createYesNoDialog(getActivity(), R.string.call_remove_participant_confirm,
+ (dialog, which) -> mConferencePresenter.removeFromCall(participant),
+ (dialog, which) -> dialog.dismiss()).show();
+ }
+
+ private void muteParticipant(ConferenceListItem item) {
+ mConferencePresenter.muteParticipant(item);
+ }
+
+ private void unMuteParticipant(ConferenceListItem item) {
+ mConferencePresenter.unMuteParticipant(item.participantId);
+ }
+
+ private void stopParticipantSS(ConferenceListItem item) {
+ mConferencePresenter.stopParticipantSS(item);
+ }
+
+ private void stopParticipantVideo(ConferenceListItem item) {
+ mConferencePresenter.stopParticipantVideo(item);
+ }
+
+
+ private void showActionSheetDialog(ActionSheetDialog.MenuItemClickListener listener, String... items) {
+ ActionSheetDialog actionSheet = new ActionSheetDialog(getActivity());
+ actionSheet.setCancelButtonTitle(getString(R.string.cancel));
+ actionSheet.addItems(items);
+ actionSheet.setItemClickListener(listener);
+ actionSheet.setCancelableOnTouchMenuOutside(true);
+ actionSheet.showMenu();
+ }
+
+ private EglBase createRootEglBase() {
+ return ContextUtils.createRootEglBase();
+ }
+
+ private void loadConferenceMembers(ArrayList members) {
+ mConfParticipantsAdapter.setItems(members);
+ }
+
+ private void setRemoteVideoRenderer(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall == null) return;
+ if (!activeConferenceCall.isConference()) return;
+ if (activeConferenceCall.mConference == null) return;
+ if (!activeConferenceCall.mConference.isConference()) return;
+ if (!activeConferenceCall.isVideoEnabled) return;
+
+ mConferencePresenter.loadConferenceParticipants(activeConferenceCall);
+ }
+
+ private void removeRemoteVideoRenderer(ActiveConferenceCall activeConferenceCall, String trackId) {
+ if (activeConferenceCall == null) return;
+ if (activeConferenceCall.mConference == null) return;
+ if (!activeConferenceCall.mConference.isConference()) return;
+ if (!activeConferenceCall.mConference.isRunning()) return;
+ if (!activeConferenceCall.isVideoEnabled) return;
+
+ if (StringUtils.isNotEmpty(trackId)) {
+ ConferenceVideoModule.getInstance().setVideoRendererForTrack(null, trackId, false);
+ }
+
+ mConfParticipantsAdapter.notifyDataSetChanged();
+ }
+
+ private void removeRemoteVideoRenderers(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall == null) return;
+ ArrayList members = mConferencePresenter.getConferenceVideoMembers(activeConferenceCall);
+ for (ConferenceListItem item : members) {
+ String trackId = ConferenceVideoModule.getInstance().getTrackIdByParticipantId(item.participantId);
+ if (StringUtils.isNotEmpty(trackId) || item.isMe) {
+ ConferenceVideoModule.getInstance().setVideoRendererForTrack(null, trackId, item.isMe);
+ }
+ }
+ }
+
+ private void setLocalVideoRenderer(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall == null) return;
+ if (activeConferenceCall.mConference == null) return;
+ if (!activeConferenceCall.isVideoEnabled) return;
+
+ mConferencePresenter.loadConferenceParticipants(activeConferenceCall);
+ }
+
+ private void removeLocalVideoRenderer(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall == null) return;
+ if (activeConferenceCall.mConference == null) return;
+ if (!activeConferenceCall.mConference.isRunning()) return;
+ if (!activeConferenceCall.isVideoEnabled) return;
+
+ mConferencePresenter.loadConferenceParticipants(activeConferenceCall);
+ }
+
+ private void setConferenceState(ActiveConferenceCall activeConferenceCall) {
+ if (activeConferenceCall.isConference()) {
+ videoConference(activeConferenceCall);
+ }
+ }
+
+ @Override
+ public void updateMicrophonState(boolean isMuted) {
+ }
+
+ @Override
+ public void closenConference() {
+ if (getActivity() == null) return;
+ getActivity().finish();
+ }
+
+
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ScreenShareFragment.kt b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ScreenShareFragment.kt
index 92f0d45b9fed0af6da353c127a663cd6924033df..8abd3f17792699a2d5f87b9d69e9616b02ef7153 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ScreenShareFragment.kt
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/conference/ScreenShareFragment.kt
@@ -68,7 +68,13 @@ class ScreenShareFragment : BaseFragment(), ScreenShareView {
mScreenShareRemote?.layoutParams = layoutParams
mZoomableFrameLayout.reset()
mFrameLayout?.addView(mContainer)
- remoteScreenShareState(mPresenter.activeConference.hasRemoteScreenShareTrack)
+ remoteScreenShareState(mPresenter.activeConference.mData.hasRemoteScreenShareTrack)
+ }
+
+ override fun onDestroyView() {
+ removeRemoteScreenShareRenderer(mPresenter.getActiveConference())
+ mScreenShareRemote?.release()
+ super.onDestroyView()
}
override fun onConfigurationChanged(newConfig: Configuration) {
@@ -87,7 +93,7 @@ class ScreenShareFragment : BaseFragment(), ScreenShareView {
}
override fun initConferenceStates(activeConferenceCall: ActiveConferenceCall) {
- if (activeConferenceCall.hasRemoteScreenShareTrack) {
+ if (activeConferenceCall.mData.hasRemoteScreenShareTrack) {
setRemoteScreenShareRenderer(activeConferenceCall)
} else {
removeRemoteScreenShareRenderer(activeConferenceCall)
@@ -121,7 +127,7 @@ class ScreenShareFragment : BaseFragment(), ScreenShareView {
}
private fun removeRemoteScreenShareRenderer(activeConferenceCall: ActiveConferenceCall?) {
- removeRemoteScreenShareRenderer(activeConferenceCall, activeConferenceCall?.mRemoteSSTrackId)
+ removeRemoteScreenShareRenderer(activeConferenceCall, activeConferenceCall?.mData?.mRemoteSSTrackId)
}
private fun remoteScreenShareState(visible: Boolean) {
@@ -148,10 +154,10 @@ class ScreenShareFragment : BaseFragment(), ScreenShareView {
if (activeConferenceCall == null) return
//if (activeConferenceCall.mCallType == ActiveCallBase.CallType.ConferenceCall) return
if (activeConferenceCall.mConference == null) return
- if (!activeConferenceCall.hasRemoteScreenShareTrack) return
+ if (!activeConferenceCall.mData.hasRemoteScreenShareTrack) return
- if (StringUtils.isNotEmpty(activeConferenceCall.mRemoteSSTrackId)) {
- setRemoteScreenShareRenderer(activeConferenceCall, activeConferenceCall.mRemoteSSTrackId)
+ if (StringUtils.isNotEmpty(activeConferenceCall.mData.mRemoteSSTrackId)) {
+ setRemoteScreenShareRenderer(activeConferenceCall, activeConferenceCall.mData.mRemoteSSTrackId)
}
remoteScreenShareState(activeConferenceCall, true)
@@ -176,7 +182,7 @@ class ScreenShareFragment : BaseFragment(), ScreenShareView {
mScreenShareRemote?.setEnableHardwareScaler(true)
mScreenShareRemote?.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT, RendererCommon.ScalingType.SCALE_ASPECT_FIT)
// duplicates to Presenter::attachView(view: ScreenShareView?) -> setRemoteScreenShareRenderer()...
- //if (activeConferenceCall.hasRemoteScreenShareTrack) {
+ //if (activeConferenceCall.mData.hasRemoteScreenShareTrack) {
// setRemoteScreenShareRenderer(activeConferenceCall)
//}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/InfoFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/InfoFragment.java
index ee91283fd6d0e205d16199f480af1dfe09f5d6dc..5e2db5dfa237dce471a30b7336bdad0314cc940f 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/InfoFragment.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/InfoFragment.java
@@ -2,9 +2,13 @@ package com.nynja.mobile.communicator.ui.fragments.signin;
import android.Manifest;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.ArrayRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
+import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -36,6 +40,10 @@ import com.nynja.mobile.communicator.utils.SpannableUtils;
import com.nynja.mobile.communicator.utils.StringUtils;
import com.nynja.mobile.communicator.utils.Utils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import butterknife.BindView;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
@@ -85,8 +93,9 @@ public class InfoFragment extends BaseFragment implements InfoView, OnBackPresse
initSpannableTerms();
if (getArguments() != null) {
- if (getArguments().getParcelable(KEY_SOCIAL_DATA) != null) {
- ISocialLoginDetails socialLoginDetails = getArguments().getParcelable(KEY_SOCIAL_DATA);
+ ISocialLoginDetails socialLoginDetails = getArguments().getParcelable(KEY_SOCIAL_DATA);
+ boolean isSocial = (socialLoginDetails != null && socialLoginDetails.isSocial());
+ if (isSocial) {
if (StringUtils.isNotEmpty(socialLoginDetails.getFirstName())) {
mFirstNameEt.setText(socialLoginDetails.getFirstName());
}
@@ -97,8 +106,12 @@ public class InfoFragment extends BaseFragment implements InfoView, OnBackPresse
mPresenter.presetAvatar(socialLoginDetails.getAvatar());
}
}
+ boolean isPending = (socialLoginDetails != null && socialLoginDetails.isPending());
+ if (isPending) {
+ generateContextDialog();
+ }
- boolean hide = (getArguments().containsKey(KEY_SOCIAL_DATA) || !mPresenter.isLoggedIn());
+ boolean hide = (isSocial || !mPresenter.isLoggedIn());
mAvatarIv.setVisibility(hide ? View.GONE : View.VISIBLE);
mPresenter.setSignedInUserFlag(!hide);
}
@@ -138,6 +151,30 @@ public class InfoFragment extends BaseFragment implements InfoView, OnBackPresse
}
+ private void generateContextDialog() {
+ new Handler(Looper.getMainLooper()).post(() ->{
+ String title = getString(R.string.new_account_alert_message_body) ;
+ DialogFactory.showModalPurchaseStoreItem(getActivity(), getString(R.string.new_account_alert_title),
+ title,
+ getString(R.string.new_account_alert_action_create_new), getString(R.string.call_no_dont_ask_me_again),
+ (dialogInterface, i) -> {
+ // positive - continue pending account creation
+ onResumed();
+ },
+ (dialogInterface, i) -> {
+ //negative - go back to login with different accouint
+ mPresenter.backToLogin();
+ });
+ });
+ }
+
+ private void onResumed() {
+ if (getActivity() instanceof BaseActivity) {
+ ((BaseActivity) getActivity()).setOnBackPressedListener(this);
+ Utils.showKeyboard(getActivity(), mUserNameEt);
+ }
+ }
+
private void validateUserData(InfoPresenter.UserData userData) {
mPresenter.validateData(userData, mTermsOfUse.isChecked());
}
@@ -339,10 +376,6 @@ public class InfoFragment extends BaseFragment implements InfoView, OnBackPresse
@Override public void onResume() {
super.onResume();
- if (getActivity() instanceof BaseActivity) {
- ((BaseActivity) getActivity()).setOnBackPressedListener(this);
- Utils.showKeyboard(getActivity(), mUserNameEt);
- }
}
@Override public void onPause() {
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/LoginFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/LoginFragment.java
index e177ed9487e3a19a3fdaa8964b12a3da71b95ab1..1e424f50014605dd891ce6af800981badcf18355 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/LoginFragment.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/signin/LoginFragment.java
@@ -29,6 +29,7 @@ import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -88,12 +89,15 @@ public class LoginFragment extends BaseFragment implements LoginView, OnPhoneEdi
@BindView(R.id.f_iphone_root) ConstraintLayout mCoordinatorLayout;
@BindView(R.id.phone_ll) LinearLayout mPhoneLayout;
@BindView(R.id.email_ll) LinearLayout mEmailLayout;
- @BindView(R.id.login_change_type_iv) ImageView mChangeTypeIv;
- @BindView(R.id.login_change_type_tv) TextView mChangeTypeTv;
@BindView(R.id.email_et) EditText mEmailEt;
@BindView(R.id.email_til) TextInputLayout mEmailTil;
@BindView(R.id.f_iphone_btn_next) AppCompatButton mNextBtn;
+ @BindView(R.id.login_choice_auth_layout) ConstraintLayout mAuthStep1Layout;
+ @BindView(R.id.login_auth_step_layout) ConstraintLayout mAuthStep2Layout;
+ @BindView(R.id.login_by_email) RelativeLayout mLoginByEmailButton;
+ @BindView(R.id.login_by_phone) RelativeLayout mLoginByPhoneButton;
+
@InjectPresenter LoginPresenter mPresenter;
private Handler mHandler;
private boolean isUpdateVersionVisible;
@@ -140,7 +144,7 @@ public class LoginFragment extends BaseFragment implements LoginView, OnPhoneEdi
phoneEdt.setTextObservers();
setTextWatchers();
//initSpannableTerms();
- requestHint();
+ //requestHint();
}
private void setTextWatchers() {
@@ -241,29 +245,63 @@ public class LoginFragment extends BaseFragment implements LoginView, OnPhoneEdi
mPresenter.showCountryPickerFragment();
}
- @OnClick(R.id.login_change_type_btn) void onClickChangeLoginType() {
- if (mEmailLayout.getVisibility() == View.VISIBLE) {
- showPhoneLogin();
- } else {
+ @OnClick(R.id.login_choice_by_email) void onClickLoginChoiceEmail() {
+ if (mAuthStep1Layout.getVisibility() == View.VISIBLE) {
+ onClickLoginChoiceByEmail();
+ }
+ }
+
+ @OnClick(R.id.login_choice_by_phone) void onClickLoginChoicePhone() {
+ if (mAuthStep1Layout.getVisibility() == View.VISIBLE) {
+ onClickLoginChoiceByPhone();
+ }
+ }
+
+ @OnClick(R.id.login_by_email) void onClickLoginEmail() {
+ if (mEmailLayout.getVisibility() != View.VISIBLE) {
showEmailLogin();
}
}
+ @OnClick(R.id.login_by_phone) void onClickLoginPhone() {
+ if (mPhoneLayout.getVisibility() != View.VISIBLE) {
+ showPhoneLogin();
+ }
+ }
+
private void showPhoneLogin() {
mEmailLayout.setVisibility(View.INVISIBLE);
mPhoneLayout.setVisibility(View.VISIBLE);
- mChangeTypeIv.setImageResource(R.drawable.icons_general_ic_email);
- mChangeTypeTv.setText(R.string.signin_email);
+ mLoginByPhoneButton.setVisibility(View.GONE);
+ mLoginByEmailButton.setVisibility(View.VISIBLE);
mNextBtn.setEnabled(validatePhone());
mPresenter.requestPhoneHint();
}
+ private void onClickLoginChoiceByEmail() {
+ if (mAuthStep1Layout.getVisibility() == View.VISIBLE) {
+ showEmailLogin();
+ mAuthStep1Layout.setVisibility(View.INVISIBLE);
+ mAuthStep2Layout.setVisibility(View.VISIBLE);
+ requestHint();
+ }
+ }
+
+ private void onClickLoginChoiceByPhone() {
+ if (mAuthStep1Layout.getVisibility() == View.VISIBLE) {
+ showPhoneLogin();
+ mAuthStep1Layout.setVisibility(View.INVISIBLE);
+ mAuthStep2Layout.setVisibility(View.VISIBLE);
+ requestHint();
+ }
+ }
+
private void showEmailLogin() {
mPhoneLayout.setVisibility(View.INVISIBLE);
mEmailLayout.setVisibility(View.VISIBLE);
- mChangeTypeIv.setImageResource(R.drawable.icons_general_ic_phone);
- mChangeTypeTv.setText(R.string.signin_phone);
+ mLoginByEmailButton.setVisibility(View.GONE);
+ mLoginByPhoneButton.setVisibility(View.VISIBLE);
if (mEmailEt.getText().toString().isEmpty()) {
mEmailTil.setError(null);
mNextBtn.setEnabled(false);
@@ -273,11 +311,11 @@ public class LoginFragment extends BaseFragment implements LoginView, OnPhoneEdi
mPresenter.requestEmailHint();
}
- @OnClick(R.id.login_fb_btn) void onClickLoginFB() {
+ @OnClick({R.id.login_fb_btn, R.id.login_choice_fb_btn}) void onClickLoginFB() {
mPresenter.loginBySocial(new FBSocialLoginImpl());
}
- @OnClick(R.id.login_google_btn) void onClickLoginGoogle() {
+ @OnClick({R.id.login_google_btn, R.id.login_choice_google_btn}) void onClickLoginGoogle() {
mPresenter.loginBySocial(new GoogleLoginImpl());
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePageIndicator.java b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePageIndicator.java
index 1de72cc6a37de47c4579bcaf37648d3e972c7bf4..e3e48346feba2f0fe68c06e4252fd7f8f9402ff4 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePageIndicator.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePageIndicator.java
@@ -374,6 +374,10 @@ public class CirclePageIndicator extends View implements ViewPager.OnPageChangeL
invalidate();
}
+ public int getCurrentItem() {
+ return mCurrentPage;
+ }
+
public void notifyDataSetChanged() {
invalidate();
}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePagerIndicatorDecoration.java b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePagerIndicatorDecoration.java
new file mode 100644
index 0000000000000000000000000000000000000000..898677c168a01a441789bfca58e738252a37ee38
--- /dev/null
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CirclePagerIndicatorDecoration.java
@@ -0,0 +1,118 @@
+package com.nynja.mobile.communicator.ui.views;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.support.annotation.ColorInt;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Created by Ergyun Syuleyman on 04/07/20.
+ */
+public class CirclePagerIndicatorDecoration extends RecyclerView.ItemDecoration {
+
+ private final int indicatorHeight;
+ private final int indicatorItemPadding;
+ private final int radius;
+
+ private final Paint inactivePaint = new Paint();
+ private final Paint activePaint = new Paint();
+
+ public CirclePagerIndicatorDecoration(int radius, int padding, int indicatorHeight,
+ int colorInactive, int colorActive) {
+ float strokeWidth = Resources.getSystem().getDisplayMetrics().density * 2;
+ this.radius = radius;
+ inactivePaint.setStrokeCap(Paint.Cap.ROUND);
+ inactivePaint.setStrokeWidth(strokeWidth);
+ inactivePaint.setStyle(Paint.Style.STROKE);
+ inactivePaint.setAntiAlias(true);
+ inactivePaint.setColor(colorInactive);
+
+ activePaint.setStrokeCap(Paint.Cap.ROUND);
+ activePaint.setStrokeWidth(strokeWidth);
+ activePaint.setStyle(Paint.Style.FILL);
+ activePaint.setAntiAlias(true);
+ activePaint.setColor(colorActive);
+
+ this.indicatorItemPadding = padding;
+ this.indicatorHeight = indicatorHeight;
+ }
+
+ @Override
+ public void onDrawOver(@NotNull Canvas c, @NotNull RecyclerView parent, @NotNull RecyclerView.State state) {
+ super.onDrawOver(c, parent, state);
+
+ final RecyclerView.Adapter adapter = parent.getAdapter();
+
+ if (adapter == null) {
+ return;
+ }
+
+ int itemCount = adapter.getItemCount();
+
+ // center horizontally, calculate width and subtract half from center
+ float totalLength = this.radius * 2 * itemCount;
+ float paddingBetweenItems = Math.max(0, itemCount - 1) * indicatorItemPadding;
+ float indicatorTotalWidth = totalLength + paddingBetweenItems;
+ float indicatorStartX = (parent.getWidth() - indicatorTotalWidth) / 2f;
+
+ // center vertically in the allotted space
+ float indicatorPosY = parent.getHeight() - indicatorHeight / 2f;
+
+ drawInactiveDots(c, indicatorStartX, indicatorPosY, itemCount);
+
+ final int activePosition;
+
+ if (parent.getLayoutManager() instanceof GridLayoutManager) {
+ activePosition = ((GridLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
+ } else if (parent.getLayoutManager() instanceof LinearLayoutManager) {
+ activePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
+ } else {
+ // not supported layout manager
+ return;
+ }
+
+ if (activePosition == RecyclerView.NO_POSITION) {
+ return;
+ }
+
+ // find offset of active page if the user is scrolling
+ final View activeChild = parent.getLayoutManager().findViewByPosition(activePosition);
+ if (activeChild == null) {
+ return;
+ }
+
+ drawActiveDot(c, indicatorStartX, indicatorPosY, activePosition);
+ }
+
+ private void drawInactiveDots(Canvas c, float indicatorStartX, float indicatorPosY, int itemCount) {
+ // width of item indicator including padding
+ final float itemWidth = this.radius * 2 + indicatorItemPadding;
+
+ float start = indicatorStartX + radius;
+ for (int i = 0; i < itemCount; i++) {
+ c.drawCircle(start, indicatorPosY, radius, inactivePaint);
+ start += itemWidth;
+ }
+ }
+
+ private void drawActiveDot(Canvas c, float indicatorStartX, float indicatorPosY,
+ int highlightPosition) {
+ // width of item indicator including padding
+ final float itemWidth = this.radius * 2 + indicatorItemPadding;
+ float highlightStart = indicatorStartX + radius + itemWidth * highlightPosition;
+ c.drawCircle(highlightStart, indicatorPosY, radius, activePaint);
+ }
+
+ @Override
+ public void getItemOffsets(@NotNull Rect outRect, @NotNull View view, @NotNull RecyclerView parent, @NotNull RecyclerView.State state) {
+ super.getItemOffsets(outRect, view, parent, state);
+ outRect.bottom = indicatorHeight;
+ }
+}
diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/wheel/entity/Factory.java b/app/src/main/java/com/nynja/mobile/communicator/ui/wheel/entity/Factory.java
index 6d865403a9789e32463ef978f935de7988505d70..047e26a48a2dd645c5f0dd78632dcb7e05df68cc 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/ui/wheel/entity/Factory.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/ui/wheel/entity/Factory.java
@@ -541,13 +541,13 @@ public class Factory {
.enableBgColor(isSubItems ? R.color.wheel_unselected_corner_bg : R.color.intercom_full_transparent_full_black)
.build());
- // add(SimpleWheelItem.newBuilder()
- // .wheelAction(HomeActions.VideoCallAction)
- // .text(R.string.video_call)
- // .icons(R.drawable.ic_new_video_call_vector, 0)
- // .enableBgColor(isSubItems ? R.color.wheel_unselected_corner_bg : R.color.intercom_full_transparent_full_black)
- // .build());
- //
+ add(SimpleWheelItem.newBuilder()
+ .wheelAction(HomeActions.VideoCallAction)
+ .text(R.string.video_call)
+ .icons(R.drawable.ic_new_video_call_vector, 0)
+ .enableBgColor(isSubItems ? R.color.wheel_unselected_corner_bg : R.color.intercom_full_transparent_full_black)
+ .build());
+
add(SimpleWheelItem.newBuilder()
.wheelAction(HomeActions.CallHistory)
diff --git a/app/src/main/java/com/nynja/mobile/communicator/utils/Consts.java b/app/src/main/java/com/nynja/mobile/communicator/utils/Consts.java
index 3a4cf23d080a556492a4b2ab6f6329a4c1950a5b..8dc5ca8301d53dedbd0225f4114024480a846709 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/utils/Consts.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/utils/Consts.java
@@ -116,13 +116,19 @@ public interface Consts {
// Incoming call showing as a popup Notification
boolean SHOW_INCOMING_CALLS_AS_POPUP_NOTIFICATIONS = false;
- // Samsung IAP
+ // Samsung
+ // IAP
boolean CLIENT_SIDE_MODERATOR_END_CONFERENCE = true;//BuildConfig.FLAVOR.toLowerCase().contentEquals("samsung");
boolean ENABLE_SAMSUNG_IAP_TEST_MODE = false;
long SHOW_TRIAL_PEROIOD_MSG_AT_START = 30; // in seconds
long SHOW_TRIAL_PEROIOD_VALUE_5 = 5; // in minutes
long SHOW_TRIAL_PEROIOD_VALUE_10 = 10; // in minutes
int SHOW_TRIAL_PEROIOD_END_TIME = 40; // in minutes
+ // Video conference
+ //boolean CLIENT_ALLOWED_VIDEO_CONFERENCE = (BuildConfig.FLAVOR.toLowerCase().contentEquals("samsung")
+ // || BuildConfig.FLAVOR.toLowerCase().contentEquals("samsungdev")
+ // || BuildConfig.FLAVOR.toLowerCase().contentEquals("samsungpreprod"));
+ boolean CLIENT_ALLOWED_VIDEO_CONFERENCE = (BuildConfig.APPLICATION_ID.toLowerCase().contentEquals("com.nynja.mobile.communicator.superapp"));
// Default Max length restriction of group chat (room) name - on creation
int MAX_GROUP_NAME_SIZE_RESTRICTION = 32;
diff --git a/app/src/main/java/com/nynja/mobile/communicator/utils/DialogFactory.java b/app/src/main/java/com/nynja/mobile/communicator/utils/DialogFactory.java
index 16df41edf1b13b701cc0d5a25fd9ea9bae812f74..ea23d5bb11e175f9983d746e6bf5c40a0882ac16 100644
--- a/app/src/main/java/com/nynja/mobile/communicator/utils/DialogFactory.java
+++ b/app/src/main/java/com/nynja/mobile/communicator/utils/DialogFactory.java
@@ -234,7 +234,7 @@ public class DialogFactory {
return dialogBuilder.create();
}
- public static AlertDialog createContextPopupDialog(Activity activity, int title,
+ public static AlertDialog createContextPopupDialog(Activity activity,
@ArrayRes List itemsRes,
DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity,
@@ -245,9 +245,6 @@ public class DialogFactory {
}
dialogBuilder.setAdapter(arrayAdapter, onClickListener);
AlertDialog dialog = dialogBuilder.create();
- if (title > 0) {
- dialog.setTitle(title);
- }
ListView listView = dialog.getListView();
listView.setDivider(new ColorDrawable(ContextCompat.getColor(activity, R.color.lite_grey)));
listView.setDividerHeight(1);
@@ -256,6 +253,50 @@ public class DialogFactory {
return dialog;
}
+ public static AlertDialog createContextPopupDialog(Activity activity, int title,
+ @ArrayRes List itemsRes,
+ DialogInterface.OnClickListener onClickListener) {
+ AlertDialog dialog = createContextPopupDialog(activity, itemsRes, onClickListener);
+ if (title > 0) {
+ dialog.setTitle(title);
+ }
+ return dialog;
+ }
+
+ public static AlertDialog createContextPopupDialog(Activity activity, String title,
+ @ArrayRes List itemsRes,
+ DialogInterface.OnClickListener onClickListener) {
+ AlertDialog dialog = createContextPopupDialog(activity, itemsRes, onClickListener);
+ if (StringUtils.isNotEmpty(title)) {
+ dialog.setTitle(title);
+ }
+ return dialog;
+ }
+
+ public static AlertDialog createContextPopupDialog(Activity activity,
+ int title,
+ int message,
+ @ArrayRes List itemsRes,
+ DialogInterface.OnClickListener onClickListener) {
+ AlertDialog dialog = createContextPopupDialog(activity, title, itemsRes, onClickListener);
+ if (message > 0) {
+ dialog.setMessage(activity.getString(message));
+ }
+ return dialog;
+ }
+
+ public static AlertDialog createContextPopupDialog(Activity activity,
+ int title,
+ String message,
+ @ArrayRes List itemsRes,
+ DialogInterface.OnClickListener onClickListener) {
+ AlertDialog dialog = createContextPopupDialog(activity, title, itemsRes, onClickListener);
+ if (StringUtils.isNotEmpty(message)) {
+ dialog.setMessage(message);
+ }
+ return dialog;
+ }
+
public static AlertDialog createDialogWithCustomView(final Activity activity, String message,
View customView,
DialogInterface.OnClickListener yesClickListener,
@@ -514,4 +555,34 @@ public class DialogFactory {
return dialog;
}
+
+ public static Dialog showModalPurchaseStoreItem(Context context,
+ String title,
+ String msg,
+ @Nullable String positiveButtonText,
+ @Nullable String negativeButtonText,
+ @Nullable DialogInterface.OnClickListener positiveListener,
+ @Nullable DialogInterface.OnClickListener negativeListener) {
+ if (context == null) return null;
+ AlertDialog.Builder builder = new AlertDialog.Builder(context,
+ R.style.Nynja_PopupMenu_AlertDialog
+ /*R.style.Nynja_Dialog*/
+ );
+ builder.setIcon(android.R.drawable.ic_dialog_info);
+ builder.setTitle(title);
+ builder.setMessage(msg);
+ builder.setPositiveButton(positiveButtonText, positiveListener);
+ builder.setNegativeButton(negativeButtonText, negativeListener);
+ builder.setCancelable(false);
+ Dialog dialog = builder.create();
+ dialog.show();
+
+ TextView tv = dialog.findViewById(android.R.id.message);
+ if (tv != null) tv.setGravity(Gravity.CENTER);
+
+ changeMessageTextSize(dialog);
+
+ return dialog;
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_mute_mic_icon.xml b/app/src/main/res/drawable/ic_mute_mic_icon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ee444f25f19fdfe415aefb90a537bff3e0742b96
--- /dev/null
+++ b/app/src/main/res/drawable/ic_mute_mic_icon.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/video_feed_square_stroke_green.xml b/app/src/main/res/drawable/video_feed_square_stroke_green.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ec8f78faa7463c0421e66b6b9ba3d70eff7ef34a
--- /dev/null
+++ b/app/src/main/res/drawable/video_feed_square_stroke_green.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/video_feed_square_stroke_red.xml b/app/src/main/res/drawable/video_feed_square_stroke_red.xml
new file mode 100644
index 0000000000000000000000000000000000000000..04f48350efd902a5f151bcc7634f4893954e6fd2
--- /dev/null
+++ b/app/src/main/res/drawable/video_feed_square_stroke_red.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_rv_call.xml b/app/src/main/res/layout/activity_rv_call.xml
new file mode 100644
index 0000000000000000000000000000000000000000..26a98b0d3c92a0d2aade003d5f69b5559a4d9d28
--- /dev/null
+++ b/app/src/main/res/layout/activity_rv_call.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_conference_video_call.xml b/app/src/main/res/layout/fragment_conference_video_call.xml
new file mode 100644
index 0000000000000000000000000000000000000000..260e83a9429f84f343cfb8849abae09268567196
--- /dev/null
+++ b/app/src/main/res/layout/fragment_conference_video_call.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_input_phone.xml b/app/src/main/res/layout/fragment_input_phone.xml
index 11e1d60ee9a0102c19905251f90ae994e3fe40dd..1bb2aa7f1b05954ef29c1d8b0c87f84672d048ee 100644
--- a/app/src/main/res/layout/fragment_input_phone.xml
+++ b/app/src/main/res/layout/fragment_input_phone.xml
@@ -37,211 +37,173 @@
app:layout_constraintTop_toBottomOf="@id/top_welcome_label_tv"
app:srcCompat="@drawable/logo"/>
-
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/f_iphone_img_logo"
+ tools:layout_editor_absoluteX="16dp">
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
-
-
-
-
-
+ android:layout_height="wrap_content" />
+
+
-
-
-
+
-
+ android:animateLayoutChanges="true"
+ app:layout_constraintTop_toTopOf="parent">
-
-
-
+
+
-
-
+ tools:text="Ukraine" />
-
-
-
-
+
+
+
-
-
+
-
+
-
-
-
+
-
+
+
+
+
+
+
+
+
-
+
-
+ android:enabled="false"
+ android:text="@string/next"
+ app:layout_constraintTop_toBottomOf="@id/auth_layout" />
-
-
-
-
-
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/margin_large"
+ android:animateLayoutChanges="true"
+ android:orientation="vertical"
+ app:layout_constraintBottom_toBottomOf="parent">
-
+ android:layout_gravity="center_horizontal"
+ android:text="@string/signin.or"
+ android:textColor="@color/hint.grey" />
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/li_conference_participant.xml b/app/src/main/res/layout/li_conference_participant.xml
index b01f8f61d52355295886974c2d0a00089c5d10a4..4977502ffeb69b0a25130160cc83f1c8d1d8a659 100644
--- a/app/src/main/res/layout/li_conference_participant.xml
+++ b/app/src/main/res/layout/li_conference_participant.xml
@@ -33,9 +33,7 @@
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:srcCompat="@drawable/v_ic_mute_member" />
+ app:srcCompat="@drawable/ic_mute_mic_icon" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_buttons_layout.xml b/app/src/main/res/layout/login_buttons_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..05d7f115ec0b7ae9e304583f959caa3144a36221
--- /dev/null
+++ b/app/src/main/res/layout/login_buttons_layout.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/login_choice_layout.xml b/app/src/main/res/layout/login_choice_layout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..534d7c072bf8d08db3f1e6b63a68c6709f8df02f
--- /dev/null
+++ b/app/src/main/res/layout/login_choice_layout.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
index 4d37bdf51d7847c515481cc3ac6a395b98053d84..70c50b5768ca816e601df35578e92cdd36911c93 100644
--- a/app/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values-en/strings.xml
@@ -848,10 +848,10 @@
Get Help
Unblock
No Data
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
Terminate this session?
Please check Internet connection and try again.
@@ -1324,4 +1324,17 @@
Phone number: +%1$s
Please select at least one message.
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
+
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 22bd5fd8329280b445bb9d03f7cc24fccfd506fd..a4c40ba95768c269b34ecbd1bb60c06ad5dcc3bb 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -843,10 +843,10 @@
Obtener ayuda
Desbloquear
No hay datos
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
¿FInalizar esta sesión?
Comprueba la conexión a Internet e inténtalo de nuevo.
@@ -1323,4 +1323,17 @@
Uploading
View
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
+
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 1f467439e7aaf7d80a6616e2ff794bb666671d1e..0ff8c721e1167a0c73313f37733efa8ef841d7c6 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -843,10 +843,10 @@
도움말 보기
차단 해제
데이터 없음
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
이 세션을 끝내시겠습니까?
인터넷 연결 상태를 확인 후 다시 시도하세요.
@@ -1323,4 +1323,17 @@
Uploading
View
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
+
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 9e0603dfe01aae7f4929cd7e07dfd9620da2dc0c..5ccdce3a7a6e16dc45a822f44de0d66df1ab6ca6 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,9 +1,9 @@
-
+
欢迎来到
新手上路
-
+
选择一个国家
好的
错误的国家代码
@@ -58,7 +58,7 @@
名字必须在2-32个符号之间且中间不得超过一个空格。
姓氏必须在2-32个符号之间且中间不得超过一个空格。
用户名必须在2-32个符号之间且可以包含拉丁字母,数字和下划线。
-
+
账户设置
删除账户
状态
@@ -87,7 +87,7 @@
如果您删除了您的账户,您将永久无法再访问您的钱包,账户数据,信息和多媒体资料。此项操作是无法撤销的。\n\n删除您的账户即代表您确认收回您对NYNJA使用条款的同意。\n\n同时,请确保您已经保存好了12个单词种子,以便之后在其他平台重新生成您的密钥。
您确定想要删除您的账户吗?此项操作无法撤销。
您是群聊唯一的管理员。您在分配另一管理员之后可删除您的账户。
-
+
电话号码
电子邮箱
Facebook
@@ -109,14 +109,14 @@
Facebook链接
Twitter链接
对不起,现在无法添加联系人信息。
-
+
电子邮箱
-
+
语音信息
-
+
!警告!
您的设备似乎刷过机了。您的应用程式的安全性可能会受到损害。
-
+
通用
登出
@@ -124,12 +124,12 @@
删除用户
日历\配置
日历配置
-
+
已选定日历集成
Google日历
Microsoft 365 Outlook日历
-
+
自动创建群聊进行群呼叫
无信息时删除群聊
@@ -143,7 +143,7 @@
A
下午7:23
下午7:24
-
+
扫描二维码
保存至图库
@@ -153,20 +153,20 @@
加入群聊失败
您想要加入群聊:%1$s ?
相册
-
+
从图库选择
从相机拍摄
从图库选择
取消
添加联系人
-
+
无网络连接
用户未找到
可用空间不足
文件未保存至下载
此代码已发送。
-
+
添加联系人
从我的通讯录添加NYNJA用户
通过短信邀请
@@ -178,11 +178,11 @@
联系历史
添加Nynja用户
联系历史
-
+
添加
忽视
-
+
操作
聊天
@@ -198,7 +198,7 @@
帮助和\支持
日历
教程
-
+
%1$s %2$s
用户名: %1$s
@@ -231,7 +231,7 @@
隐藏
标为已读
标为未读
-
+
个人资料设置
个人资料信息
@@ -239,7 +239,7 @@
空闲超时
用户名\u002A
电子邮箱
-
+
新联系人
全部
@@ -261,7 +261,7 @@
方向盘\n位置
更改\号码
更改号码
-
+
历史
按二维\n码
@@ -271,7 +271,7 @@
按用户名
按联系人
邀请好友
-
+
联系人
视频通话
@@ -282,7 +282,7 @@
位置
视频
加入会议
-
+
最近
最近聊天
@@ -290,7 +290,7 @@
家庭
工作
已预约发送
-
+
我的二维\n码
编辑账户
@@ -302,20 +302,20 @@
更改\n号码
我的二维码
群聊\n选项
-
+
输入电子邮箱地址
输入电话号码
输入用户名
用户未找到
未找到结果
-
+
接受
已添加
已请求
历史
-
+
呼叫历史
呼叫历史
@@ -336,7 +336,7 @@
%1$sh
%1$sm
%1$ss
-
+
切换至音频
接受音频
@@ -414,9 +414,9 @@
说话者
耳机
呼叫未找到
-
-
-
+
+
+
活跃
空闲
@@ -455,7 +455,7 @@
替换
Keep
此对话草稿已保存在服务器上。您想要删除您当前的草稿信息吗?
-
+
出错
移动通信器
永不回头
@@ -490,11 +490,11 @@
翻译失败。请重试。
转录失败。请重试。
您有另外一个通话正在进行中。请完成您的其他通话并重试。
-
+
打开
复制链接
-
+
新的群聊
群聊名称*:
@@ -520,14 +520,14 @@
新用户在通话中没有位置
新用户在通话中只有%1$d位置
复制链接
-
+
余额
显示全部
星标信息
进入聊天
进入群聊
进入星标信息
-
+
未读信息
未读群聊信息
联系人请求
@@ -537,7 +537,7 @@
%1$d位成员,%2$d位处于活跃状态
%1$d位成员
您已经从此群聊中被移出
-
+
编辑姓名
保留您的现有姓名。
@@ -547,7 +547,7 @@
不要添加用户名。
您可以在NYNJA上选择一个用户名。在您选定之后,其他人将能够通过此用户名找到您,他们无需知道您的电话号码就可以与您取得联系。
保留您的现有用户名。
-
+
群组规则
通知
@@ -569,7 +569,7 @@
添加为成员
呼叫
您不是管理员。请申请本群聊的添加权限。
-
+
点击两次退出。
对不起,此用户名是无效的
用户名必须至少2个字符
@@ -599,7 +599,7 @@
%2$d中的%1$d发送中
%1$s加入了群聊
%1$s加入了群聊
-
+
翻译接收信息的语言
发送已翻译信息的语言
@@ -618,11 +618,11 @@
自动
收到
关闭
-
+
翻译接收信息
翻译发送信息
将语音信息转录成文本
-
+
发送时的翻译语言
接收时自动翻译
发送时自动翻译
@@ -648,23 +648,23 @@
相机
更多
频道列表
-
+
粘贴
-
+
今天
上午
下午
日期
时间
-
+
小时
分钟
:
此处繁忙
+
-
+
星标
未加星标
@@ -693,15 +693,15 @@
停止共享
添加至日历
邀请您加入NYNJA会议。加入信息以关注。
-
+
删除双方信息
删除我的信息
删除全部信息
-
+
回复
活跃
-
+
语音信息
联系人
@@ -713,7 +713,7 @@
已删除信息
语音通话
视频通话
-
+
发送信息至:
文本信息:
@@ -730,11 +730,11 @@
选定的日期和/或时间是无效的。请一定要选择一个有效的日期和时间。
信息已经成功\n预约发送
您无法预约发送音频信息,因为您无法连接到服务器。
-
+
已加星标信息
已添加:%1$s
-
+
用户名可以包含英文字母,数字和下划线
错误的用户名格式
返回主页
@@ -751,13 +751,13 @@
您正在使用的是一个过时的应用版本。请确保从Play Store下载最新版本。如果您现在的版本是从Play Store下载的最新版并且您仍然会收到此信息,请稍作坚持,等待开发团队为您发布新版本。
Send Location发送位置
搜索或选择一个地方
-
+
地图
精确到%1$d米
卫星
混合
无结果
-
+
全部
文本
@@ -768,7 +768,7 @@
音频
联系人
位置
-
+
照片
视频
@@ -778,7 +778,7 @@
无数据
不支持附件
已编辑
-
+
已选定
未选定聊天
@@ -787,7 +787,7 @@
请至少选个一个聊天
\u0020和%d其他
\u0020和%d其他
-
+
已加入黑名单
邀请好友
@@ -795,12 +795,12 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
邀请至Nynja
联系卡
-
+
已加入黑名单联系人
-
+
Google服务必需使用此功能
-
+
星期一
星期二
@@ -809,7 +809,7 @@
星期五
星期六
星期日
-
+
星期一
星期二
星期三
@@ -817,7 +817,7 @@
星期五
星期六
星期日
-
+
共享
分享音频
@@ -826,11 +826,11 @@
分享文件
分享链接
分享联系人
-
+
NYNJA for Android\n%s
版本
版本号
-
+
当前会话
中止全部其他会话
@@ -843,19 +843,19 @@
获得帮助
移出黑名单
无数据
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
-
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
+
中止本会话?
请检查网络连接并重试。
对不起,我们在没有网络连接的情况下无法进行搜索。
已删除参与人
已删除联系人
-
+
进入联系历史
-
+
选择国家
当前号码:
@@ -872,7 +872,7 @@
您应当在%d秒内收到它。
分享NYNJA
数据和存储
-
+
新消息提醒
呼叫通知
@@ -889,7 +889,7 @@
NYNJA Android
NYNJA iOS
已发信息音
-
+
方向盘位置
选择方向盘位置
@@ -897,14 +897,14 @@
右手
(当前位置)
使用此方向盘位置?
-
+
主题
选择最适合您的主题
黑暗的归途
天国的阶梯
使用此主题?
-
+
自动多媒体下载
本地存储使用
当使用移动数据时
@@ -924,7 +924,7 @@
GIFs
转录
转录中…
-
+
时间表设置
显示发送信息
@@ -939,7 +939,7 @@
本周
最后7天
最后30天
-
+
频道名称*
频道链接*
@@ -955,7 +955,7 @@
您的频道列表是空的。您可以创建您自己的频道。
对不起,无订阅者可供选择
订阅者
-
+
网格
扫描二维码
@@ -985,7 +985,7 @@
相机正在被一款其他应用在使用。
麦克风正在通话中使用。在通话中静音即可开始录制视频。
麦克风正在被一款其他有应用在使用。
-
+
未找到任何结果…\n尝试另一次搜索
此链接已经在使用
群聊照片
@@ -1002,12 +1002,12 @@
剪切
复制
标签
-
+
加入
播放...
您不再具有查看此频道内容的权限。
管理员已经将您屏蔽。
-
+
- %1$d订阅者
- %1$d订阅者
@@ -1016,7 +1016,7 @@
- %1$d订阅者
- %1$d订阅者
-
+
创建钱包
钱包
@@ -1065,14 +1065,14 @@
最多500个符号
用户未找到
生成种子
-
+
新的信息
未知错误
频道信息
频道已存在
-
+
即将推出
-
+
市场
自由职业
@@ -1095,7 +1095,7 @@
口译类型
搜索口译人员
总价格
-
+
输入口译时间 (1-300)
时间范围从1到300分钟
请选择您想要进行口译的源语言
@@ -1128,7 +1128,7 @@
口译人员分配中
NYNJA正在为您寻找完美的口译人员。继续使用本应用,我们将在口译人员准备好开始通话时通知您。
即将推出
-
+
0.0 K/s
@@ -1138,7 +1138,7 @@
好友通知
添加好友请求通知
呼叫通知
-
+
%1$s想要在NYNJA添加您为好友!
通过短信邀请
@@ -1171,14 +1171,14 @@
直接拨打电话号码
发送短信信息
设置
-
+
现在
一分钟前
%d分钟前
今天
昨天
-
+
内部错误。请稍后再试
验证码不正确
@@ -1194,13 +1194,13 @@
电话号码是无效的
电话号码已在使用
请检查您所输入的数据
-
+
分享内容访问失败。
不支持功能
服务台
服务台目前不可用。请稍后再试!
-
+
无已加入黑名单联系人
Home phone
@@ -1323,4 +1323,17 @@
Uploading
View
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
+
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index 9e0603dfe01aae7f4929cd7e07dfd9620da2dc0c..5ccdce3a7a6e16dc45a822f44de0d66df1ab6ca6 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -1,9 +1,9 @@
-
+
欢迎来到
新手上路
-
+
选择一个国家
好的
错误的国家代码
@@ -58,7 +58,7 @@
名字必须在2-32个符号之间且中间不得超过一个空格。
姓氏必须在2-32个符号之间且中间不得超过一个空格。
用户名必须在2-32个符号之间且可以包含拉丁字母,数字和下划线。
-
+
账户设置
删除账户
状态
@@ -87,7 +87,7 @@
如果您删除了您的账户,您将永久无法再访问您的钱包,账户数据,信息和多媒体资料。此项操作是无法撤销的。\n\n删除您的账户即代表您确认收回您对NYNJA使用条款的同意。\n\n同时,请确保您已经保存好了12个单词种子,以便之后在其他平台重新生成您的密钥。
您确定想要删除您的账户吗?此项操作无法撤销。
您是群聊唯一的管理员。您在分配另一管理员之后可删除您的账户。
-
+
电话号码
电子邮箱
Facebook
@@ -109,14 +109,14 @@
Facebook链接
Twitter链接
对不起,现在无法添加联系人信息。
-
+
电子邮箱
-
+
语音信息
-
+
!警告!
您的设备似乎刷过机了。您的应用程式的安全性可能会受到损害。
-
+
通用
登出
@@ -124,12 +124,12 @@
删除用户
日历\配置
日历配置
-
+
已选定日历集成
Google日历
Microsoft 365 Outlook日历
-
+
自动创建群聊进行群呼叫
无信息时删除群聊
@@ -143,7 +143,7 @@
A
下午7:23
下午7:24
-
+
扫描二维码
保存至图库
@@ -153,20 +153,20 @@
加入群聊失败
您想要加入群聊:%1$s ?
相册
-
+
从图库选择
从相机拍摄
从图库选择
取消
添加联系人
-
+
无网络连接
用户未找到
可用空间不足
文件未保存至下载
此代码已发送。
-
+
添加联系人
从我的通讯录添加NYNJA用户
通过短信邀请
@@ -178,11 +178,11 @@
联系历史
添加Nynja用户
联系历史
-
+
添加
忽视
-
+
操作
聊天
@@ -198,7 +198,7 @@
帮助和\支持
日历
教程
-
+
%1$s %2$s
用户名: %1$s
@@ -231,7 +231,7 @@
隐藏
标为已读
标为未读
-
+
个人资料设置
个人资料信息
@@ -239,7 +239,7 @@
空闲超时
用户名\u002A
电子邮箱
-
+
新联系人
全部
@@ -261,7 +261,7 @@
方向盘\n位置
更改\号码
更改号码
-
+
历史
按二维\n码
@@ -271,7 +271,7 @@
按用户名
按联系人
邀请好友
-
+
联系人
视频通话
@@ -282,7 +282,7 @@
位置
视频
加入会议
-
+
最近
最近聊天
@@ -290,7 +290,7 @@
家庭
工作
已预约发送
-
+
我的二维\n码
编辑账户
@@ -302,20 +302,20 @@
更改\n号码
我的二维码
群聊\n选项
-
+
输入电子邮箱地址
输入电话号码
输入用户名
用户未找到
未找到结果
-
+
接受
已添加
已请求
历史
-
+
呼叫历史
呼叫历史
@@ -336,7 +336,7 @@
%1$sh
%1$sm
%1$ss
-
+
切换至音频
接受音频
@@ -414,9 +414,9 @@
说话者
耳机
呼叫未找到
-
-
-
+
+
+
活跃
空闲
@@ -455,7 +455,7 @@
替换
Keep
此对话草稿已保存在服务器上。您想要删除您当前的草稿信息吗?
-
+
出错
移动通信器
永不回头
@@ -490,11 +490,11 @@
翻译失败。请重试。
转录失败。请重试。
您有另外一个通话正在进行中。请完成您的其他通话并重试。
-
+
打开
复制链接
-
+
新的群聊
群聊名称*:
@@ -520,14 +520,14 @@
新用户在通话中没有位置
新用户在通话中只有%1$d位置
复制链接
-
+
余额
显示全部
星标信息
进入聊天
进入群聊
进入星标信息
-
+
未读信息
未读群聊信息
联系人请求
@@ -537,7 +537,7 @@
%1$d位成员,%2$d位处于活跃状态
%1$d位成员
您已经从此群聊中被移出
-
+
编辑姓名
保留您的现有姓名。
@@ -547,7 +547,7 @@
不要添加用户名。
您可以在NYNJA上选择一个用户名。在您选定之后,其他人将能够通过此用户名找到您,他们无需知道您的电话号码就可以与您取得联系。
保留您的现有用户名。
-
+
群组规则
通知
@@ -569,7 +569,7 @@
添加为成员
呼叫
您不是管理员。请申请本群聊的添加权限。
-
+
点击两次退出。
对不起,此用户名是无效的
用户名必须至少2个字符
@@ -599,7 +599,7 @@
%2$d中的%1$d发送中
%1$s加入了群聊
%1$s加入了群聊
-
+
翻译接收信息的语言
发送已翻译信息的语言
@@ -618,11 +618,11 @@
自动
收到
关闭
-
+
翻译接收信息
翻译发送信息
将语音信息转录成文本
-
+
发送时的翻译语言
接收时自动翻译
发送时自动翻译
@@ -648,23 +648,23 @@
相机
更多
频道列表
-
+
粘贴
-
+
今天
上午
下午
日期
时间
-
+
小时
分钟
:
此处繁忙
+
-
+
星标
未加星标
@@ -693,15 +693,15 @@
停止共享
添加至日历
邀请您加入NYNJA会议。加入信息以关注。
-
+
删除双方信息
删除我的信息
删除全部信息
-
+
回复
活跃
-
+
语音信息
联系人
@@ -713,7 +713,7 @@
已删除信息
语音通话
视频通话
-
+
发送信息至:
文本信息:
@@ -730,11 +730,11 @@
选定的日期和/或时间是无效的。请一定要选择一个有效的日期和时间。
信息已经成功\n预约发送
您无法预约发送音频信息,因为您无法连接到服务器。
-
+
已加星标信息
已添加:%1$s
-
+
用户名可以包含英文字母,数字和下划线
错误的用户名格式
返回主页
@@ -751,13 +751,13 @@
您正在使用的是一个过时的应用版本。请确保从Play Store下载最新版本。如果您现在的版本是从Play Store下载的最新版并且您仍然会收到此信息,请稍作坚持,等待开发团队为您发布新版本。
Send Location发送位置
搜索或选择一个地方
-
+
地图
精确到%1$d米
卫星
混合
无结果
-
+
全部
文本
@@ -768,7 +768,7 @@
音频
联系人
位置
-
+
照片
视频
@@ -778,7 +778,7 @@
无数据
不支持附件
已编辑
-
+
已选定
未选定聊天
@@ -787,7 +787,7 @@
请至少选个一个聊天
\u0020和%d其他
\u0020和%d其他
-
+
已加入黑名单
邀请好友
@@ -795,12 +795,12 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
邀请至Nynja
联系卡
-
+
已加入黑名单联系人
-
+
Google服务必需使用此功能
-
+
星期一
星期二
@@ -809,7 +809,7 @@
星期五
星期六
星期日
-
+
星期一
星期二
星期三
@@ -817,7 +817,7 @@
星期五
星期六
星期日
-
+
共享
分享音频
@@ -826,11 +826,11 @@
分享文件
分享链接
分享联系人
-
+
NYNJA for Android\n%s
版本
版本号
-
+
当前会话
中止全部其他会话
@@ -843,19 +843,19 @@
获得帮助
移出黑名单
无数据
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
-
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
+
中止本会话?
请检查网络连接并重试。
对不起,我们在没有网络连接的情况下无法进行搜索。
已删除参与人
已删除联系人
-
+
进入联系历史
-
+
选择国家
当前号码:
@@ -872,7 +872,7 @@
您应当在%d秒内收到它。
分享NYNJA
数据和存储
-
+
新消息提醒
呼叫通知
@@ -889,7 +889,7 @@
NYNJA Android
NYNJA iOS
已发信息音
-
+
方向盘位置
选择方向盘位置
@@ -897,14 +897,14 @@
右手
(当前位置)
使用此方向盘位置?
-
+
主题
选择最适合您的主题
黑暗的归途
天国的阶梯
使用此主题?
-
+
自动多媒体下载
本地存储使用
当使用移动数据时
@@ -924,7 +924,7 @@
GIFs
转录
转录中…
-
+
时间表设置
显示发送信息
@@ -939,7 +939,7 @@
本周
最后7天
最后30天
-
+
频道名称*
频道链接*
@@ -955,7 +955,7 @@
您的频道列表是空的。您可以创建您自己的频道。
对不起,无订阅者可供选择
订阅者
-
+
网格
扫描二维码
@@ -985,7 +985,7 @@
相机正在被一款其他应用在使用。
麦克风正在通话中使用。在通话中静音即可开始录制视频。
麦克风正在被一款其他有应用在使用。
-
+
未找到任何结果…\n尝试另一次搜索
此链接已经在使用
群聊照片
@@ -1002,12 +1002,12 @@
剪切
复制
标签
-
+
加入
播放...
您不再具有查看此频道内容的权限。
管理员已经将您屏蔽。
-
+
- %1$d订阅者
- %1$d订阅者
@@ -1016,7 +1016,7 @@
- %1$d订阅者
- %1$d订阅者
-
+
创建钱包
钱包
@@ -1065,14 +1065,14 @@
最多500个符号
用户未找到
生成种子
-
+
新的信息
未知错误
频道信息
频道已存在
-
+
即将推出
-
+
市场
自由职业
@@ -1095,7 +1095,7 @@
口译类型
搜索口译人员
总价格
-
+
输入口译时间 (1-300)
时间范围从1到300分钟
请选择您想要进行口译的源语言
@@ -1128,7 +1128,7 @@
口译人员分配中
NYNJA正在为您寻找完美的口译人员。继续使用本应用,我们将在口译人员准备好开始通话时通知您。
即将推出
-
+
0.0 K/s
@@ -1138,7 +1138,7 @@
好友通知
添加好友请求通知
呼叫通知
-
+
%1$s想要在NYNJA添加您为好友!
通过短信邀请
@@ -1171,14 +1171,14 @@
直接拨打电话号码
发送短信信息
设置
-
+
现在
一分钟前
%d分钟前
今天
昨天
-
+
内部错误。请稍后再试
验证码不正确
@@ -1194,13 +1194,13 @@
电话号码是无效的
电话号码已在使用
请检查您所输入的数据
-
+
分享内容访问失败。
不支持功能
服务台
服务台目前不可用。请稍后再试!
-
+
无已加入黑名单联系人
Home phone
@@ -1323,4 +1323,17 @@
Uploading
View
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
+
diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml
index ec7e8a434ecd6a90f47ab477185a0a9db46822f0..28d7133a14a04d43116a8f748218c2faaae3bd5c 100644
--- a/app/src/main/res/values/dimen.xml
+++ b/app/src/main/res/values/dimen.xml
@@ -260,4 +260,9 @@
30dp
+
+ 12dp
+ 5dp
+ 8dp
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index db722a5096581c35c5c612b615a9483306ef1c35..011d976b8a79c9cb91f1d439ae8eca248392bbcb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -855,10 +855,10 @@
Get Help
Unblock
No Data
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
Terminate this session?
Please check Internet connection and try again.
@@ -1325,5 +1325,17 @@
Stop sharing
Stop video
+
+ "Create New NYNJA Account!"
+ Click \"Create New NYNJA Account\" below to confirm. If you already have a NYNJA account, click \"Use Another Account\"
+ Create New NYNJA Account
+ Use Another Account
+
+
+ Please stop your screen share first
+ Cannot start camera because it has been already started by another participant
+ Please stop your camera first
+ Cannot start screen share because it has been already started by another participant
+ Start camera is not available for groups
diff --git a/app/src/prod/res/values-en/strings.xml b/app/src/prod/res/values-en/strings.xml
index 4fa5447bdcab516d52d50c7618f80315de2519aa..fd4bc8680eb67cc2e7160f75b5944055bc82e220 100644
--- a/app/src/prod/res/values-en/strings.xml
+++ b/app/src/prod/res/values-en/strings.xml
@@ -5,9 +5,9 @@
Introducing an amazing new platform called NYNJA! It is a productivity and communications aggregator platform. Download it here: https://www.nynja.io/mobile and add me as a contact with my NYNJA user ID: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/prod/res/values-es/strings.xml b/app/src/prod/res/values-es/strings.xml
index 78812d62f36c19ce48f6a9d2551cf42156654d72..3cb971897dbd9f849b1a94ad1c74f5b31fb4e965 100644
--- a/app/src/prod/res/values-es/strings.xml
+++ b/app/src/prod/res/values-es/strings.xml
@@ -5,9 +5,9 @@
¡Presentamos una nueva y sorprendente plataforma llamada NYNJA! Es una plataforma agregadora de comunicaciones y productividad. Descárgala aquí: https://www.nynja.io/mobile y agrégame como contacto con mi ID de usuario NYNJA: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/prod/res/values-ko/strings.xml b/app/src/prod/res/values-ko/strings.xml
index e7d0c196c28baaba3d883e8b63fda65cd0523e1c..7d4eb06e4601b351064e6463e17a2a2edee97b92 100644
--- a/app/src/prod/res/values-ko/strings.xml
+++ b/app/src/prod/res/values-ko/strings.xml
@@ -5,9 +5,9 @@
새로운 플랫폼 NYNJA를 소개합니다! 다양한 커뮤니케이션 웹사이트 플랫폼입니다. https://www.nynja.io/mobile 여기에서 다운로드 후, NYNJA 사용자 ID: %1$s 연락처로 저를 추가하세요
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/prod/res/values-zh-rCN/strings.xml b/app/src/prod/res/values-zh-rCN/strings.xml
index e11af5132360de7c42456221db7fbdd330d46e97..66e01815f8e7fc7672c0b0e2fd3cdffde60d16c4 100644
--- a/app/src/prod/res/values-zh-rCN/strings.xml
+++ b/app/src/prod/res/values-zh-rCN/strings.xml
@@ -5,9 +5,9 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/prod/res/values-zh/strings.xml b/app/src/prod/res/values-zh/strings.xml
index e11af5132360de7c42456221db7fbdd330d46e97..66e01815f8e7fc7672c0b0e2fd3cdffde60d16c4 100644
--- a/app/src/prod/res/values-zh/strings.xml
+++ b/app/src/prod/res/values-zh/strings.xml
@@ -5,9 +5,9 @@
介绍一款名叫NYNJA的超棒的全新平台!这是一个集工作效率和沟通通信于一体的平台。在这里下载它:https://www.nynja.io/mobile并添加我为联系人,我的NYNJA用户名:%1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use
diff --git a/app/src/prod/res/values/strings.xml b/app/src/prod/res/values/strings.xml
index 4fa5447bdcab516d52d50c7618f80315de2519aa..fd4bc8680eb67cc2e7160f75b5944055bc82e220 100644
--- a/app/src/prod/res/values/strings.xml
+++ b/app/src/prod/res/values/strings.xml
@@ -5,9 +5,9 @@
Introducing an amazing new platform called NYNJA! It is a productivity and communications aggregator platform. Download it here: https://www.nynja.io/mobile and add me as a contact with my NYNJA user ID: %1$s
- https://www.nynja.io/nynja-faq
- https://www.nynja.io/how-to-videos
- https://www.nynja.io/privacy-policy
- https://www.nynja.io/terms-of-use
+ https://nynja.work/nynja-faq
+ https://nynja.work/how-to-videos
+ https://nynja.work/privacy-policy
+ https://nynja.work/terms-of-use