From d8cbc0cef2326cf25f49108d1e724d2ed4865535 Mon Sep 17 00:00:00 2001 From: Ergyun Syuleyman Date: Tue, 26 May 2020 13:09:27 +0300 Subject: [PATCH 01/10] -initial UI of NY-8442: [AN]: Implement Call Pickup --- .../data/sdk/ConferenceSDKPresenter.java | 2 + .../data/sdk/calls/ConferenceSDKListener.java | 2 + .../data/sdk/calls/ConferenceSDKModule.java | 62 +++++-- .../mvp/presenters/BasePresenter.java | 9 + .../mvp/presenters/MainActivityPresenter.kt | 31 +++- .../mvp/view/MainActivityView.java | 4 + .../ui/activities/MainActivity.java | 172 +++++++++++------- app/src/main/res/layout/activity_home.xml | 33 +++- .../main/res/layout/partial_call_pickup.xml | 75 ++++++++ app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/strings.xml | 3 + 11 files changed, 308 insertions(+), 87 deletions(-) create mode 100644 app/src/main/res/layout/partial_call_pickup.xml 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 9c1ae7305c..7c7444708a 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 @@ -51,6 +51,8 @@ public abstract class ConferenceSDKPresenter extends Bas @Override public void onStateChangedForCall(NYNCall iConference) {} + @Override public void onAcceptedElsewhereConference(String conferenceId) {} + @Override public void onCreateVideoCallReady(ActiveConferenceCall activeConferenceCall) {} @Override public void onScreenShareState(boolean active) {} 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 4710d6de07..76c67924f8 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 @@ -36,6 +36,8 @@ public interface ConferenceSDKListener { void onStateChangedForCall(NYNCall iConference); + void onAcceptedElsewhereConference(String conferenceId); + void onCreateVideoCallReady(ActiveConferenceCall activeConferenceCall); void onScreenShareState(boolean active); 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 b00746dd83..89a6005aae 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 @@ -26,7 +26,6 @@ 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.conference.ActiveCallBase; -import com.nynja.mobile.communicator.data.conference.ConferenceVideoModule; import com.nynja.mobile.communicator.data.db.DbHelper; import com.nynja.mobile.communicator.data.models.SettingNotifications; import com.nynja.mobile.communicator.data.models.StateDevice; @@ -77,7 +76,6 @@ import java.util.Map; import java.util.Timer; import java.util.TimerTask; -import kotlin.jvm.Synchronized; import timber.log.Timber; import static com.nynja.sdk.NYNCallEndReason.NYNCallEndReasonFailed; @@ -544,6 +542,31 @@ public class ConferenceSDKModule extends BaseSDKModule { } } + public boolean hasCallForPickup() { + if (mMyAcceptedElsewhereCalls.size() == 0) { + return false; + } + return true; + } + public synchronized String callPickupText() { + String text = ""; + synchronized (mMyAcceptedElsewhereCalls) { + for (String callId : mMyAcceptedElsewhereCalls.keySet()) { + NYNCall call = mCallManager.getCallById(callId); + if (call != null) { + if (StringUtils.isNotEmpty(text)) { + text += ", "; + } + if (!call.isConference()) { + String id = call.isOutgoing() ? call.callee() : call.caller(); + // TODO: get local contact OR ROOM name by ID + text += (call.getExternalInfo()); + } + } + } + } + return text; + } public boolean isCameraRunning() { if (!hasCreatedActiveCall()) return false; @@ -1075,6 +1098,8 @@ public class ConferenceSDKModule extends BaseSDKModule { conferenceId + "\' " + (result ? "succeed" : "failed!!!")); synchronized (mActiveConference.mData) { mActiveConference.mData.mParticipantArray = mActiveConference.mConference.getParticipants(); + Timber.d("Request conference member with members size=\'" + + mActiveConference.mData.mParticipantArray.size()); } // update chatRoomId @@ -1177,9 +1202,14 @@ public class ConferenceSDKModule extends BaseSDKModule { NYNCallState state = call.callState(); boolean isActive = !NYNCallState.NYNCallStateClosed.equals(state); if (StringUtils.isNotEmpty(roomId)) { - //if (!mMyAcceptedElsewhereCalls.containsKey(roomId) && isActive) { - // mMyAcceptedElsewhereCalls.put(roomId, callId); - //} else + if (NYNCallState.NYNCallStateConnected.equals(state) && + !mMyAcceptedElsewhereCalls.containsKey(callId)) { + if (!((hasCreatedActiveCall() && mActiveConference.mConference != null + && mActiveConference.mConference.callId().contentEquals(callId)) || + call.isStartedOnThisDevice())) { + mMyAcceptedElsewhereCalls.put(callId, roomId); + } + } if (!forceFireEvent) { if ((hasCreatedActiveCall() && mActiveConference.mConference != null && mActiveConference.mConference.callId().contentEquals(callId))) { @@ -1199,14 +1229,15 @@ public class ConferenceSDKModule extends BaseSDKModule { private void onCallEndedHandle(NYNCall call, boolean forceFireEvent) { if (call != null) { + String callId = call.callId(); String roomId = (call.isConference() ? call.getChatRoomId() : (call.isOutgoing() ? call.callee() : call.caller())); - //if (mMyAcceptedElsewhereCalls.containsKey(roomId)) { - // mMyAcceptedElsewhereCalls.remove(roomId); - //} else + if (mMyAcceptedElsewhereCalls.containsKey(callId)) { + mMyAcceptedElsewhereCalls.remove(callId); + } if (!forceFireEvent) { if (!(hasCreatedActiveCall() && mActiveConference.mConference != null - && mActiveConference.mConference.callId().contentEquals(call.callId()))) { + && mActiveConference.mConference.callId().contentEquals(callId))) { return; } } @@ -1423,7 +1454,7 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public void receivedAcceptedElsewhere(String conferenceId) { - onAcceptedElsewhereConferenceRinging(conferenceId); + onAcceptedElsewhereConference(conferenceId); } @Override @@ -2342,7 +2373,7 @@ public class ConferenceSDKModule extends BaseSDKModule { public boolean hasRunningCallWithRoom(String roomId) { return (mCallManager.hasRunningCallWithRoom(roomId) || - (//mMyAcceptedElsewhereCalls.containsKey(roomId) && + (//mMyAcceptedElsewhereCalls.containsValue(roomId) && mCallManager.hasRunningCallWithContact(roomId))); } @@ -3041,7 +3072,7 @@ public class ConferenceSDKModule extends BaseSDKModule { } } - private void onAcceptedElsewhereConferenceRinging(String conferenceId) { + private void onAcceptedElsewhereConference(String conferenceId) { if (!hasCreatedActiveCall()) return; if (mActiveConference.mConference == null) return; @@ -3051,7 +3082,12 @@ public class ConferenceSDKModule extends BaseSDKModule { && mActiveConference.isOutgoingCall) { // Nothing to do when is my outgoing call - may need check when allow multiple login } else { - //mMyAcceptedElsewhereCalls.put(mActiveConference.mEndPointId, conferenceId); + if (isP2P()) { + mMyAcceptedElsewhereCalls.put(conferenceId, mActiveConference.mEndPointId); + for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { + conferenceSDKListener.onAcceptedElsewhereConference(conferenceId); + } + } onConferenceEnded(conferenceId); } } 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 fd01699566..c0b8a8a169 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 @@ -266,6 +266,15 @@ public abstract class BasePresenter extends MvpPresenter< mDataManager.getConferenceSDK().isScreenShareAllowed = allowed; } + public boolean hasCallForPickup() { + return mDataManager.getConferenceSDK().hasCallForPickup(); + } + + public String callPickupText() { + if (!hasCallForPickup()) return ""; + return mDataManager.getConferenceSDK().callPickupText(); + } + @Override public void showDefaultError(@NotNull Object data, @StringRes int errorRes) { getViewState().showDefaultServerError(errorRes); } 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 923269e60c..d5d3fd7fa2 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 @@ -36,6 +36,7 @@ import com.nynja.mobile.communicator.utils.StringUtils import com.nynja.mobile.communicator.utils.navigation.Screen import com.nynja.mobile.communicator.utils.navigation.navigators.HomeNavigator import com.nynja.mobile.communicator.utils.navigation.navigators.NynjaNavigator +import com.nynja.sdk.NYNCall import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.Function import io.reactivex.schedulers.Schedulers @@ -126,6 +127,7 @@ class MainActivityPresenter : ConferenceSDKPresenter() { viewState.onInitWheel(mIsConferenceActive) val activeCall = mDataManager.conferenceSDK.activeConference if (activeCall != null) onConferenceStateChanged(activeCall) + onAcceptedElsewhereConference(""); } fun continueToJojnGroup() { @@ -620,16 +622,20 @@ class MainActivityPresenter : ConferenceSDKPresenter() { override fun activeConference(activeConferenceCall: ActiveConferenceCall) {} override fun timeAway(videoEnabled: Boolean, time: String) { + if (attachedViews.size == 0) return viewState.onConferenceTimeChange(time) } override fun conferenceEnded() { - viewState.onConferenceEnded() + if (attachedViews.size > 0) { + viewState.onConferenceEnded() + } invalidateWheelAfterCallStateChaged() clearIncomingCallNotification() } override fun onConferenceRinging() { + if (attachedViews.size == 0) return viewState.onConferenceRinging() } @@ -638,21 +644,40 @@ class MainActivityPresenter : ConferenceSDKPresenter() { } override fun onConferenceJoinFailed(reason: String) { - viewState.onConferenceJoinFailed(reason) + if (attachedViews.size > 0) { + viewState.onConferenceJoinFailed(reason) + } invalidateWheelAfterCallStateChaged() } override fun onConferenceStateChanged(activeConferenceCall: ActiveConferenceCall) { + if (attachedViews.size == 0) return viewState.onConferenceStateChanged(activeConferenceCall) } + override fun onStateChangedForCall(iConference: NYNCall?) { + if (attachedViews.size == 0) return + if (iConference != null) { + viewState.onStateChangedForCall(iConference.callId()) + } + } + + override fun onAcceptedElsewhereConference(conferenceId: String) { + if (attachedViews.size == 0) return + if (conferenceId != null) { + viewState.onAcceptedElsewhereConference(conferenceId) + } + } + override fun showPurchaseDialog(isModerator: Boolean, message: String?) { if (attachedViews.size == 0) return viewState.showPurchaseDialog(isModerator, message) } fun openActiveConference() { - viewState.openActiveConference() + if (attachedViews.size > 0) { + viewState.openActiveConference() + } mRouter.backTo(HomeNavigator.CHAT) } 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 4ecb0e41d9..750054749c 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 @@ -41,6 +41,10 @@ public interface MainActivityView extends JoinGroupView { void onConferenceStateChanged(ActiveConferenceCall activeConferenceCall); + void onStateChangedForCall(String callId); + + void onAcceptedElsewhereConference(String conferenceId); + void openActiveConference(); void onConferenceRinging(); 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 cc4a659d41..a8aa689d13 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 @@ -102,27 +102,23 @@ public class MainActivity extends BaseActivity implements MainActivityView, private static final String OPEN_SCREEN_KEY = "open_screen_key"; private static final String FILE_TYPE = "file"; - @BindView(R.id.nynja_navigation_view) - NynjaNavigationView mNynjaNavigationView; - @BindView(R.id.chat_active_video) - SurfaceViewRenderer video; - @BindView(R.id.chat_audio_layout) - View chatAudioLayout; - @BindView(R.id.chat_audio_name) - TextView chatAudioName; - @BindView(R.id.chat_audio_duration) - TextView duration; - @BindView(R.id.chat_return_text) - TextView headerStatusText; - @BindView(R.id.chat_audio_photo) - ImageView audioAvatar; - @BindView(R.id.home_activity_container_cl) - CoordinatorLayout mHomeActivityContainerCl; - @BindView(R.id.a_home_container) - RelativeLayout mHomeContainer; + @BindView(R.id.nynja_navigation_view) NynjaNavigationView mNynjaNavigationView; + @BindView(R.id.chat_active_video) SurfaceViewRenderer video; + @BindView(R.id.chat_audio_layout) View chatAudioLayout; + @BindView(R.id.chat_audio_name) TextView chatAudioName; + @BindView(R.id.chat_audio_duration) TextView duration; + @BindView(R.id.chat_return_text) TextView headerStatusText; + @BindView(R.id.chat_audio_photo) ImageView audioAvatar; + @BindView(R.id.home_activity_container_cl) CoordinatorLayout mHomeActivityContainerCl; + @BindView(R.id.a_home_container) RelativeLayout mHomeContainer; //Second Keyboard Container - @BindView(R.id.a_home_keyboard_container) - ViewGroup mSecondKeyboardContainer; + @BindView(R.id.a_home_keyboard_container) ViewGroup mSecondKeyboardContainer; + + // Call pickup banner + @BindView(R.id.call_pickup_layout) View callPickupLayout; + @BindView(R.id.call_pickup_name) TextView callPickupName; + @BindView(R.id.call_pickup_count) TextView callPickupCount; + @BindView(R.id.call_pickup_title_text) TextView callPickupHeaderText; @InjectPresenter MainActivityPresenter mPresenter; @@ -190,7 +186,7 @@ public class MainActivity extends BaseActivity implements MainActivityView, mContainer = new Container(this); mContainer.setOnScreenChangedListener(this); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - params.addRule(RelativeLayout.BELOW, R.id.chat_audio_layout); + params.addRule(RelativeLayout.BELOW, R.id.call_top_banner_layout); mHomeContainer.addView(mContainer, params); mNavigator = new HomeNavigator(this); @@ -591,14 +587,7 @@ public class MainActivity extends BaseActivity implements MainActivityView, @Override public void onConferenceEnded() { - mHandler.postDelayed(() -> releaseWakeLock(), Consts.DELAY_500); - runOnUiThread(() -> { - video.setVisibility(View.GONE); - chatAudioLayout.setVisibility(View.GONE); - duration.setText(""); - headerStatusText.setText(R.string.call_connecting); - chatAudioName.setText(""); - }); + onCallEnded(); } @Override @@ -609,41 +598,23 @@ public class MainActivity extends BaseActivity implements MainActivityView, @Override public void onConferenceStateChanged(ActiveConferenceCall activeConferenceCall) { - if (activeConferenceCall == null) return; - if (!mPresenter.isConferenceActive()) return; - if (!activeConferenceCall.isCallInProgress() - && !activeConferenceCall.isRinging - && !activeConferenceCall.isWaiting()) return; - if (activeConferenceCall.mConference != null && - activeConferenceCall.mConference.callState() == NYNCallState.NYNCallStateConnected) { - mHandler.post(() -> wakeLock()); - } + onCallStateChanged(activeConferenceCall); + } + + @Override + public void onStateChangedForCall(String callId) { runOnUiThread(() -> { - video.setVisibility(View.GONE); - if (activeConferenceCall != null && activeConferenceCall.isWaiting()) { - chatAudioLayout.setBackgroundResource(R.color.waiting_call_bg); - headerStatusText.setText(R.string.call_waiting_period); - } else { - chatAudioLayout.setBackgroundResource(R.color.active_call_bg); - } - chatAudioLayout.setVisibility(View.VISIBLE); - mPresenter.requestUser(); - //TODO: video feeds support in next features - //if (!activeConferenceCall.mData.isOwnStreamActive || !activeConferenceCall.hasRemoteVideoTrack) { - // video.setVisibility(View.GONE); - // chatAudioLayout.setVisibility(View.VISIBLE); - // mPresenter.requestUser(); - // if (activeConferenceCall.mConference != null) - // activeConferenceCall.mConference.setVideoRendererForTrack(video); - //} else { - // video.setVisibility(View.VISIBLE); - // chatAudioLayout.setVisibility(View.GONE); - // if (activeConferenceCall.mConference != null) { - // activeConferenceCall.mConference.setVideoRendererForTrack(null); - // } - //} - } - ); + onCallsStateChanged(); + }); + + } + + @Override + public void onAcceptedElsewhereConference(String conferenceId) { + runOnUiThread(() -> { + onCallsStateChanged(); + }); + } @Override @@ -1003,4 +974,79 @@ public class MainActivity extends BaseActivity implements MainActivityView, } ); } + + private void onCallStateChanged(ActiveConferenceCall activeConferenceCall) { + if ((activeConferenceCall == null) || + (!mPresenter.isConferenceActive()) || + (!activeConferenceCall.isCallInProgress() + && !activeConferenceCall.isRinging + && !activeConferenceCall.isWaiting())) { + runOnUiThread(() -> { + onCallsStateChanged(); + }); + return; + } + if (activeConferenceCall.mConference != null && + activeConferenceCall.mConference.callState() == NYNCallState.NYNCallStateConnected) { + mHandler.post(() -> wakeLock()); + } + runOnUiThread(() -> { + onActiveCallStateChanged(activeConferenceCall); + }); + } + + private void onCallEnded() { + mHandler.postDelayed(() -> releaseWakeLock(), Consts.DELAY_500); + runOnUiThread(() -> { + onActiveCallEnded(); + }); + } + + private void onActiveCallStateChanged(ActiveConferenceCall activeConferenceCall) { + video.setVisibility(View.GONE); + if (activeConferenceCall != null && activeConferenceCall.isWaiting()) { + chatAudioLayout.setBackgroundResource(R.color.waiting_call_bg); + headerStatusText.setText(R.string.call_waiting_period); + } else { + chatAudioLayout.setBackgroundResource(R.color.active_call_bg); + } + callPickupLayout.setVisibility(View.GONE); + chatAudioLayout.setVisibility(View.VISIBLE); + mPresenter.requestUser(); + //TODO: video feeds support in next features + //if (!activeConferenceCall.mData.isOwnStreamActive || !activeConferenceCall.hasRemoteVideoTrack) { + // video.setVisibility(View.GONE); + // chatAudioLayout.setVisibility(View.VISIBLE); + // mPresenter.requestUser(); + // if (activeConferenceCall.mConference != null) + // activeConferenceCall.mConference.setVideoRendererForTrack(video); + //} else { + // video.setVisibility(View.VISIBLE); + // chatAudioLayout.setVisibility(View.GONE); + // if (activeConferenceCall.mConference != null) { + // activeConferenceCall.mConference.setVideoRendererForTrack(null); + // } + //} + } + + private void onActiveCallEnded() { + video.setVisibility(View.GONE); + chatAudioLayout.setVisibility(View.GONE); + duration.setText(""); + headerStatusText.setText(R.string.call_connecting); + chatAudioName.setText(""); + + onCallsStateChanged(); + } + + private void onCallsStateChanged() { + if (mPresenter.hasCallForPickup()) { + //callPickupCount.setText(mPresenter.callPickupCount()); + callPickupLayout.setVisibility(View.VISIBLE); + callPickupName.setText(mPresenter.callPickupText()); + } else { + callPickupLayout.setVisibility(View.GONE); + } + } + } diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 31948f8463..3b17c6014a 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -1,11 +1,11 @@ - + android:orientation="vertical" + xmlns:tools="http://schemas.android.com/tools"> + android:layout_below="@+id/call_top_banner_layout"/> - + android:orientation="vertical"> + + + + + + diff --git a/app/src/main/res/layout/partial_call_pickup.xml b/app/src/main/res/layout/partial_call_pickup.xml new file mode 100644 index 0000000000..97bf17fd92 --- /dev/null +++ b/app/src/main/res/layout/partial_call_pickup.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 70dc74265c..38dfadc534 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -99,4 +99,6 @@ #A6ffffff #00000000 + #676BB9 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 398d5866d8..9fdb634ef2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1338,4 +1338,7 @@ Cannot start screen share because it has been already started by another participant Start camera is not available for groups + + Call pickup + -- GitLab From 109ade1330fae8811d8532e59613d4fe72d6cb36 Mon Sep 17 00:00:00 2001 From: Ergyun Syuleyman Date: Sun, 31 May 2020 19:32:04 +0300 Subject: [PATCH 02/10] -first alpha version of call pickup :) --- app/build.gradle | 2 +- .../data/sdk/ConferenceSDKPresenter.java | 3 + .../data/sdk/NynjaSDKManager.java | 2 +- .../data/sdk/calls/ConferenceSDKListener.java | 2 + .../data/sdk/calls/ConferenceSDKModule.java | 181 ++++++++++++++++-- .../mvp/presenters/BasePresenter.java | 54 ++++++ .../mvp/presenters/MainActivityPresenter.kt | 20 +- .../mvp/view/MainActivityView.java | 2 + .../ui/activities/MainActivity.java | 85 +++++++- .../communicator/utils/DialogFactory.java | 48 ++++- .../main/res/layout/partial_call_pickup.xml | 10 +- app/src/main/res/values-en/strings.xml | 5 + app/src/main/res/values-es/strings.xml | 5 + app/src/main/res/values-ko/strings.xml | 5 + app/src/main/res/values-zh-rCN/strings.xml | 5 + app/src/main/res/values-zh/strings.xml | 5 + app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/strings.xml | 2 + 18 files changed, 399 insertions(+), 39 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index dec91bee46..c87335eaef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -679,7 +679,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // Conference, Calls mobile SDK - implementation 'com.nynja.sdk:NynjaSdk:1.21.5@aar' + implementation 'com.nynja.sdk:NynjaSdk:1.21.5.1@aar' //implementation(name: 'NynjaSdk-1.21.5', ext: 'aar') //ExoPlayer 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 63e96f550c..9e3b3ee8cc 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 @@ -102,4 +102,7 @@ public abstract class ConferenceSDKPresenter extends Bas @Override public void showPurchaseDialog(boolean isModerator, final String message) {} @Override public void onPurchaseFinished() {} + + @Override public void pickupCallWhileAnotherActiveCall() {} + } diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/NynjaSDKManager.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/NynjaSDKManager.java index a4db15d106..7678e9d28a 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/NynjaSDKManager.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/NynjaSDKManager.java @@ -66,7 +66,7 @@ public class NynjaSDKManager { } else { communicator = NynjaCommunicator.newInstance(); } - communicator.setDeviceId(Utils.getAndroidId(mContext)); + communicator.setDeviceId(Utils.getDeviceId(mContext));//)getAndroidId(mContext)); mAccountSDKModule = new AccountSDKModule(mContext, communicator); mConferenceSDKModule = new ConferenceSDKModule(context, communicator, NynjaApp.getComponent().dbHelper(), mPreferenceHelper.getSettingNotifications(), new StateDevice(false), 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 21600b1296..4b7d023f76 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 @@ -87,4 +87,6 @@ public interface ConferenceSDKListener { void showPurchaseDialog(boolean isModerator, final String message); void onPurchaseFinished(); + + void pickupCallWhileAnotherActiveCall(); } 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 b663a25c0b..6b735b34d2 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 @@ -61,6 +61,7 @@ import com.nynja.sdk.NYNCallParticipant; import com.nynja.sdk.NYNCallParticipantArray; import com.nynja.sdk.NYNCallRoomType; import com.nynja.sdk.NYNCallState; +import com.nynja.sdk.NYNCallsArray; import com.nynja.sdk.NYNConfMemberOption; import com.nynja.sdk.NYNError; import com.nynja.sdk.NynjaCallHistoryManager; @@ -140,7 +141,8 @@ public class ConferenceSDKModule extends BaseSDKModule { private boolean isSpeakerPhoneForced = false; private HashMap mConferenceRoomLimits = new HashMap<>(); private HashMap mConferenceWaitingRoomLNames = new HashMap<>(); - private HashMap mMyAcceptedElsewhereCalls = new HashMap<>(); + //private HashMap mMyAcceptedElsewhereCalls = new HashMap<>(); + private HashMap mMyAcceptedElsewhereCalls = new HashMap<>(); private int mLastPhoneCallState = TelephonyManager.CALL_STATE_IDLE; @@ -529,18 +531,20 @@ public class ConferenceSDKModule extends BaseSDKModule { } return true; } + public synchronized String callPickupText() { String text = ""; synchronized (mMyAcceptedElsewhereCalls) { for (String callId : mMyAcceptedElsewhereCalls.keySet()) { - NYNCall call = mCallManager.getCallById(callId); +// NYNCall call = mCallManager.getCallById(callId); + NYNCall call = mMyAcceptedElsewhereCalls.get(callId); if (call != null) { if (StringUtils.isNotEmpty(text)) { text += ", "; } if (!call.isConference()) { - String id = call.isOutgoing() ? call.callee() : call.caller(); // TODO: get local contact OR ROOM name by ID + //String id = call.isOutgoing() ? call.callee() : call.caller(); text += (call.getExternalInfo()); } } @@ -549,6 +553,85 @@ public class ConferenceSDKModule extends BaseSDKModule { return text; } + public synchronized HashMap pickupCallsInfo() { + HashMap pickupeCalls = new HashMap<>(); + synchronized (mMyAcceptedElsewhereCalls) { + for (String callId : mMyAcceptedElsewhereCalls.keySet()) { + NYNCall call = mCallManager.getCallById(callId); + if (call != null) { + pickupeCalls.put(callId, call.getExternalInfo()); + } + } + } + return pickupeCalls; + } + + public synchronized HashMap pickupCalls() { + return mMyAcceptedElsewhereCalls; + } + + public synchronized boolean callPickup(String callId) { + if (callId == null) { + Timber.w("callPickup(): try to pickup with callId=null!!!"); + return false; + } + if (hasCreatedActiveCall()) { + if (mActiveConference.mConference != null && + callId.contentEquals(mActiveConference.mConference.callId())) { + Timber.w("callPickup(): try to pickup the same already pickingUP call - ID=%s",callId); + return false; + } + if (mActiveConference.mConference != null) { + Timber.w("callPickup(): while has another active call!! callID=%s", + mActiveConference.mConference.callId()); + mHandler.postDelayed(() -> { + synchronized (mConferenceSDKListener) { + for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { + conferenceSDKListener.pickupCallWhileAnotherActiveCall(); + } + } + }, Consts.DELAY_50); + return false; + } + } + NYNCall call = mCallManager.pickupCall(Utils.generateUUID(), callId); + if (call != null) { + mConferenceDetails = new ConferenceDetails(getDeviceId(), callId); + mActiveConference = createActiveConference(call); + if (hasCreatedActiveCall()) { + initConferenceCall(false); + mActiveConference.isCallInProgress = true; + //startConferenceActivity(); + return true; + } + } + return false; + } + + public void loadPickupCalls() { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + if (!isLoggedIn()) return; + NYNCallsArray pickups = mCallManager.callsActiveElsewhere(); + if (pickups != null) { + if (pickups.size() == 0) return; + mMyAcceptedElsewhereCalls.clear(); + for (int index = 0; index< pickups.size(); index++) { + NYNCall call = pickups.get(index); + if (call != null && StringUtils.isNotEmpty(call.callId())) { + mMyAcceptedElsewhereCalls.put(call.callId(), call); + } + } + mHandler.postDelayed(() -> { + synchronized (mConferenceSDKListener) { + for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { + conferenceSDKListener.onConferenceStateChanged(mActiveConference); + } + } + }, Consts.DELAY_50); + } + },Consts.DELAY_200); + } + public boolean isCameraRunning() { if (!hasCreatedActiveCall()) return false; if (mActiveConference.mConference == null) return false; @@ -1192,7 +1275,8 @@ public class ConferenceSDKModule extends BaseSDKModule { if (!((hasCreatedActiveCall() && mActiveConference.mConference != null && mActiveConference.mConference.callId().contentEquals(callId)) || call.isStartedOnThisDevice())) { - mMyAcceptedElsewhereCalls.put(callId, roomId); + //mMyAcceptedElsewhereCalls.put(callId, roomId); + mMyAcceptedElsewhereCalls.put(callId, mCallManager.getCallById(callId)); } } if (!forceFireEvent) { @@ -1429,6 +1513,7 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public void receivedRingingCall(NYNCall call) { + Timber.d("receivedRingingCall(): call with \'CallId\'=\'%s", (call !=null ? call.callId(): "null")); onIncomingConference(call); } @@ -1439,6 +1524,7 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public void receivedAcceptedElsewhere(String conferenceId) { + Timber.d("receivedAcceptedElsewhere(): call with \'CallId\'=\'%s", conferenceId); onAcceptedElsewhereConference(conferenceId); } @@ -1469,6 +1555,7 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public void conferenceIdByLinkIdFinished(NYNError err, String requestId, String confId) { + Timber.d("conferenceIdByLinkIdFinished(): call with \'CallId\'=\'%s", confId); if (onJoinConferenceByLinkIdFailed(confId, err)) { return; } @@ -1477,17 +1564,20 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public void joinConferenceByLinkIdFinished(NYNError err, String requestId, String confId) { + Timber.d("joinConferenceByLinkIdFinished(): call with \'CallId\'=\'%s", confId); onJoinConferenceByLinkIdFinished(err, confId); } @Override public void receivedAcceptedCall(NYNCall call) { + Timber.d("receivedAcceptedCall(): call with \'CallId\'=\'%s", (call !=null ? call.callId(): "null")); onAcceptedCall(call); } @Override public void receivedCompletedCall(NYNCall call) { - String callId = call.callId(); + String callId = (call != null ? call.callId(): null); + Timber.d("receivedCompletedCall(): call with \'CallId\'=\'%s", callId); onCallEndedHandle(call, true); if (call != null && callId != null && hasCreatedActiveCall() && mActiveConference.mConference != null @@ -1539,6 +1629,11 @@ public class ConferenceSDKModule extends BaseSDKModule { onEscalateConferenceFinished(err, replaceRef, roomId, conferenceId); } + @Override + public void pickupCallFinished(String requestId, String callId, boolean success) { + onPickupCallFinished(requestId, callId, success); + } + @Override public void signalCallCompleted(NYNCall call) { onSignalCallCompleted(call); @@ -1549,6 +1644,12 @@ public class ConferenceSDKModule extends BaseSDKModule { onCallTimedOut(call); } + @Override + public void elsewhereCallFinished(NYNCall call) { + if (call == null) return; + onElsewhereCallFinished(call.callId()); + } + }; mCallManager.setListener(mCallManagerListener); } @@ -2987,10 +3088,13 @@ public class ConferenceSDKModule extends BaseSDKModule { createIncomingConference(iConference, true); } + private boolean isP2P(NYNCall call) { + return (call != null && !call.isConference()); + } + public synchronized boolean isP2P() { return (mActiveConference != null - && mActiveConference.mConference != null - && !mActiveConference.mConference.isConference() + && isP2P(mActiveConference.mConference) ); } @@ -3064,26 +3168,71 @@ public class ConferenceSDKModule extends BaseSDKModule { } private void onAcceptedElsewhereConference(String conferenceId) { - if (!hasCreatedActiveCall()) return; - if (mActiveConference.mConference == null) return; + if (StringUtils.isNotEmpty(conferenceId)) { + NYNCall call = mCallManager.getCallById(conferenceId); + if (call != null) { + if (isP2P(call)) { + //String roomId = (call.isConference() ? call.getChatRoomId() : + // (call.isOutgoing() ? call.callee() : call.caller())); + //mMyAcceptedElsewhereCalls.put(conferenceId, roomId); + mMyAcceptedElsewhereCalls.put(conferenceId, call); + for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { + conferenceSDKListener.onAcceptedElsewhereConference(conferenceId); + } + } + } + } - if (mActiveConference.mConference.callId().contentEquals(conferenceId)) { + if (mActiveConference != null && + mActiveConference.mConference != null && + mActiveConference.mConference.callId().contentEquals(conferenceId)) { mActiveConference.isRinging = false; if (mActiveConference.mConference.isOutgoing() && mActiveConference.isOutgoingCall) { // Nothing to do when is my outgoing call - may need check when allow multiple login } else { - if (isP2P()) { - mMyAcceptedElsewhereCalls.put(conferenceId, mActiveConference.mEndPointId); - for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { - conferenceSDKListener.onAcceptedElsewhereConference(conferenceId); - } - } + //if (isP2P() && !mActiveConference.isCallRinging()) return; onConferenceEnded(conferenceId); } } } + private synchronized void removeCallFromElsewhereCallsList(String callId, boolean fireEvent) { + if (mMyAcceptedElsewhereCalls.containsKey(callId)) { + //String roomId = (call.isConference() ? call.getChatRoomId() : + // (call.isOutgoing() ? call.callee() : call.caller())); + //mMyAcceptedElsewhereCalls.put(conferenceId, roomId); + mMyAcceptedElsewhereCalls.remove(callId); + if (!fireEvent) return; + for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { + conferenceSDKListener.onAcceptedElsewhereConference(callId); + } + } + } + + private void onPickupCallFinished(String requestId, String callId, boolean success) { + Timber.d("onPickupCallFinished(): callId=%s, result=%s", + callId, success ? "true" : "false"); + if (success) { + removeCallFromElsewhereCallsList(callId, false); + if (mActiveConference != null && + mActiveConference.mConference != null && + mActiveConference.mConference.callId().contentEquals(callId)) { + initConferenceCall(true); + mActiveConference.isCallInProgress = true; + mActiveConference.mConference.hangup(); + } + } else { + onConferenceFailedInternal("Pickup failed.", false); + } + } + + private void onElsewhereCallFinished(String callId) { + if (callId == null) return; + Timber.d("onElsewhereCallFinished(): callId=%s", callId); + removeCallFromElsewhereCallsList(callId, true); + } + private synchronized void onStateChangedForCall(NYNCall iConference) { onCallStateHandle(iConference, false); for (ConferenceSDKListener conferenceSDKListener : mConferenceSDKListener) { 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 c0b8a8a169..0c1edb32e6 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 @@ -31,9 +31,13 @@ import com.nynja.mobile.communicator.utils.navigation.NynjaRouter; import com.nynja.mobile.communicator.utils.navigation.Screen; import com.nynja.mobile.communicator.utils.navigation.navigators.HomeNavigator; import com.nynja.mobile.communicator.utils.navigation.navigators.NynjaNavigator; +import com.nynja.sdk.NYNCall; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.HashMap; + import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; @@ -275,6 +279,56 @@ public abstract class BasePresenter extends MvpPresenter< return mDataManager.getConferenceSDK().callPickupText(); } + public synchronized String callPickupsText() { + if (!hasCallForPickup()) return ""; + String text = ""; + HashMap myAcceptedElsewhereCalls = mDataManager.getConferenceSDK().pickupCalls(); + synchronized (myAcceptedElsewhereCalls) { + for (String callId : myAcceptedElsewhereCalls.keySet()) { +// NYNCall call = mCallManager.getCallById(callId); + NYNCall call = myAcceptedElsewhereCalls.get(callId); + if (call != null) { + if (StringUtils.isNotEmpty(text)) { + text += ", "; + } + if (!call.isConference()) { + text += (call.getExternalInfo()); + } + } + } + } + return text; + } + + public synchronized ArrayList callPickupsAvatar() { + ArrayList avatars = new ArrayList<>(); + HashMap myAcceptedElsewhereCalls = mDataManager.getConferenceSDK().pickupCalls(); + synchronized (myAcceptedElsewhereCalls) { + for (String callId : myAcceptedElsewhereCalls.keySet()) { +// NYNCall call = mCallManager.getCallById(callId); + NYNCall call = myAcceptedElsewhereCalls.get(callId); + if (call != null) { + String caller = call.caller(); + if (caller != null) { + ContactModel contact = mDataManager.getContactByChatId(caller); + if (contact != null) { + avatars.add(contact.avatar); + } + } + } + } + } + return avatars; + } + + public synchronized HashMap pickupCallsInfo() { + return mDataManager.getConferenceSDK().pickupCallsInfo(); + } + + public synchronized HashMap pickupCalls() { + return mDataManager.getConferenceSDK().pickupCalls(); + } + @Override public void showDefaultError(@NotNull Object data, @StringRes int errorRes) { getViewState().showDefaultServerError(errorRes); } 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 263ba8e86b..16a97299db 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 @@ -632,9 +632,9 @@ class MainActivityPresenter : ConferenceSDKPresenter() { } override fun conferenceEnded() { - if (attachedViews.size > 0) { + //if (attachedViews.size > 0) { viewState.onConferenceEnded() - } + //} invalidateWheelAfterCallStateChaged() clearIncomingCallNotification() } @@ -655,7 +655,7 @@ class MainActivityPresenter : ConferenceSDKPresenter() { invalidateWheelAfterCallStateChaged() } - override fun onConferenceStateChanged(activeConferenceCall: ActiveConferenceCall) { + override fun onConferenceStateChanged(activeConferenceCall: ActiveConferenceCall?) { if (attachedViews.size == 0) return viewState.onConferenceStateChanged(activeConferenceCall) } @@ -788,6 +788,10 @@ class MainActivityPresenter : ConferenceSDKPresenter() { } + override fun pickupCallWhileAnotherActiveCall() { + //if (attachedViews.size == 0) return + viewState.pickupCallWhileAnotherActiveCall() + } private fun showActiveCallDialog() { viewState.showActiveCallDialog() @@ -923,4 +927,14 @@ class MainActivityPresenter : ConferenceSDKPresenter() { } } } + + fun callPickup(callId: String?) { + if (mDataManager.conferenceSDK.callPickup(callId)) { + mRouter.navigateTo(NynjaNavigator.ACTIVE_CALL) + } + } + + fun loadPickupCalls() { + mDataManager.conferenceSDK.loadPickupCalls(); + } } 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 750054749c..604679b0e0 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 @@ -80,4 +80,6 @@ public interface MainActivityView extends JoinGroupView { void tryStartCall(boolean createNew, boolean isGroup, boolean isVideo, Parcelable prevModel); void showAlertMessage(int res); + + void pickupCallWhileAnotherActiveCall(); } 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 cf2788f8fb..0cae776017 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 @@ -6,6 +6,7 @@ import android.app.NotificationManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.media.AudioManager; import android.net.Uri; @@ -60,6 +61,7 @@ import com.nynja.mobile.communicator.ui.wheel.entity.actions.WheelMenuKey; import com.nynja.mobile.communicator.ui.wheel.entity.adapters.WheelChatAdapter; import com.nynja.mobile.communicator.ui.wheel.entity.items.BaseWheelItem; import com.nynja.mobile.communicator.ui.wheel.entity.items.WheelChatItem; +import com.nynja.mobile.communicator.utils.ActionSheetDialog; import com.nynja.mobile.communicator.utils.CallUtils; import com.nynja.mobile.communicator.utils.Consts; import com.nynja.mobile.communicator.utils.DefaultWheelClickListener; @@ -71,13 +73,16 @@ import com.nynja.mobile.communicator.utils.Utils; import com.nynja.mobile.communicator.utils.iap.InAppPurchaseManager; import com.nynja.mobile.communicator.utils.navigation.header.NynjaStatusHeaderView; import com.nynja.mobile.communicator.utils.navigation.navigators.HomeNavigator; +import com.nynja.sdk.NYNCall; import com.nynja.sdk.NYNCallState; import org.webrtc.SurfaceViewRenderer; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Set; import butterknife.BindView; import butterknife.OnClick; @@ -119,6 +124,7 @@ public class MainActivity extends BaseActivity implements MainActivityView, @BindView(R.id.call_pickup_name) TextView callPickupName; @BindView(R.id.call_pickup_count) TextView callPickupCount; @BindView(R.id.call_pickup_title_text) TextView callPickupHeaderText; + @BindView(R.id.call_pickup_photo) ImageView allPickupAvatar; @InjectPresenter MainActivityPresenter mPresenter; @@ -210,6 +216,7 @@ public class MainActivity extends BaseActivity implements MainActivityView, } catch (Exception ex) { Timber.e(ex); } + mPresenter.loadPickupCalls(); } @Override @@ -976,6 +983,15 @@ public class MainActivity extends BaseActivity implements MainActivityView, ); } + @Override + public void pickupCallWhileAnotherActiveCall() { + Dialog createdDialog = DialogFactory.createOkNoDialog(this, R.string.call_pickup_alert_while_another_call, + (dialog, which) -> { + }, null); + createdDialog.show(); + DialogFactory.changeMessageTextSize(createdDialog); + } + private void onCallStateChanged(ActiveConferenceCall activeConferenceCall) { if ((activeConferenceCall == null) || (!mPresenter.isConferenceActive()) || @@ -983,6 +999,7 @@ public class MainActivity extends BaseActivity implements MainActivityView, && !activeConferenceCall.isRinging && !activeConferenceCall.isWaiting())) { runOnUiThread(() -> { + onActiveCallStateChanged(null); onCallsStateChanged(); }); return; @@ -1005,15 +1022,19 @@ public class MainActivity extends BaseActivity implements MainActivityView, private void onActiveCallStateChanged(ActiveConferenceCall activeConferenceCall) { video.setVisibility(View.GONE); - if (activeConferenceCall != null && activeConferenceCall.isWaiting()) { - chatAudioLayout.setBackgroundResource(R.color.waiting_call_bg); - headerStatusText.setText(R.string.call_waiting_period); + if (activeConferenceCall != null) { + if (activeConferenceCall.isWaiting()) { + chatAudioLayout.setBackgroundResource(R.color.waiting_call_bg); + headerStatusText.setText(R.string.call_waiting_period); + } else { + chatAudioLayout.setBackgroundResource(R.color.active_call_bg); + } + hideCallPickupLayout(); + chatAudioLayout.setVisibility(View.VISIBLE); + mPresenter.requestUser(); } else { - chatAudioLayout.setBackgroundResource(R.color.active_call_bg); + chatAudioLayout.setVisibility(View.VISIBLE); } - callPickupLayout.setVisibility(View.GONE); - chatAudioLayout.setVisibility(View.VISIBLE); - mPresenter.requestUser(); //TODO: video feeds support in next features //if (!activeConferenceCall.mData.isOwnStreamActive || !activeConferenceCall.hasRemoteVideoTrack) { // video.setVisibility(View.GONE); @@ -1040,13 +1061,59 @@ public class MainActivity extends BaseActivity implements MainActivityView, onCallsStateChanged(); } + private void onClickCallPickup() { + final HashMap calls = mPresenter.pickupCallsInfo(); + ArrayList keys = new ArrayList(calls.keySet()); + String[] values = (new ArrayList<>(calls.values())).toArray(new String[0]); + //{"Ergun Y8", "Ergun Y2", "Ergun Y3", "Ergun Y4"};// + final Context context = this; +// DialogFactory.showActionSheetDialog(this, itemPosition -> { +// if (itemPosition < keys.size()) { +// String callId = keys.get(itemPosition); +// mPresenter.callPickup(callId); +// //Toast.makeText(context, ("Start Pickup with ID: "+ callId), Toast.LENGTH_LONG).show(); +// } +// }, values); + + DialogFactory.createContextPopupDialog(this, R.string.call_pickup_alert_title_text, values, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (i < keys.size()) { + String callId = keys.get(i); + mPresenter.callPickup(callId); + //Toast.makeText(context, ("Start Pickup with ID: "+ callId), Toast.LENGTH_LONG).show(); + } + + } + }).show(); + } + + private void hideCallPickupLayout() { + callPickupLayout.setOnClickListener(null); + callPickupLayout.setVisibility(View.GONE); + } + + private void onCallsStateChanged() { if (mPresenter.hasCallForPickup()) { + callPickupLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onClickCallPickup(); + } + }); //callPickupCount.setText(mPresenter.callPickupCount()); callPickupLayout.setVisibility(View.VISIBLE); - callPickupName.setText(mPresenter.callPickupText()); + callPickupName.setText(mPresenter.callPickupsText()); + ArrayList avatars = mPresenter.callPickupsAvatar(); + if (avatars.size() > 0) { + ImageUtils.loadAvatarImage(avatars.get(0), allPickupAvatar); + allPickupAvatar.setVisibility(View.VISIBLE); + } else { + allPickupAvatar.setVisibility(View.GONE); + } } else { - callPickupLayout.setVisibility(View.GONE); + hideCallPickupLayout(); } } 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 4354878781..a24e190b50 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 @@ -34,6 +34,7 @@ import com.nynja.mobile.communicator.R; import com.nynja.mobile.communicator.utils.iap.InAppPurchaseManager; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; +import java.util.ArrayList; import java.util.List; import timber.log.Timber; @@ -231,11 +232,17 @@ public class DialogFactory { public static AlertDialog createContextDialog(Activity activity, @ArrayRes List itemsRes, DialogInterface.OnClickListener onClickListener) { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, R.style.Nynja_Context_Dialog); String[] items = new String[itemsRes.size()]; for (int i = 0; i < itemsRes.size(); i++) { items[i] = activity.getString(itemsRes.get(i)); } + return createContextDialog(activity, items, onClickListener); + } + + public static AlertDialog createContextDialog(Activity activity, + String[] items, + DialogInterface.OnClickListener onClickListener) { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, R.style.Nynja_Context_Dialog); dialogBuilder.setItems(items, onClickListener); return dialogBuilder.create(); } @@ -243,16 +250,27 @@ public class DialogFactory { public static AlertDialog createContextPopupDialog(Activity activity, @ArrayRes List itemsRes, DialogInterface.OnClickListener onClickListener) { + String[] items = new String[itemsRes.size()]; + for (int i = 0; i < itemsRes.size(); i++) { + items[i] = (activity.getString(itemsRes.get(i))); + } + return createContextPopupDialog(activity, items, onClickListener); + } + + public static AlertDialog createContextPopupDialog(Activity activity, + String[] items, + DialogInterface.OnClickListener onClickListener) { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, R.style.Nynja_PopupMenu_AlertDialog); + final ArrayAdapter arrayAdapter = new ArrayAdapter(activity, R.layout.li_alert_popup_menu_item); - for (int i = 0; i < itemsRes.size(); i++) { - arrayAdapter.add(activity.getString(itemsRes.get(i))); - } + arrayAdapter.addAll(items); dialogBuilder.setAdapter(arrayAdapter, onClickListener); AlertDialog dialog = dialogBuilder.create(); ListView listView = dialog.getListView(); - listView.setDivider(new ColorDrawable(ContextCompat.getColor(activity, R.color.lite_grey))); + listView.setDivider(new ColorDrawable(ContextCompat.getColor(activity, R.color.grey))); + listView.setHeaderDividersEnabled(true); + listView.setFooterDividersEnabled(false); listView.setDividerHeight(1); @@ -279,6 +297,26 @@ public class DialogFactory { return dialog; } + public static AlertDialog createContextPopupDialog(Activity activity, int title, + String[] items, + DialogInterface.OnClickListener onClickListener) { + AlertDialog dialog = createContextPopupDialog(activity, items, onClickListener); + if (title > 0) { + dialog.setTitle(title); + } + return dialog; + } + + public static AlertDialog createContextPopupDialog(Activity activity, String title, + String[] items, + DialogInterface.OnClickListener onClickListener) { + AlertDialog dialog = createContextPopupDialog(activity, items, onClickListener); + if (StringUtils.isNotEmpty(title)) { + dialog.setTitle(title); + } + return dialog; + } + public static AlertDialog createContextPopupDialog(Activity activity, int title, int message, diff --git a/app/src/main/res/layout/partial_call_pickup.xml b/app/src/main/res/layout/partial_call_pickup.xml index 97bf17fd92..7697cd4028 100644 --- a/app/src/main/res/layout/partial_call_pickup.xml +++ b/app/src/main/res/layout/partial_call_pickup.xml @@ -23,7 +23,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" - android:layout_marginEnd="@dimen/margin_normal" android:layout_marginStart="@dimen/margin_normal" android:layout_weight="1" android:orientation="vertical"> @@ -48,9 +47,13 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" + android:ellipsize="end" + android:lines="1" + android:maxLines="1" + android:singleLine="true" android:textColor="@color/white" android:textSize="@dimen/text_size_normal" - tools:text="Shorty Design"/> + tools:text="Shorty Design" /> + tools:text="1"/> @@ -68,6 +71,7 @@ android:id="@+id/call_pickup_photo" android:layout_width="42dp" android:layout_height="42dp" + android:layout_marginStart="@dimen/margin_normal" android:layout_gravity="center" tools:ignore="ContentDescription" tools:src="@drawable/avatar_placeholder_circle" diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 4b8c7a2ef6..8da13b5fc2 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -1341,4 +1341,9 @@ To start your camera, you need to stop screen sharing first. Continue + + Call pickup + Choose call to pickup + You can\'t call when you are talking + diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index a93d6de9c0..cc31e962dc 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1340,4 +1340,9 @@ To start your camera, you need to stop screen sharing first. Continue + + Call pickup + Choose call to pickup + You can\'t call when you are talking + diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3fb29a0c69..58547c814f 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1340,4 +1340,9 @@ To start your camera, you need to stop screen sharing first. Continue + + Call pickup + Choose call to pickup + You can\'t call when you are talking + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4716478128..c2bf97f05a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1340,4 +1340,9 @@ To start your camera, you need to stop screen sharing first. Continue + + Call pickup + Choose call to pickup + You can\'t call when you are talking + diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 4716478128..c2bf97f05a 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1340,4 +1340,9 @@ To start your camera, you need to stop screen sharing first. Continue + + Call pickup + Choose call to pickup + You can\'t call when you are talking + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 38dfadc534..e43dd50e49 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -99,6 +99,6 @@ #A6ffffff #00000000 - #676BB9 + #F3AF22 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49e43700b7..7930de99a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1344,5 +1344,7 @@ Call pickup + Choose call to pickup + You can\'t call when you are talking -- GitLab From 5b5e24ceb934d8b887949ebf91c55a35a5a65c8f Mon Sep 17 00:00:00 2001 From: Ergyun Syuleyman Date: Mon, 1 Jun 2020 00:01:11 +0300 Subject: [PATCH 03/10] -Nynja black styled popup pickup dialog --- .../com/nynja/mobile/communicator/utils/DialogFactory.java | 4 +--- app/src/main/res/layout/li_alert_popup_menu_item.xml | 2 +- app/src/main/res/values/styles.xml | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) 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 a24e190b50..18e2aa172b 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 @@ -268,9 +268,7 @@ public class DialogFactory { dialogBuilder.setAdapter(arrayAdapter, onClickListener); AlertDialog dialog = dialogBuilder.create(); ListView listView = dialog.getListView(); - listView.setDivider(new ColorDrawable(ContextCompat.getColor(activity, R.color.grey))); - listView.setHeaderDividersEnabled(true); - listView.setFooterDividersEnabled(false); + listView.setDivider(new ColorDrawable(ContextCompat.getColor(activity, R.color.colorScheduleBackground))); listView.setDividerHeight(1); diff --git a/app/src/main/res/layout/li_alert_popup_menu_item.xml b/app/src/main/res/layout/li_alert_popup_menu_item.xml index 19e4bfb0d7..c118f92f87 100644 --- a/app/src/main/res/layout/li_alert_popup_menu_item.xml +++ b/app/src/main/res/layout/li_alert_popup_menu_item.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/dialog_popup_menu_item_selector" + android:background="@color/colorContextMenuSeparator" android:ellipsize="marquee" android:gravity="center" android:paddingBottom="@dimen/padding_small" diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 61669101ef..83cd4e10db 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -43,7 +43,7 @@