diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/db/DbHelper.java b/app/src/main/java/com/nynja/mobile/communicator/data/db/DbHelper.java index 8c739b6926dd91340c193843ef86f2fb016877af..2d8a9036b2ea173ec09a911b3c86fe851f4da06b 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/db/DbHelper.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/db/DbHelper.java @@ -794,6 +794,7 @@ public class DbHelper { } public void saveContact(Contact contact, Roster roster) { + if (!StringUtils.isNotEmpty(contact.phoneId)) return; BriteDatabase.Transaction transaction = mDb.newTransaction(); try { updateInsert(ContactsTable.TABLE_NAME, diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/ActiveCall.java b/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/ActiveCall.java index a8cfa6d4004a83f73db9269d22473344ecf6ffc2..9036ba9f497de3de543400360d00f9b1c2629bc0 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/ActiveCall.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/ActiveCall.java @@ -19,6 +19,7 @@ public class ActiveCall { public IVideoStream ownStream; public boolean isRemoteStreamActive; public IVideoStream remoteStream; + public boolean isRinging; public ActiveCall(ICall call, String endPointId) { mCall = call; diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/VoxService.java b/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/VoxService.java index 881160169c6a3610c440638d40cbcae6cd2c204d..e2e6691f3d279747575678410a31acc31058eea0 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/VoxService.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/voximplant/VoxService.java @@ -180,12 +180,14 @@ public class VoxService extends Service implements SensorEventListener { try { if (isProximityNear) { mWakeLock.acquire(); + } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) mWakeLock.release(1); else mWakeLock.release(); } + setSpeakerData(isProximityNear); } catch (Exception x) { Timber.e(x); } @@ -193,6 +195,15 @@ public class VoxService extends Service implements SensorEventListener { } } + private void setSpeakerData(boolean isProximityNear) { + VoxImplantModule implantModule = mDataManager.getVoxImlant(); + ActiveCall activeCall = implantModule.getActiveCall(); + if ((activeCall.isSpeakerOn && isProximityNear) + || (!activeCall.isSpeakerOn && !isProximityNear)){ + implantModule.setSpeaker(); + } + } + @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallPresenter.java index be22489618150c25d0e27e5a5ac5bab7bd28b3dd..d3594443be53b3d8b01a7c9adc50667e7801e233 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallPresenter.java +++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallPresenter.java @@ -15,7 +15,9 @@ public class CallPresenter extends VoxPresenter implements CallListene @Override protected void onFirstViewAttach() { super.onFirstViewAttach(); - getViewState().initStates(mDataManager.getVoxImlant().getActiveCall()); + ActiveCall activeCall = mDataManager.getVoxImlant().getActiveCall(); + getViewState().initStates(activeCall); + if (activeCall.isRinging) onCallRinging(); } public void switchCamera() { @@ -72,6 +74,7 @@ public class CallPresenter extends VoxPresenter implements CallListene } @Override public void onCallRinging() { + mDataManager.getVoxImlant().getActiveCall().isRinging = true; getViewState().onCallRinging(); } @@ -87,4 +90,8 @@ public class CallPresenter extends VoxPresenter implements CallListene @Override public void onStateChanged(ActiveCall activeCall) { getViewState().onCallStateChanged(activeCall); } + + public void onClickPortOut() { + //TODO StasS implement it + } } diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/HomePresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/HomePresenter.java index 69e3c70b687c531cb44fcc8cf8d89af49d57f701..46cc75fb4dcf9c55a54d053851e13fdd5157b394 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/HomePresenter.java +++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/HomePresenter.java @@ -216,11 +216,12 @@ public class HomePresenter extends VoxPresenter { getViewState().openActiveCall(); } - public void requestPhoto() { + public void requestUser() { String username = mDataManager.getVoxImlant().getAnotherUsername(); if (username != null) { Contact contact = mDataManager.getProfile().getRoster().getContactByVoxUser(username); getViewState().onAudioCallPhoto(contact.avatar); + getViewState().onAudioCallName(contact.getFullName()); } } @@ -244,4 +245,10 @@ public class HomePresenter extends VoxPresenter { @Override public void onCallFailed(String reason) { callEnded(); } + + @Override public void onCallRinging() { + mDataManager.getVoxImlant().getActiveCall().isRinging = true; + getViewState().onCallRinging(); + } + } diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/IncomeCallPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/IncomeCallPresenter.java index 78d06913c2222382754e84d75130a6209e5775c3..e6ac60055dfcebb0960f71a9083a4964e9d0d0e9 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/IncomeCallPresenter.java +++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/IncomeCallPresenter.java @@ -37,4 +37,8 @@ public class IncomeCallPresenter extends VoxPresenter { @Override public void activeCall(ActiveCall activeCall) { setCallWithUser(); } + + public void onPortOutClick() { + //TODO StasS implement it + } } diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/HomeView.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/HomeView.java index 2d8c5045317cd995f9dedacca5a8111e0269a8c2..0758cc3ac3b9f5c8a11b4cdbaa81ed7d0935a353 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/mvp/view/HomeView.java +++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/view/HomeView.java @@ -28,4 +28,8 @@ public interface HomeView extends ErrorMvpView{ void onCallStateChanged(ActiveCall activeCall); void openActiveCall(); + + void onCallRinging(); + + void onAudioCallName(String fullName); } diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/HomeActivity.java b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/HomeActivity.java index 1b357bf89add55550344803595e2708075a78cc3..cb2a9718204722e02c07e1aa0bcc9d889cb9ef97 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/HomeActivity.java +++ b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/HomeActivity.java @@ -87,7 +87,9 @@ public class HomeActivity extends BaseActivity implements HomeView, MenuButton.O @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; @InjectPresenter HomePresenter mPresenter; @@ -358,6 +360,9 @@ public class HomeActivity extends BaseActivity implements HomeView, MenuButton.O runOnUiThread(() -> { if (chatAudioLayout.getVisibility() == View.VISIBLE) { duration.setText(time); + if (!headerStatusText.getText().toString().equals(getString(R.string.text_return_call))) { + headerStatusText.setText(R.string.text_return_call); + } } }); } @@ -366,6 +371,9 @@ public class HomeActivity extends BaseActivity implements HomeView, MenuButton.O runOnUiThread(() -> { video.setVisibility(View.GONE); chatAudioLayout.setVisibility(View.GONE); + duration.setText(""); + headerStatusText.setText(R.string.call_connecting); + chatAudioName.setText(""); }); } @@ -409,7 +417,7 @@ public class HomeActivity extends BaseActivity implements HomeView, MenuButton.O if (!activeCall.isOwnStreamActive || !activeCall.isRemoteStreamActive) { video.setVisibility(View.GONE); chatAudioLayout.setVisibility(View.VISIBLE); - mPresenter.requestPhoto(); + mPresenter.requestUser(); if (activeCall.remoteStream != null) activeCall.remoteStream.removeVideoRenderer(video); } else { @@ -425,4 +433,13 @@ public class HomeActivity extends BaseActivity implements HomeView, MenuButton.O @Override public void openActiveCall() { startActivity(CallActivity.getLaunchIntent(this)); } + + @Override public void onCallRinging() { + headerStatusText.setText(R.string.call_ringing); + } + + @Override public void onAudioCallName(String fullName) { + chatAudioName.setText(fullName); + } + } 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 28a6c59c93da84c99c4a52507e43f5615d8f7875..f3bd57025b437e24bd5460219806fd3fcd6dea40 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 @@ -4,7 +4,9 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.constraint.ConstraintLayout; +import android.support.v7.widget.AppCompatCheckBox; import android.view.View; +import android.widget.CheckedTextView; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -20,6 +22,7 @@ import com.nynja.mobile.communicator.data.voximplant.VoxImplantModule; import com.nynja.mobile.communicator.mvp.presenters.CallPresenter; import com.nynja.mobile.communicator.mvp.view.CallView; import com.nynja.mobile.communicator.ui.base.BaseActivity; +import com.nynja.mobile.communicator.ui.views.CheckableImageView; import com.nynja.mobile.communicator.utils.DialogFactory; import com.voximplant.sdk.Voximplant; import com.voximplant.sdk.hardware.ICameraEventsListener; @@ -29,6 +32,7 @@ import com.voximplant.sdk.hardware.VideoQuality; import org.webrtc.SurfaceViewRenderer; import butterknife.BindView; +import butterknife.OnCheckedChanged; import butterknife.OnClick; import timber.log.Timber; @@ -43,7 +47,7 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent @BindView(R.id.video_outgoing_layout) ConstraintLayout videoOutgoingLayout; //video controls - @BindView(R.id.video_active_switch_audio) ImageView swithToAudio; + @BindView(R.id.video_active_switch_audio) ImageView switchToAudio; @BindView(R.id.video_active_hangup) ImageView videoHangUp; @BindView(R.id.video_active_switch_camera) ImageView videoSwithCam; @BindView(R.id.video_active_duration) TextView videoDuration; @@ -52,16 +56,13 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent //audio controls @BindView(R.id.audio_active_hangup) ImageView audioHangUp; - @BindView(R.id.audio_active_mute) ImageView audioMute; - @BindView(R.id.audio_call_outgoing_hangup) ImageView hangUp; - @BindView(R.id.audio_active_speaker) ImageView audioSpeaker; - @BindView(R.id.audio_active_duration) TextView audioDuration; + @BindView(R.id.audio_active_mute) CheckableImageView audioMute; + @BindView(R.id.audio_active_speaker) CheckableImageView audioSpeaker; + @BindView(R.id.audio_active_mute_text) TextView muteText; - @BindView(R.id.call_active_name) TextView name; - @BindView(R.id.call_active_status) TextView status; + @BindView(R.id.audio_active_name) TextView name; + @BindView(R.id.audio_active_duration) TextView status; @BindView(R.id.call_active_user_photo) ImageView userPhoto; - @BindView(R.id.audio_active_speaker_image) ImageView speakerImage; - @BindView(R.id.audio_active_mute_image) ImageView muteImage; @InjectPresenter CallPresenter mPresenter; @@ -79,9 +80,14 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_call); + audioMute.setOnCheckedChangeListener((buttonView, isChecked) -> setMuteText(isChecked)); } - @OnClick({R.id.audio_active_hangup, R.id.video_active_hangup, R.id.audio_call_outgoing_hangup, R.id.video_outgoing_hangup}) + private void setMuteText(boolean isChecked) { + muteText.setText(isChecked ? R.string.mute : R.string.unmute); + } + + @OnClick({R.id.audio_active_hangup, R.id.video_active_hangup, R.id.video_outgoing_hangup}) void hangUp() { mPresenter.hangUp(); } @@ -106,6 +112,12 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent mPresenter.openChat(mContact); } + @OnClick({R.id.audio_active_port_out, R.id.audio_active_port_out_text}) + void clickPortOut() { + Toast.makeText(this, R.string.this_feature_is_currently_unavailable, Toast.LENGTH_SHORT).show(); + mPresenter.onClickPortOut(); + } + @Override public void onCameraSwitch() { mCameraType = (mCameraType == 0) ? 1 : 0; mCameraManager.setCamera(mCameraType, DEFAULT_VIDEO_QUALITY); @@ -127,7 +139,6 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent @Override public void onCallConnected(ActiveCall activeCall) { runOnUiThread(() -> { - hangUp.setVisibility(View.GONE); if (activeCall.mCall.isVideoEnabled()) { videoCall(activeCall); status.setVisibility(View.GONE); @@ -193,13 +204,8 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent videoViewLayout.setVisibility(View.GONE); videoIncomeLayout.setVisibility(View.GONE); videoOutgoingLayout.setVisibility(View.GONE); - - if (activeCall.isCallInProgress) { - audioIncomeLayout.setVisibility(View.VISIBLE); - name.setVisibility(View.VISIBLE); - } else { - hangUp.setVisibility(View.VISIBLE); - } + audioIncomeLayout.setVisibility(View.VISIBLE); + name.setVisibility(View.VISIBLE); }); } @@ -211,6 +217,7 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent videoIncomeLayout.setVisibility(View.VISIBLE); videoOutgoingLayout.setVisibility(View.GONE); name.setVisibility(View.GONE); + audioIncomeLayout.setVisibility(View.GONE); videoViewLayout.setVisibility(View.VISIBLE); videoRemote.setVisibility(View.VISIBLE); } else { @@ -235,8 +242,8 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent } } mPresenter.loadUser(activeCall); - startCall(); + startCall(); initCall(activeCall); } @@ -247,8 +254,9 @@ public class CallActivity extends BaseActivity implements CallView, ICameraEvent private void initCall(ActiveCall activeCall) { if (!activeCall.isOwnStreamActive || !activeCall.isRemoteStreamActive) { audioCall(activeCall); - muteImage.setVisibility(activeCall.isMuted ? View.VISIBLE : View.GONE); - speakerImage.setVisibility(activeCall.isSpeakerOn ? View.VISIBLE : View.GONE); + audioSpeaker.setChecked(activeCall.isSpeakerOn); + audioMute.setChecked(activeCall.isMuted); + setMuteText(activeCall.isMuted); if (activeCall.remoteStream != null) activeCall.remoteStream.removeVideoRenderer(videoRemote); if (activeCall.ownStream != null) diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/IncomeCallActivity.java b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/IncomeCallActivity.java index e4d232d97abfcf2be090f2f1c0289cead22a8f64..5e0faa151ebb0ac64512666c612a181e4f8ef3b6 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/IncomeCallActivity.java +++ b/app/src/main/java/com/nynja/mobile/communicator/ui/activities/calls/IncomeCallActivity.java @@ -8,9 +8,11 @@ import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.os.PowerManager; +import android.support.v7.app.AppCompatDelegate; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import com.arellomobile.mvp.presenter.InjectPresenter; import com.bumptech.glide.Glide; @@ -57,13 +59,14 @@ public class IncomeCallActivity extends BaseActivity implements IncomeCallView { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); setContentView(R.layout.activity_voice_call); PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); if (pm != null) mWl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, getClass().getSimpleName()); } - @OnClick(R.id.voice_call_income_accept) void answerVoiceClick(){ + @OnClick(R.id.voice_call_income_accept) void answerVoiceClick() { mPresenter.answerCall(false); } @@ -153,4 +156,11 @@ public class IncomeCallActivity extends BaseActivity implements IncomeCallView { private void stopSound() { player.stop(); } + + + @OnClick({R.id.voice_call_income_port_out, R.id.voice_call_income_port_out_text}) + void portOutClick() { + Toast.makeText(this, R.string.this_feature_is_currently_unavailable, Toast.LENGTH_SHORT).show(); + // mPresenter.onPortOutClick(); + } } diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/AddContactByPhoneFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/AddContactByPhoneFragment.java index c121c0aa30c8559c687438dd56f7048205d93dce..c4e28cd4b3562e1a5e98af5b21c6253807c074f0 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/AddContactByPhoneFragment.java +++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/AddContactByPhoneFragment.java @@ -50,7 +50,7 @@ public class AddContactByPhoneFragment extends BaseFragment implements AddContac @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragmnet_add_contact_by_phone, container, false); + return inflater.inflate(R.layout.fragment_add_contact_by_phone, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/CountryPickerFragment.java b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/CountryPickerFragment.java index 05b880038561799bd166aaa4fc0e5882e2cd269f..a43664927218f4e046f499cd954e8167d08e28aa 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/CountryPickerFragment.java +++ b/app/src/main/java/com/nynja/mobile/communicator/ui/fragments/contacts/CountryPickerFragment.java @@ -47,7 +47,7 @@ public class CountryPickerFragment extends BaseFragment implements CountryPicker @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragmnet_country_picker, container, false); + return inflater.inflate(R.layout.fragment_country_picker, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { diff --git a/app/src/main/java/com/nynja/mobile/communicator/ui/views/CheckableImageView.java b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CheckableImageView.java new file mode 100644 index 0000000000000000000000000000000000000000..4f1afea9ea1cbd52d131226dc7e6420b7637b612 --- /dev/null +++ b/app/src/main/java/com/nynja/mobile/communicator/ui/views/CheckableImageView.java @@ -0,0 +1,193 @@ +package com.nynja.mobile.communicator.ui.views; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.widget.Checkable; + +/** + * Created by Stas Safyanov on 06.11.17. + */ + +public class CheckableImageView extends android.support.v7.widget.AppCompatImageView + implements Checkable { + +// private boolean mChecked; +// +// private static final int[] CHECKED_STATE_SET = { +// android.R.attr.state_checked +// }; +// +// public CheckableImageView(Context context, AttributeSet attrs) { +// super(context, attrs); +// } +// +// @Override +// public int[] onCreateDrawableState(int extraSpace) { +// final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); +// if (isChecked()) { +// mergeDrawableStates(drawableState, CHECKED_STATE_SET); +// } +// return drawableState; +// } +// +// public void toggle() { +// setChecked(!mChecked); +// } +// +// public boolean isChecked() { +// return mChecked; +// } +// +// public void setChecked(boolean checked) { +// if (mChecked != checked) { +// mChecked = checked; +// refreshDrawableState(); +// } +// } + + private static final int[] checkedStateSet = { android.R.attr.state_checked }; + + private boolean mChecked = false; + private OnCheckedChangeListener mOnCheckedChangeListener; + + private boolean mBroadcasting; + + public CheckableImageView(Context context) { + super(context); + } + + public CheckableImageView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CheckableImageView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public boolean isChecked() { + return mChecked; + } + + @Override + public boolean performClick() { + toggle(); + return super.performClick(); + } + + @Override + public void toggle() { + setChecked(!mChecked); + } + + @Override + public int[] onCreateDrawableState(int extraSpace) { + final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); + if (isChecked()) { + mergeDrawableStates(drawableState, checkedStateSet); + } + return drawableState; + } + + @Override + public void setChecked(boolean checked) { + if (mChecked != checked) { + mChecked = checked; + refreshDrawableState(); + + // Avoid infinite recursions if setChecked() is called from a listener + if (mBroadcasting) { + return; + } + + mBroadcasting = true; + if (mOnCheckedChangeListener != null) { + mOnCheckedChangeListener.onCheckedChanged(this, mChecked); + } + + mBroadcasting = false; + } + } + + /** + * Register a callback to be invoked when the checked state of this button + * changes. + * + * @param listener the callback to call on checked state change + */ + public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { + mOnCheckedChangeListener = listener; + } + + /** + * Interface definition for a callback to be invoked when the checked state + * of a compound button changed. + */ + public static interface OnCheckedChangeListener { + /** + * Called when the checked state of a compound button has changed. + * + * @param buttonView The compound button view whose state has changed. + * @param isChecked The new checked state of buttonView. + */ + void onCheckedChanged(CheckableImageView buttonView, boolean isChecked); + } + + static class SavedState extends BaseSavedState { + boolean checked; + + SavedState(Parcelable superState) { + super(superState); + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + checked = (Boolean) in.readValue(null); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeValue(checked); + } + + @Override + public String toString() { + return "CheckableImageView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " checked=" + checked + "}"; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.checked = isChecked(); + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + + super.onRestoreInstanceState(ss.getSuperState()); + setChecked(ss.checked); + requestLayout(); + } +} diff --git a/app/src/main/res/drawable-hdpi/icons_voice_call_ic_unmute_voice_call.png b/app/src/main/res/drawable-hdpi/icons_voice_call_ic_unmute_voice_call.png new file mode 100644 index 0000000000000000000000000000000000000000..d81e36c096e9b6251b3d01b038d13eadd1161014 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icons_voice_call_ic_unmute_voice_call.png differ diff --git a/app/src/main/res/drawable-mdpi/icons_voice_call_ic_unmute_voice_call.png b/app/src/main/res/drawable-mdpi/icons_voice_call_ic_unmute_voice_call.png new file mode 100644 index 0000000000000000000000000000000000000000..cce9f10912d064cb13b068f8c2e9ab78e66494a1 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icons_voice_call_ic_unmute_voice_call.png differ diff --git a/app/src/main/res/drawable-xhdpi/icons_voice_call_ic_unmute_voice_call.png b/app/src/main/res/drawable-xhdpi/icons_voice_call_ic_unmute_voice_call.png new file mode 100644 index 0000000000000000000000000000000000000000..a7729b7f71999f406f65bae7fed4507124cdbfbe Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icons_voice_call_ic_unmute_voice_call.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icons_voice_call_ic_unmute_voice_call.png b/app/src/main/res/drawable-xxhdpi/icons_voice_call_ic_unmute_voice_call.png new file mode 100644 index 0000000000000000000000000000000000000000..f44277ace0e77527ffed79299925ff659006d2e4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icons_voice_call_ic_unmute_voice_call.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icons_voice_call_ic_unmute_voice_call.png b/app/src/main/res/drawable-xxxhdpi/icons_voice_call_ic_unmute_voice_call.png new file mode 100644 index 0000000000000000000000000000000000000000..d4a46e20b645f706d2b79b581b852584d8543119 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icons_voice_call_ic_unmute_voice_call.png differ diff --git a/app/src/main/res/drawable/button_accept.xml b/app/src/main/res/drawable/button_accept.xml new file mode 100644 index 0000000000000000000000000000000000000000..f700219c1c2a896d61029568ad4ce30aa6cd4c9a --- /dev/null +++ b/app/src/main/res/drawable/button_accept.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_hangup.xml b/app/src/main/res/drawable/button_hangup.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe6c2ba817da6bcb3efbfa56fed554b687ded837 --- /dev/null +++ b/app/src/main/res/drawable/button_hangup.xml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/photo_circle_shape.xml b/app/src/main/res/drawable/photo_circle_shape.xml index c33537d0003cbe1b591d0a7b60d81ca875c176b4..6222cb94117b6bbc296bb215cef3276cecc7c806 100644 --- a/app/src/main/res/drawable/photo_circle_shape.xml +++ b/app/src/main/res/drawable/photo_circle_shape.xml @@ -11,5 +11,9 @@ + android:top="16dp" + android:bottom="16dp" + android:left="16dp" + android:right="16dp" + android:gravity="center"/> \ No newline at end of file diff --git a/app/src/main/res/drawable/speaker_selector.xml b/app/src/main/res/drawable/speaker_selector.xml new file mode 100644 index 0000000000000000000000000000000000000000..e0cb96c352f72e086b3f720eff239ce1b7e0adfc --- /dev/null +++ b/app/src/main/res/drawable/speaker_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/v_chat.xml b/app/src/main/res/drawable/v_chat.xml new file mode 100644 index 0000000000000000000000000000000000000000..61f5936aa4caa8157d2fe4c4c516f8794acbc5c4 --- /dev/null +++ b/app/src/main/res/drawable/v_chat.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/app/src/main/res/drawable/v_hangup_call.xml b/app/src/main/res/drawable/v_hangup_call.xml new file mode 100644 index 0000000000000000000000000000000000000000..54d909f33ecb9275f39474cd1d640a0eb747f0f9 --- /dev/null +++ b/app/src/main/res/drawable/v_hangup_call.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/v_port_out.xml b/app/src/main/res/drawable/v_port_out.xml new file mode 100644 index 0000000000000000000000000000000000000000..d1dc21b4ba233ed7344033f00a08edee226b5ad8 --- /dev/null +++ b/app/src/main/res/drawable/v_port_out.xml @@ -0,0 +1,19 @@ + + + + diff --git a/app/src/main/res/drawable/v_ring_call.xml b/app/src/main/res/drawable/v_ring_call.xml new file mode 100644 index 0000000000000000000000000000000000000000..2bcab8b992e02c210f6b0be11351ceac5c54ef5c --- /dev/null +++ b/app/src/main/res/drawable/v_ring_call.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/v_speaker_off.xml b/app/src/main/res/drawable/v_speaker_off.xml new file mode 100644 index 0000000000000000000000000000000000000000..5cb820a654b0768641df6b2d2ba3e651766a3eb0 --- /dev/null +++ b/app/src/main/res/drawable/v_speaker_off.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/v_speaker_on.xml b/app/src/main/res/drawable/v_speaker_on.xml new file mode 100644 index 0000000000000000000000000000000000000000..afc77cf9067d646f23d5c0f28486b299c45920d9 --- /dev/null +++ b/app/src/main/res/drawable/v_speaker_on.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/drawable/v_voice_call_mute.xml b/app/src/main/res/drawable/v_voice_call_mute.xml new file mode 100644 index 0000000000000000000000000000000000000000..07c3559cb07f44172c1abb2cf7605b6998874254 --- /dev/null +++ b/app/src/main/res/drawable/v_voice_call_mute.xml @@ -0,0 +1,18 @@ + + + + diff --git a/app/src/main/res/drawable/v_voice_call_unmute.xml b/app/src/main/res/drawable/v_voice_call_unmute.xml new file mode 100644 index 0000000000000000000000000000000000000000..5678a8a79f6d20dc00c43c69bd40f08ead1950c5 --- /dev/null +++ b/app/src/main/res/drawable/v_voice_call_unmute.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/voice_selector.xml b/app/src/main/res/drawable/voice_selector.xml new file mode 100644 index 0000000000000000000000000000000000000000..990339f813dc36f14cc096ea1de24b686765e55c --- /dev/null +++ b/app/src/main/res/drawable/voice_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_call.xml b/app/src/main/res/layout/activity_call.xml index 84e790ae3e1e2300476d0b9b891bd2050e050473..621c4bfc29ad9a48aefbc6c476df416a018889eb 100644 --- a/app/src/main/res/layout/activity_call.xml +++ b/app/src/main/res/layout/activity_call.xml @@ -1,43 +1,52 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + tools:src="@drawable/avatar_placeholder"/> - + android:layout_height="100dp" + android:layout_gravity="bottom" + app:layout_constraintBottom_toBottomOf="@+id/call_active_user_photo"/> - + + + + + + + + + + + + + + + + + + + + + + + app:layout_constraintTop_toTopOf="parent"/> + app:layout_constraintTop_toTopOf="parent"/> @@ -76,7 +85,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent"/> + app:layout_constraintTop_toTopOf="parent"/> + app:layout_constraintTop_toTopOf="parent"/> - + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_voice_call.xml b/app/src/main/res/layout/activity_voice_call.xml index d869b98ff6030c9d55a240524e83e8667c4eba81..61c56abfa1af24672bc257feb421143b42154e13 100644 --- a/app/src/main/res/layout/activity_voice_call.xml +++ b/app/src/main/res/layout/activity_voice_call.xml @@ -9,34 +9,20 @@ android:id="@+id/imageView" android:layout_width="0dp" android:layout_height="0dp" - android:src="@drawable/contact_placeholder" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintLeft_toLeftOf="parent" - app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - - + tools:src="@drawable/avatar_placeholder"/> - + - - + app:srcCompat="@drawable/photo_circle_shape"/> @@ -177,26 +177,26 @@ android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:srcCompat="@drawable/v_right_arrow_white" app:layout_constraintBottom_toBottomOf="@+id/f_create_group_tv_name" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toTopOf="@+id/textView3"/> + app:layout_constraintTop_toTopOf="@+id/textView3" + app:srcCompat="@drawable/v_right_arrow_white"/> + app:layout_constraintTop_toTopOf="@+id/textView5" + app:srcCompat="@drawable/v_right_arrow_white"/> + app:srcCompat="@drawable/v_right_arrow_white"/> \ No newline at end of file diff --git a/app/src/main/res/layout/partial_audio_active.xml b/app/src/main/res/layout/partial_audio_active.xml index 4a3099681dd1fba2cdf282a024bcfb4c5cff78e2..44579036e89104989951f25b4b65e2136eca64ab 100644 --- a/app/src/main/res/layout/partial_audio_active.xml +++ b/app/src/main/res/layout/partial_audio_active.xml @@ -1,95 +1,148 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + tools:text="Name"/> + tools:text="Voice call - 00:35"/> - + + android:checked="true" + app:layout_constraintBottom_toTopOf="@+id/audio_active_mute_text" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toEndOf="@+id/audio_active_port_out" + app:layout_constraintTop_toBottomOf="@+id/audio_active_duration" + app:layout_constraintVertical_bias="0.8" + app:layout_constraintVertical_chainStyle="packed" + app:srcCompat="@drawable/voice_selector"/> + android:id="@+id/audio_active_port_out" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@+id/audio_active_port_out_text" + app:layout_constraintEnd_toStartOf="@+id/audio_active_mute" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/audio_active_duration" + app:layout_constraintVertical_bias="0.8" + app:layout_constraintVertical_chainStyle="packed" + app:srcCompat="@drawable/v_port_out"/> - + + + app:layout_constraintEnd_toStartOf="@+id/audio_active_hangup" + app:layout_constraintHorizontal_chainStyle="spread" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/audio_active_speaker"/> + android:id="@+id/audio_active_hangup" + android:layout_width="68dp" + android:layout_height="68dp" + android:layout_marginBottom="16dp" + android:scaleType="fitCenter" + app:srcCompat="@drawable/button_hangup" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"/> + app:layout_constraintBottom_toTopOf="@+id/audio_active_text_text" + app:layout_constraintEnd_toEndOf="@+id/audio_active_text_text" + app:layout_constraintStart_toStartOf="@+id/audio_active_text_text" + app:layout_constraintTop_toTopOf="@+id/audio_active_hangup" + app:layout_constraintVertical_chainStyle="packed" + app:srcCompat="@drawable/v_chat"/> - + android:fontFamily="@font/avenir_roman" + android:text="@string/return.to.chat" + android:textColor="@color/white" + android:textSize="12sp" + app:layout_constraintBottom_toBottomOf="@+id/audio_active_hangup" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/audio_active_hangup" + app:layout_constraintTop_toBottomOf="@+id/audio_active_text"/> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/partial_chat_audio.xml b/app/src/main/res/layout/partial_chat_audio.xml index b22f1b6fff2340021dd61b2e6a8fd8a6847f6404..af0ef85a0e0f25cf4037c1063a28ec29a04aa6fd 100644 --- a/app/src/main/res/layout/partial_chat_audio.xml +++ b/app/src/main/res/layout/partial_chat_audio.xml @@ -33,7 +33,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/avenir_roman" - android:text="@string/text.return_call" + android:text="@string/call.connecting" android:textColor="@color/white" /> @@ -58,8 +57,7 @@ android:layout_height="wrap_content" android:fontFamily="@font/avenir_roman" android:textColor="@color/white" - android:textSize="14sp" - tools:text="01:11" /> + android:textSize="14sp"/> diff --git a/app/src/main/res/layout/partial_voice_income.xml b/app/src/main/res/layout/partial_voice_income.xml index d2b21fd5ca16447dcaab24cded5414407cadaa7a..579b4ada21b58047b18dfb1b6dce9e750daf9168 100644 --- a/app/src/main/res/layout/partial_voice_income.xml +++ b/app/src/main/res/layout/partial_voice_income.xml @@ -1,47 +1,77 @@ - + - + + + + + + app:layout_constraintRight_toLeftOf="@+id/voice_call_income_accept"/> - + app:layout_constraintRight_toRightOf="parent"/> - + app:layout_constraintBottom_toTopOf="@+id/voice_call_income_port_out_text" + app:layout_constraintEnd_toEndOf="@+id/voice_call_income_port_out_text" + app:layout_constraintStart_toStartOf="@+id/voice_call_income_port_out_text" + app:srcCompat="@drawable/v_port_out"/> + android:layout_marginBottom="26dp" + android:fontFamily="@font/avenir_roman" + android:text="@string/port.out.to.phone" + android:textColor="@color/white" + android:textSize="12sp" + app:layout_constraintBottom_toTopOf="@+id/voice_call_income_decline" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"/> \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index d3ee592579ff0e37bfd62ee17967eb8ecea92e74..51f1ad8b6f7411beec099ccea5268e4550d082da 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -118,4 +118,7 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 721f070262da3da6d8b0efe0e5813e8abef845d7..18cfd9325367e80260ee6b7828f5b9e7518ba690 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -125,10 +125,10 @@ Switch Camera Accept Decline - Incoming voice call… - Incoming video call… + Incoming Voice Call… + Incoming Video Call… Voice call - %1$s - Call connecting… + Connecting… Ringing… @@ -212,4 +212,12 @@ %1$s has created the group %2$s You + + Port Out to Phone + Mute + Unmute + Speakerphone + Return to Chat + This feature is currently unavailable +