mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 12:09:45 +01:00
Merge pull request #1655 from nextcloud/bugfix/1582/rewriteToggleChatEtc
Bugfix/1582/rewrite toggle chat etc
This commit is contained in:
commit
d602bf3dfe
@ -41,7 +41,7 @@ import com.bluelinelabs.logansquare.LoganSquare
|
|||||||
import com.google.firebase.messaging.FirebaseMessagingService
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
import com.google.firebase.messaging.RemoteMessage
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.activities.MagicCallActivity
|
import com.nextcloud.talk.activities.CallNotificationActivity
|
||||||
import com.nextcloud.talk.api.NcApi
|
import com.nextcloud.talk.api.NcApi
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||||
@ -178,7 +178,7 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (type == "call") {
|
} else if (type == "call") {
|
||||||
val fullScreenIntent = Intent(applicationContext, MagicCallActivity::class.java)
|
val fullScreenIntent = Intent(applicationContext, CallNotificationActivity::class.java)
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_ID, decryptedPushMessage!!.id)
|
bundle.putString(BundleKeys.KEY_ROOM_ID, decryptedPushMessage!!.id)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification!!.userEntity)
|
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification!!.userEntity)
|
||||||
|
@ -123,9 +123,24 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.MagicCallActivity"
|
android:name=".activities.CallActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:theme="@style/AppTheme.CallLauncher"
|
||||||
android:launchMode="singleTask" />
|
android:supportsPictureInPicture="true"
|
||||||
|
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:taskAffinity=".call"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:showOnLockScreen="true"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".activities.CallNotificationActivity"
|
||||||
|
android:theme="@style/AppTheme.CallLauncher"
|
||||||
|
android:supportsPictureInPicture="true"
|
||||||
|
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:taskAffinity=".call"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:showOnLockScreen="true" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.FullScreenImageActivity"
|
android:name=".activities.FullScreenImageActivity"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,131 @@
|
|||||||
|
package com.nextcloud.talk.activities;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AppOpsManager;
|
||||||
|
import android.app.KeyguardManager;
|
||||||
|
import android.app.PictureInPictureParams;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Rational;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import com.nextcloud.talk.BuildConfig;
|
||||||
|
|
||||||
|
public abstract class CallBaseActivity extends BaseActivity {
|
||||||
|
|
||||||
|
public static final String TAG = "CallBaseActivity";
|
||||||
|
|
||||||
|
public PictureInPictureParams.Builder mPictureInPictureParamsBuilder;
|
||||||
|
public Boolean isInPipMode = false;
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
dismissKeyguard();
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
if (isGreaterEqualOreo() && isPipModePossible()) {
|
||||||
|
mPictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hideNavigationIfNoPipAvailable(){
|
||||||
|
if (!isPipModePossible()) {
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||||
|
suppressFitsSystemWindows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dismissKeyguard() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||||
|
setShowWhenLocked(true);
|
||||||
|
setTurnScreenOn(true);
|
||||||
|
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
|
||||||
|
keyguardManager.requestDismissKeyguard(this, null);
|
||||||
|
} else {
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableKeyguard() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||||
|
setShowWhenLocked(false);
|
||||||
|
} else {
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (isInPipMode) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (isPipModePossible()) {
|
||||||
|
enterPipMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onUserLeaveHint() {
|
||||||
|
enterPipMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void enterPipMode() {
|
||||||
|
enableKeyguard();
|
||||||
|
if (isGreaterEqualOreo() && isPipModePossible()) {
|
||||||
|
Rational pipRatio = new Rational(300, 500);
|
||||||
|
mPictureInPictureParamsBuilder.setAspectRatio(pipRatio);
|
||||||
|
enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
|
||||||
|
} else {
|
||||||
|
// we don't support other solutions than PIP to have a call in the background.
|
||||||
|
// If PIP is not available the call is ended when user presses the home button.
|
||||||
|
Log.d(TAG, "Activity was finished because PIP is not available.");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isPipModePossible() {
|
||||||
|
if (isGreaterEqualOreo()) {
|
||||||
|
boolean deviceHasPipFeature = getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
|
||||||
|
|
||||||
|
AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
|
||||||
|
boolean isPipFeatureGranted = appOpsManager.checkOpNoThrow(
|
||||||
|
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
|
||||||
|
android.os.Process.myUid(),
|
||||||
|
BuildConfig.APPLICATION_ID) == AppOpsManager.MODE_ALLOWED;
|
||||||
|
return deviceHasPipFeature && isPipFeatureGranted;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isGreaterEqualOreo(){
|
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void updateUiForPipMode();
|
||||||
|
|
||||||
|
abstract void updateUiForNormalMode();
|
||||||
|
|
||||||
|
abstract void suppressFitsSystemWindows();
|
||||||
|
}
|
@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.activities;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.media.AudioAttributes;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.bluelinelabs.logansquare.LoganSquare;
|
||||||
|
import com.facebook.common.executors.UiThreadImmediateExecutorService;
|
||||||
|
import com.facebook.common.references.CloseableReference;
|
||||||
|
import com.facebook.datasource.DataSource;
|
||||||
|
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||||
|
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||||
|
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||||
|
import com.facebook.imagepipeline.image.CloseableImage;
|
||||||
|
import com.facebook.imagepipeline.request.ImageRequest;
|
||||||
|
import com.nextcloud.talk.R;
|
||||||
|
import com.nextcloud.talk.api.NcApi;
|
||||||
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
|
import com.nextcloud.talk.databinding.CallNotificationActivityBinding;
|
||||||
|
import com.nextcloud.talk.events.CallNotificationClick;
|
||||||
|
import com.nextcloud.talk.models.RingtoneSettings;
|
||||||
|
import com.nextcloud.talk.models.database.CapabilitiesUtil;
|
||||||
|
import com.nextcloud.talk.models.database.UserEntity;
|
||||||
|
import com.nextcloud.talk.models.json.conversations.Conversation;
|
||||||
|
import com.nextcloud.talk.models.json.conversations.RoomOverall;
|
||||||
|
import com.nextcloud.talk.models.json.participants.Participant;
|
||||||
|
import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
|
||||||
|
import com.nextcloud.talk.utils.ApiUtils;
|
||||||
|
import com.nextcloud.talk.utils.DisplayUtils;
|
||||||
|
import com.nextcloud.talk.utils.DoNotDisturbUtils;
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||||
|
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import autodagger.AutoInjector;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import io.reactivex.Observer;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import okhttp3.Cache;
|
||||||
|
|
||||||
|
@SuppressLint("LongLogTag")
|
||||||
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
|
public class CallNotificationActivity extends CallBaseActivity {
|
||||||
|
|
||||||
|
public static final String TAG = "CallNotificationActivity";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
NcApi ncApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AppPreferences appPreferences;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Cache cache;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
EventBus eventBus;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
private List<Disposable> disposablesList = new ArrayList<>();
|
||||||
|
private Bundle originalBundle;
|
||||||
|
private String roomId;
|
||||||
|
private UserEntity userBeingCalled;
|
||||||
|
private String credentials;
|
||||||
|
private Conversation currentConversation;
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
private boolean leavingScreen = false;
|
||||||
|
private Handler handler;
|
||||||
|
private CallNotificationActivityBinding binding;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
Log.d(TAG, "onCreate");
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
||||||
|
|
||||||
|
binding = CallNotificationActivityBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
hideNavigationIfNoPipAvailable();
|
||||||
|
|
||||||
|
eventBus.post(new CallNotificationClick());
|
||||||
|
|
||||||
|
Bundle extras = getIntent().getExtras();
|
||||||
|
this.roomId = extras.getString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), "");
|
||||||
|
this.currentConversation = Parcels.unwrap(extras.getParcelable(BundleKeys.INSTANCE.getKEY_ROOM()));
|
||||||
|
this.userBeingCalled = extras.getParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY());
|
||||||
|
|
||||||
|
this.originalBundle = extras;
|
||||||
|
credentials = ApiUtils.getCredentials(userBeingCalled.getUsername(), userBeingCalled.getToken());
|
||||||
|
|
||||||
|
setCallDescriptionText();
|
||||||
|
|
||||||
|
if (currentConversation == null) {
|
||||||
|
handleFromNotification();
|
||||||
|
} else {
|
||||||
|
setUpAfterConversationIsKnown();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DoNotDisturbUtils.INSTANCE.shouldPlaySound()) {
|
||||||
|
playRingtoneSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
initClickListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
if (handler == null) {
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
|
try {
|
||||||
|
cache.evictAll();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to evict cache");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initClickListeners() {
|
||||||
|
binding.callAnswerVoiceOnlyView.setOnClickListener(l -> {
|
||||||
|
Log.d(TAG, "accept call (voice only)");
|
||||||
|
originalBundle.putBoolean(BundleKeys.INSTANCE.getKEY_CALL_VOICE_ONLY(), true);
|
||||||
|
proceedToCall();
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.callAnswerCameraView.setOnClickListener(l -> {
|
||||||
|
Log.d(TAG, "accept call (with video)");
|
||||||
|
originalBundle.putBoolean(BundleKeys.INSTANCE.getKEY_CALL_VOICE_ONLY(), false);
|
||||||
|
proceedToCall();
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.hangupButton.setOnClickListener(l -> hangup());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCallDescriptionText() {
|
||||||
|
String callDescriptionWithoutTypeInfo =
|
||||||
|
String.format(
|
||||||
|
getResources().getString(R.string.nc_call_unknown),
|
||||||
|
getResources().getString(R.string.nc_app_product_name));
|
||||||
|
|
||||||
|
binding.incomingCallVoiceOrVideoTextView.setText(callDescriptionWithoutTypeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showAnswerControls() {
|
||||||
|
binding.callAnswerCameraView.setVisibility(View.VISIBLE);
|
||||||
|
binding.callAnswerVoiceOnlyView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.hangupButton)
|
||||||
|
void hangup() {
|
||||||
|
leavingScreen = true;
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void proceedToCall() {
|
||||||
|
originalBundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), currentConversation.getToken());
|
||||||
|
originalBundle.putString(BundleKeys.INSTANCE.getKEY_CONVERSATION_NAME(), currentConversation.getDisplayName());
|
||||||
|
|
||||||
|
Intent intent = new Intent(this, CallActivity.class);
|
||||||
|
intent.putExtras(originalBundle);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIfAnyParticipantsRemainInRoom() {
|
||||||
|
int apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, new int[]{ApiUtils.APIv4, 1});
|
||||||
|
|
||||||
|
ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(),
|
||||||
|
currentConversation.getToken()))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.takeWhile(observable -> !leavingScreen)
|
||||||
|
.subscribe(new Observer<ParticipantsOverall>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Disposable d) {
|
||||||
|
disposablesList.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(ParticipantsOverall participantsOverall) {
|
||||||
|
boolean hasParticipantsInCall = false;
|
||||||
|
boolean inCallOnDifferentDevice = false;
|
||||||
|
List<Participant> participantList = participantsOverall.getOcs().getData();
|
||||||
|
hasParticipantsInCall = participantList.size() > 0;
|
||||||
|
|
||||||
|
if (hasParticipantsInCall) {
|
||||||
|
for (Participant participant : participantList) {
|
||||||
|
if (participant.getActorType() == Participant.ActorType.USERS &&
|
||||||
|
participant.getActorId().equals(userBeingCalled.getUserId())) {
|
||||||
|
inCallOnDifferentDevice = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasParticipantsInCall || inCallOnDifferentDevice) {
|
||||||
|
runOnUiThread(() -> hangup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
if (!leavingScreen) {
|
||||||
|
handler.postDelayed(() -> checkIfAnyParticipantsRemainInRoom(), 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleFromNotification() {
|
||||||
|
int apiVersion = ApiUtils.getConversationApiVersion(userBeingCalled, new int[]{ApiUtils.APIv4,
|
||||||
|
ApiUtils.APIv3, 1});
|
||||||
|
|
||||||
|
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, userBeingCalled.getBaseUrl(), roomId))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.retry(3)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Observer<RoomOverall>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
|
||||||
|
disposablesList.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@io.reactivex.annotations.NonNull RoomOverall roomOverall) {
|
||||||
|
currentConversation = roomOverall.getOcs().data;
|
||||||
|
setUpAfterConversationIsKnown();
|
||||||
|
|
||||||
|
if (apiVersion >= 3) {
|
||||||
|
boolean hasCallFlags =
|
||||||
|
CapabilitiesUtil.hasSpreedFeatureCapability(userBeingCalled,
|
||||||
|
"conversation-call-flags");
|
||||||
|
if (hasCallFlags) {
|
||||||
|
if (isInCallWithVideo(currentConversation.callFlag)) {
|
||||||
|
binding.incomingCallVoiceOrVideoTextView.setText(
|
||||||
|
String.format(getResources().getString(R.string.nc_call_video),
|
||||||
|
getResources().getString(R.string.nc_app_product_name)));
|
||||||
|
} else {
|
||||||
|
binding.incomingCallVoiceOrVideoTextView.setText(
|
||||||
|
String.format(getResources().getString(R.string.nc_call_voice),
|
||||||
|
getResources().getString(R.string.nc_app_product_name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
|
||||||
|
Log.e(TAG, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInCallWithVideo(int callFlag) {
|
||||||
|
return (Participant.ParticipantFlags.IN_CALL_WITH_VIDEO.getValue() == callFlag
|
||||||
|
|| Participant.ParticipantFlags.IN_CALL_WITH_AUDIO_AND_VIDEO.getValue() == callFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpAfterConversationIsKnown() {
|
||||||
|
binding.conversationNameTextView.setText(currentConversation.getDisplayName());
|
||||||
|
|
||||||
|
if(currentConversation.getType() == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL){
|
||||||
|
setAvatarForOneToOneCall();
|
||||||
|
} else {
|
||||||
|
binding.avatarImageView.setImageResource(R.drawable.ic_circular_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfAnyParticipantsRemainInRoom();
|
||||||
|
showAnswerControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAvatarForOneToOneCall() {
|
||||||
|
ImageRequest imageRequest =
|
||||||
|
DisplayUtils.getImageRequestForUrl(
|
||||||
|
ApiUtils.getUrlForAvatarWithName(userBeingCalled.getBaseUrl(),
|
||||||
|
currentConversation.getName(),
|
||||||
|
R.dimen.avatar_size_big), null);
|
||||||
|
|
||||||
|
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||||
|
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);
|
||||||
|
|
||||||
|
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||||
|
@Override
|
||||||
|
protected void onNewResultImpl(@Nullable Bitmap bitmap) {
|
||||||
|
binding.avatarImageView.getHierarchy().setImage(
|
||||||
|
new BitmapDrawable(getResources(), bitmap),
|
||||||
|
100,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
|
||||||
|
Log.e(TAG, "failed to load avatar");
|
||||||
|
}
|
||||||
|
}, UiThreadImmediateExecutorService.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void endMediaNotifications() {
|
||||||
|
if (mediaPlayer != null) {
|
||||||
|
if (mediaPlayer.isPlaying()) {
|
||||||
|
mediaPlayer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaPlayer.release();
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
leavingScreen = true;
|
||||||
|
if (handler != null) {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
dispose();
|
||||||
|
endMediaNotifications();
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispose() {
|
||||||
|
if (disposablesList != null) {
|
||||||
|
for (Disposable disposable : disposablesList) {
|
||||||
|
if (!disposable.isDisposed()) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playRingtoneSound() {
|
||||||
|
String callRingtonePreferenceString = appPreferences.getCallRingtoneUri();
|
||||||
|
Uri ringtoneUri;
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(callRingtonePreferenceString)) {
|
||||||
|
// play default sound
|
||||||
|
ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() +
|
||||||
|
"/raw/librem_by_feandesign_call");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
RingtoneSettings ringtoneSettings = LoganSquare.parse(
|
||||||
|
callRingtonePreferenceString, RingtoneSettings.class);
|
||||||
|
ringtoneUri = ringtoneSettings.getRingtoneUri();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to parse ringtone settings");
|
||||||
|
ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() +
|
||||||
|
"/raw/librem_by_feandesign_call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ringtoneUri != null) {
|
||||||
|
mediaPlayer = new MediaPlayer();
|
||||||
|
try {
|
||||||
|
mediaPlayer.setDataSource(this, ringtoneUri);
|
||||||
|
|
||||||
|
mediaPlayer.setLooping(true);
|
||||||
|
AudioAttributes audioAttributes = new AudioAttributes
|
||||||
|
.Builder()
|
||||||
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||||
|
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||||
|
.build();
|
||||||
|
mediaPlayer.setAudioAttributes(audioAttributes);
|
||||||
|
|
||||||
|
mediaPlayer.setOnPreparedListener(mp -> mediaPlayer.start());
|
||||||
|
|
||||||
|
mediaPlayer.prepareAsync();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to set data source");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
@Override
|
||||||
|
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
|
||||||
|
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
|
||||||
|
isInPipMode = isInPictureInPictureMode;
|
||||||
|
if (isInPictureInPictureMode) {
|
||||||
|
updateUiForPipMode();
|
||||||
|
} else {
|
||||||
|
updateUiForNormalMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUiForPipMode() {
|
||||||
|
binding.callAnswerButtons.setVisibility(View.INVISIBLE);
|
||||||
|
binding.incomingCallRelativeLayout.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUiForNormalMode() {
|
||||||
|
binding.callAnswerButtons.setVisibility(View.VISIBLE);
|
||||||
|
binding.incomingCallRelativeLayout.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void suppressFitsSystemWindows() {
|
||||||
|
binding.controllerCallNotificationLayout.setFitsSystemWindows(false);
|
||||||
|
}
|
||||||
|
}
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* @author Andy Scherzinger
|
|
||||||
* Copyright (C) 2021 Andy Scherzinger (infoi@andy-scherzinger.de)
|
|
||||||
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.nextcloud.talk.activities
|
|
||||||
|
|
||||||
import android.app.KeyguardManager
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.view.Window
|
|
||||||
import android.view.WindowManager
|
|
||||||
import autodagger.AutoInjector
|
|
||||||
import com.bluelinelabs.conductor.Conductor
|
|
||||||
import com.bluelinelabs.conductor.Router
|
|
||||||
import com.bluelinelabs.conductor.RouterTransaction
|
|
||||||
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
|
|
||||||
import com.nextcloud.talk.R
|
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
|
||||||
import com.nextcloud.talk.controllers.CallController
|
|
||||||
import com.nextcloud.talk.controllers.CallNotificationController
|
|
||||||
import com.nextcloud.talk.controllers.ChatController
|
|
||||||
import com.nextcloud.talk.databinding.ActivityMagicCallBinding
|
|
||||||
import com.nextcloud.talk.events.ConfigurationChangeEvent
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
|
||||||
class MagicCallActivity : BaseActivity() {
|
|
||||||
lateinit var binding: ActivityMagicCallBinding
|
|
||||||
|
|
||||||
private lateinit var chatController: ChatController
|
|
||||||
|
|
||||||
private var router: Router? = null
|
|
||||||
private var chatRouter: Router? = null
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
|
||||||
setTheme(R.style.CallTheme)
|
|
||||||
|
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
dismissKeyguard()
|
|
||||||
window.addFlags(
|
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN or
|
|
||||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
|
||||||
)
|
|
||||||
window.decorView.systemUiVisibility = systemUiVisibility
|
|
||||||
|
|
||||||
binding = ActivityMagicCallBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
|
|
||||||
router = Conductor.attachRouter(this, binding.controllerContainer, savedInstanceState)
|
|
||||||
router!!.setPopsLastView(false)
|
|
||||||
|
|
||||||
if (!router!!.hasRootController()) {
|
|
||||||
if (intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)) {
|
|
||||||
router!!.setRoot(
|
|
||||||
RouterTransaction.with(CallNotificationController(intent.extras))
|
|
||||||
.pushChangeHandler(HorizontalChangeHandler())
|
|
||||||
.popChangeHandler(HorizontalChangeHandler())
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
router!!.setRoot(
|
|
||||||
RouterTransaction.with(CallController(intent.extras))
|
|
||||||
.pushChangeHandler(HorizontalChangeHandler())
|
|
||||||
.popChangeHandler(HorizontalChangeHandler())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val extras = intent.extras ?: Bundle()
|
|
||||||
extras.putBoolean("showToggleChat", true)
|
|
||||||
|
|
||||||
chatController = ChatController(extras)
|
|
||||||
chatRouter = Conductor.attachRouter(this, binding.chatControllerView, savedInstanceState)
|
|
||||||
chatRouter!!.setRoot(
|
|
||||||
RouterTransaction.with(chatController)
|
|
||||||
.pushChangeHandler(HorizontalChangeHandler())
|
|
||||||
.popChangeHandler(HorizontalChangeHandler())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun showChat() {
|
|
||||||
enableKeyguard()
|
|
||||||
binding.chatControllerView.visibility = View.VISIBLE
|
|
||||||
binding.controllerContainer.visibility = View.GONE
|
|
||||||
chatController.wasDetached = false
|
|
||||||
chatController.pullChatMessages(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun showCall() {
|
|
||||||
binding.controllerContainer.visibility = View.VISIBLE
|
|
||||||
binding.chatControllerView.visibility = View.GONE
|
|
||||||
chatController.wasDetached = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
||||||
super.onConfigurationChanged(newConfig)
|
|
||||||
eventBus.post(ConfigurationChangeEvent())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dismissKeyguard() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
||||||
setShowWhenLocked(true)
|
|
||||||
setTurnScreenOn(true)
|
|
||||||
val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
|
|
||||||
keyguardManager.requestDismissKeyguard(this, null)
|
|
||||||
} else {
|
|
||||||
window.addFlags(
|
|
||||||
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
|
||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun enableKeyguard() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
||||||
setShowWhenLocked(false)
|
|
||||||
} else {
|
|
||||||
window.clearFlags(
|
|
||||||
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
|
||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val TAG = "MagicCallActivity"
|
|
||||||
|
|
||||||
private val systemUiVisibility: Int
|
|
||||||
get() {
|
|
||||||
var flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
||||||
flags = flags or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
||||||
return flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -40,7 +40,6 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.api.NcApi
|
import com.nextcloud.talk.api.NcApi
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.controllers.CallNotificationController
|
|
||||||
import com.nextcloud.talk.controllers.ConversationsListController
|
import com.nextcloud.talk.controllers.ConversationsListController
|
||||||
import com.nextcloud.talk.controllers.LockedController
|
import com.nextcloud.talk.controllers.LockedController
|
||||||
import com.nextcloud.talk.controllers.ServerSelectionController
|
import com.nextcloud.talk.controllers.ServerSelectionController
|
||||||
@ -310,11 +309,9 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
handleActionFromContact(intent)
|
handleActionFromContact(intent)
|
||||||
if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) {
|
if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) {
|
||||||
if (intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)) {
|
if (intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)) {
|
||||||
router!!.pushController(
|
val callNotificationIntent = Intent(this, CallNotificationActivity::class.java)
|
||||||
RouterTransaction.with(CallNotificationController(intent.extras))
|
intent.extras?.let { callNotificationIntent.putExtras(it) }
|
||||||
.pushChangeHandler(HorizontalChangeHandler())
|
startActivity(callNotificationIntent)
|
||||||
.popChangeHandler(HorizontalChangeHandler())
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
ConductorRemapping.remapChatController(
|
ConductorRemapping.remapChatController(
|
||||||
router!!, intent.getLongExtra(BundleKeys.KEY_INTERNAL_USER_ID, -1),
|
router!!, intent.getLongExtra(BundleKeys.KEY_INTERNAL_USER_ID, -1),
|
||||||
|
@ -15,6 +15,7 @@ import com.facebook.drawee.backends.pipeline.Fresco;
|
|||||||
import com.facebook.drawee.interfaces.DraweeController;
|
import com.facebook.drawee.interfaces.DraweeController;
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
import com.facebook.drawee.view.SimpleDraweeView;
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
|
import com.nextcloud.talk.activities.CallActivity;
|
||||||
import com.nextcloud.talk.utils.DisplayUtils;
|
import com.nextcloud.talk.utils.DisplayUtils;
|
||||||
|
|
||||||
import org.webrtc.MediaStream;
|
import org.webrtc.MediaStream;
|
||||||
@ -79,6 +80,8 @@ public class ParticipantsAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
surfaceViewRenderer = convertView.findViewById(R.id.surface_view);
|
surfaceViewRenderer = convertView.findViewById(R.id.surface_view);
|
||||||
try {
|
try {
|
||||||
|
Log.d(TAG, "hasSurface: " + participantDisplayItem.getRootEglBase().hasSurface());
|
||||||
|
|
||||||
surfaceViewRenderer.setMirror(false);
|
surfaceViewRenderer.setMirror(false);
|
||||||
surfaceViewRenderer.init(participantDisplayItem.getRootEglBase().getEglBaseContext(), null);
|
surfaceViewRenderer.init(participantDisplayItem.getRootEglBase().getEglBaseContext(), null);
|
||||||
surfaceViewRenderer.setZOrderMediaOverlay(false);
|
surfaceViewRenderer.setZOrderMediaOverlay(false);
|
||||||
@ -96,7 +99,6 @@ public class ParticipantsAdapter extends BaseAdapter {
|
|||||||
layoutParams.height = scaleGridViewItemHeight();
|
layoutParams.height = scaleGridViewItemHeight();
|
||||||
convertView.setLayoutParams(layoutParams);
|
convertView.setLayoutParams(layoutParams);
|
||||||
|
|
||||||
|
|
||||||
TextView nickTextView = convertView.findViewById(R.id.peer_nick_text_view);
|
TextView nickTextView = convertView.findViewById(R.id.peer_nick_text_view);
|
||||||
SimpleDraweeView imageView = convertView.findViewById(R.id.avatarImageView);
|
SimpleDraweeView imageView = convertView.findViewById(R.id.avatarImageView);
|
||||||
|
|
||||||
@ -110,8 +112,13 @@ public class ParticipantsAdapter extends BaseAdapter {
|
|||||||
} else {
|
} else {
|
||||||
imageView.setVisibility(View.VISIBLE);
|
imageView.setVisibility(View.VISIBLE);
|
||||||
surfaceViewRenderer.setVisibility(View.INVISIBLE);
|
surfaceViewRenderer.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
if (((CallActivity) mContext).isInPipMode) {
|
||||||
|
nickTextView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
nickTextView.setVisibility(View.VISIBLE);
|
nickTextView.setVisibility(View.VISIBLE);
|
||||||
nickTextView.setText(participantDisplayItem.getNick());
|
nickTextView.setText(participantDisplayItem.getNick());
|
||||||
|
}
|
||||||
|
|
||||||
imageView.setController(null);
|
imageView.setController(null);
|
||||||
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
||||||
@ -127,7 +134,9 @@ public class ParticipantsAdapter extends BaseAdapter {
|
|||||||
} else {
|
} else {
|
||||||
audioOffView.setVisibility(View.INVISIBLE);
|
audioOffView.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasVideoStream(ParticipantDisplayItem participantDisplayItem, MediaStream mediaStream) {
|
private boolean hasVideoStream(ParticipantDisplayItem participantDisplayItem, MediaStream mediaStream) {
|
||||||
|
@ -1,520 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk application
|
|
||||||
*
|
|
||||||
* @author Mario Danic
|
|
||||||
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.nextcloud.talk.controllers;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.media.AudioAttributes;
|
|
||||||
import android.media.MediaPlayer;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.renderscript.RenderScript;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.bluelinelabs.conductor.RouterTransaction;
|
|
||||||
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
|
|
||||||
import com.bluelinelabs.logansquare.LoganSquare;
|
|
||||||
import com.facebook.common.executors.UiThreadImmediateExecutorService;
|
|
||||||
import com.facebook.common.references.CloseableReference;
|
|
||||||
import com.facebook.datasource.DataSource;
|
|
||||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
|
||||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
|
||||||
import com.facebook.imagepipeline.image.CloseableImage;
|
|
||||||
import com.facebook.imagepipeline.postprocessors.BlurPostProcessor;
|
|
||||||
import com.facebook.imagepipeline.request.ImageRequest;
|
|
||||||
import com.nextcloud.talk.R;
|
|
||||||
import com.nextcloud.talk.api.NcApi;
|
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
|
||||||
import com.nextcloud.talk.controllers.base.BaseController;
|
|
||||||
import com.nextcloud.talk.events.CallNotificationClick;
|
|
||||||
import com.nextcloud.talk.events.ConfigurationChangeEvent;
|
|
||||||
import com.nextcloud.talk.models.RingtoneSettings;
|
|
||||||
import com.nextcloud.talk.models.database.CapabilitiesUtil;
|
|
||||||
import com.nextcloud.talk.models.database.UserEntity;
|
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation;
|
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall;
|
|
||||||
import com.nextcloud.talk.models.json.participants.Participant;
|
|
||||||
import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
|
|
||||||
import com.nextcloud.talk.utils.ApiUtils;
|
|
||||||
import com.nextcloud.talk.utils.DisplayUtils;
|
|
||||||
import com.nextcloud.talk.utils.DoNotDisturbUtils;
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
|
||||||
import com.nextcloud.talk.utils.singletons.AvatarStatusCodeHolder;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
|
||||||
import org.greenrobot.eventbus.ThreadMode;
|
|
||||||
import org.michaelevans.colorart.library.ColorArt;
|
|
||||||
import org.parceler.Parcels;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
|
||||||
import autodagger.AutoInjector;
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
import io.reactivex.Observer;
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
import okhttp3.Cache;
|
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication.class)
|
|
||||||
public class CallNotificationController extends BaseController {
|
|
||||||
|
|
||||||
private static final String TAG = "CallNotificationController";
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
NcApi ncApi;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
AppPreferences appPreferences;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Cache cache;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
EventBus eventBus;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Context context;
|
|
||||||
|
|
||||||
@BindView(R.id.incomingCallVoiceOrVideoTextView)
|
|
||||||
TextView incomingCallVoiceOrVideoTextView;
|
|
||||||
|
|
||||||
@BindView(R.id.conversationNameTextView)
|
|
||||||
TextView conversationNameTextView;
|
|
||||||
|
|
||||||
@BindView(R.id.avatarImageView)
|
|
||||||
SimpleDraweeView avatarImageView;
|
|
||||||
|
|
||||||
@BindView(R.id.callAnswerVoiceOnlyView)
|
|
||||||
SimpleDraweeView callAnswerVoiceOnlyView;
|
|
||||||
|
|
||||||
@BindView(R.id.callAnswerCameraView)
|
|
||||||
SimpleDraweeView callAnswerCameraView;
|
|
||||||
|
|
||||||
@BindView(R.id.backgroundImageView)
|
|
||||||
ImageView backgroundImageView;
|
|
||||||
|
|
||||||
@BindView(R.id.incomingTextRelativeLayout)
|
|
||||||
RelativeLayout incomingTextRelativeLayout;
|
|
||||||
|
|
||||||
private List<Disposable> disposablesList = new ArrayList<>();
|
|
||||||
private Bundle originalBundle;
|
|
||||||
private String roomId;
|
|
||||||
private UserEntity userBeingCalled;
|
|
||||||
private String credentials;
|
|
||||||
private Conversation currentConversation;
|
|
||||||
private MediaPlayer mediaPlayer;
|
|
||||||
private boolean leavingScreen = false;
|
|
||||||
private RenderScript renderScript;
|
|
||||||
private Handler handler;
|
|
||||||
|
|
||||||
public CallNotificationController(Bundle args) {
|
|
||||||
super(args);
|
|
||||||
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
|
||||||
|
|
||||||
eventBus.post(new CallNotificationClick());
|
|
||||||
this.roomId = args.getString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), "");
|
|
||||||
this.currentConversation = Parcels.unwrap(args.getParcelable(BundleKeys.INSTANCE.getKEY_ROOM()));
|
|
||||||
this.userBeingCalled = args.getParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY());
|
|
||||||
|
|
||||||
this.originalBundle = args;
|
|
||||||
credentials = ApiUtils.getCredentials(userBeingCalled.getUsername(), userBeingCalled.getToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
|
|
||||||
return inflater.inflate(R.layout.controller_call_notification, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showAnswerControls() {
|
|
||||||
callAnswerCameraView.setVisibility(View.VISIBLE);
|
|
||||||
callAnswerVoiceOnlyView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.callControlHangupView)
|
|
||||||
void hangup() {
|
|
||||||
leavingScreen = true;
|
|
||||||
|
|
||||||
if (getActivity() != null) {
|
|
||||||
getActivity().finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.callAnswerCameraView)
|
|
||||||
void answerWithCamera() {
|
|
||||||
originalBundle.putBoolean(BundleKeys.INSTANCE.getKEY_CALL_VOICE_ONLY(), false);
|
|
||||||
proceedToCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.callAnswerVoiceOnlyView)
|
|
||||||
void answerVoiceOnly() {
|
|
||||||
originalBundle.putBoolean(BundleKeys.INSTANCE.getKEY_CALL_VOICE_ONLY(), true);
|
|
||||||
proceedToCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void proceedToCall() {
|
|
||||||
originalBundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), currentConversation.getToken());
|
|
||||||
originalBundle.putString(BundleKeys.INSTANCE.getKEY_CONVERSATION_NAME(), currentConversation.getDisplayName());
|
|
||||||
|
|
||||||
getRouter().replaceTopController(RouterTransaction.with(new CallController(originalBundle))
|
|
||||||
.popChangeHandler(new HorizontalChangeHandler())
|
|
||||||
.pushChangeHandler(new HorizontalChangeHandler()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkIfAnyParticipantsRemainInRoom() {
|
|
||||||
int apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, new int[] {ApiUtils.APIv4, 1});
|
|
||||||
|
|
||||||
ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(),
|
|
||||||
currentConversation.getToken()))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.takeWhile(observable -> !leavingScreen)
|
|
||||||
.subscribe(new Observer<ParticipantsOverall>() {
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(Disposable d) {
|
|
||||||
disposablesList.add(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(ParticipantsOverall participantsOverall) {
|
|
||||||
boolean hasParticipantsInCall = false;
|
|
||||||
boolean inCallOnDifferentDevice = false;
|
|
||||||
List<Participant> participantList = participantsOverall.getOcs().getData();
|
|
||||||
hasParticipantsInCall = participantList.size() > 0;
|
|
||||||
|
|
||||||
if (hasParticipantsInCall) {
|
|
||||||
for (Participant participant : participantList) {
|
|
||||||
if (participant.getActorType() == Participant.ActorType.USERS &&
|
|
||||||
participant.getActorId().equals(userBeingCalled.getUserId())) {
|
|
||||||
inCallOnDifferentDevice = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasParticipantsInCall || inCallOnDifferentDevice) {
|
|
||||||
if (getActivity() != null) {
|
|
||||||
getActivity().runOnUiThread(() -> hangup());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
if (!leavingScreen) {
|
|
||||||
handler.postDelayed(() -> checkIfAnyParticipantsRemainInRoom(), 5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleFromNotification() {
|
|
||||||
int apiVersion = ApiUtils.getConversationApiVersion(userBeingCalled, new int[] {ApiUtils.APIv4,
|
|
||||||
ApiUtils.APIv3, 1});
|
|
||||||
|
|
||||||
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, userBeingCalled.getBaseUrl(), roomId))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.retry(3)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new Observer<RoomOverall>() {
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
|
|
||||||
disposablesList.add(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(@io.reactivex.annotations.NonNull RoomOverall roomOverall) {
|
|
||||||
currentConversation = roomOverall.getOcs().data;
|
|
||||||
runAllThings();
|
|
||||||
|
|
||||||
if (apiVersion >= 3) {
|
|
||||||
boolean hasCallFlags =
|
|
||||||
CapabilitiesUtil.hasSpreedFeatureCapability(userBeingCalled,
|
|
||||||
"conversation-call-flags");
|
|
||||||
if (hasCallFlags) {
|
|
||||||
if (isInCallWithVideo(currentConversation.callFlag)) {
|
|
||||||
incomingCallVoiceOrVideoTextView.setText(
|
|
||||||
String.format(getResources().getString(R.string.nc_call_video),
|
|
||||||
getResources().getString(R.string.nc_app_product_name)));
|
|
||||||
} else {
|
|
||||||
incomingCallVoiceOrVideoTextView.setText(
|
|
||||||
String.format(getResources().getString(R.string.nc_call_voice),
|
|
||||||
getResources().getString(R.string.nc_app_product_name)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("LongLogTag")
|
|
||||||
@Override
|
|
||||||
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
|
|
||||||
Log.e(TAG, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInCallWithVideo(int callFlag) {
|
|
||||||
return (Participant.ParticipantFlags.IN_CALL_WITH_VIDEO.getValue() == callFlag
|
|
||||||
|| Participant.ParticipantFlags.IN_CALL_WITH_AUDIO_AND_VIDEO.getValue() == callFlag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runAllThings() {
|
|
||||||
if (conversationNameTextView != null) {
|
|
||||||
conversationNameTextView.setText(currentConversation.getDisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
loadAvatar();
|
|
||||||
checkIfAnyParticipantsRemainInRoom();
|
|
||||||
showAnswerControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint({"LongLogTag"})
|
|
||||||
@Override
|
|
||||||
protected void onViewBound(@NonNull View view) {
|
|
||||||
super.onViewBound(view);
|
|
||||||
|
|
||||||
String callDescriptionWithoutTypeInfo =
|
|
||||||
String.format(
|
|
||||||
getResources().getString(R.string.nc_call_unknown),
|
|
||||||
getResources().getString(R.string.nc_app_product_name));
|
|
||||||
|
|
||||||
incomingCallVoiceOrVideoTextView.setText(callDescriptionWithoutTypeInfo);
|
|
||||||
|
|
||||||
renderScript = RenderScript.create(getActivity());
|
|
||||||
|
|
||||||
if (handler == null) {
|
|
||||||
handler = new Handler();
|
|
||||||
|
|
||||||
try {
|
|
||||||
cache.evictAll();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Failed to evict cache");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentConversation == null) {
|
|
||||||
handleFromNotification();
|
|
||||||
} else {
|
|
||||||
runAllThings();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DoNotDisturbUtils.INSTANCE.shouldPlaySound()) {
|
|
||||||
playRingtoneSound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
||||||
public void onMessageEvent(ConfigurationChangeEvent configurationChangeEvent) {
|
|
||||||
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) avatarImageView.getLayoutParams();
|
|
||||||
int dimen = (int) getResources().getDimension(R.dimen.avatar_size_very_big);
|
|
||||||
|
|
||||||
layoutParams.width = dimen;
|
|
||||||
layoutParams.height = dimen;
|
|
||||||
avatarImageView.setLayoutParams(layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDetach(@NonNull View view) {
|
|
||||||
super.onDetach(view);
|
|
||||||
eventBus.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAttach(@NonNull View view) {
|
|
||||||
super.onAttach(view);
|
|
||||||
eventBus.register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadAvatar() {
|
|
||||||
switch (currentConversation.getType()) {
|
|
||||||
case ROOM_TYPE_ONE_TO_ONE_CALL:
|
|
||||||
avatarImageView.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
ImageRequest imageRequest =
|
|
||||||
DisplayUtils.getImageRequestForUrl(
|
|
||||||
ApiUtils.getUrlForAvatarWithName(userBeingCalled.getBaseUrl(),
|
|
||||||
currentConversation.getName(),
|
|
||||||
R.dimen.avatar_size_very_big),
|
|
||||||
null);
|
|
||||||
|
|
||||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
|
||||||
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null);
|
|
||||||
|
|
||||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
|
||||||
@Override
|
|
||||||
protected void onNewResultImpl(@Nullable Bitmap bitmap) {
|
|
||||||
if (avatarImageView != null) {
|
|
||||||
avatarImageView.getHierarchy().setImage(new BitmapDrawable(bitmap), 100,
|
|
||||||
true);
|
|
||||||
|
|
||||||
if (getResources() != null) {
|
|
||||||
incomingTextRelativeLayout.setBackground(
|
|
||||||
getResources().getDrawable(R.drawable.incoming_gradient));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AvatarStatusCodeHolder.getInstance().getStatusCode() == 200 ||
|
|
||||||
AvatarStatusCodeHolder.getInstance().getStatusCode() == 0) {
|
|
||||||
if (getActivity() != null) {
|
|
||||||
Bitmap backgroundBitmap = bitmap.copy(bitmap.getConfig(), true);
|
|
||||||
new BlurPostProcessor(5, getActivity()).process(backgroundBitmap);
|
|
||||||
backgroundImageView.setImageDrawable(new BitmapDrawable(backgroundBitmap));
|
|
||||||
}
|
|
||||||
} else if (AvatarStatusCodeHolder.getInstance().getStatusCode() == 201) {
|
|
||||||
ColorArt colorArt = new ColorArt(bitmap);
|
|
||||||
int color = colorArt.getBackgroundColor();
|
|
||||||
|
|
||||||
float[] hsv = new float[3];
|
|
||||||
Color.colorToHSV(color, hsv);
|
|
||||||
hsv[2] *= 0.75f;
|
|
||||||
color = Color.HSVToColor(hsv);
|
|
||||||
|
|
||||||
backgroundImageView.setImageDrawable(new ColorDrawable(color));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
}, UiThreadImmediateExecutorService.getInstance());
|
|
||||||
|
|
||||||
break;
|
|
||||||
case ROOM_GROUP_CALL:
|
|
||||||
avatarImageView.setImageResource(R.drawable.ic_circular_group);
|
|
||||||
case ROOM_PUBLIC_CALL:
|
|
||||||
avatarImageView.setImageResource(R.drawable.ic_circular_group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endMediaNotifications() {
|
|
||||||
if (mediaPlayer != null) {
|
|
||||||
if (mediaPlayer.isPlaying()) {
|
|
||||||
mediaPlayer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaPlayer.release();
|
|
||||||
mediaPlayer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
AvatarStatusCodeHolder.getInstance().setStatusCode(0);
|
|
||||||
leavingScreen = true;
|
|
||||||
if (handler != null) {
|
|
||||||
handler.removeCallbacksAndMessages(null);
|
|
||||||
handler = null;
|
|
||||||
}
|
|
||||||
dispose();
|
|
||||||
endMediaNotifications();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dispose() {
|
|
||||||
if (disposablesList != null) {
|
|
||||||
for (Disposable disposable : disposablesList) {
|
|
||||||
if (!disposable.isDisposed()) {
|
|
||||||
disposable.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("LongLogTag")
|
|
||||||
private void playRingtoneSound() {
|
|
||||||
String callRingtonePreferenceString = appPreferences.getCallRingtoneUri();
|
|
||||||
Uri ringtoneUri;
|
|
||||||
|
|
||||||
if (TextUtils.isEmpty(callRingtonePreferenceString)) {
|
|
||||||
// play default sound
|
|
||||||
ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() +
|
|
||||||
"/raw/librem_by_feandesign_call");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
RingtoneSettings ringtoneSettings = LoganSquare.parse(
|
|
||||||
callRingtonePreferenceString, RingtoneSettings.class);
|
|
||||||
ringtoneUri = ringtoneSettings.getRingtoneUri();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Failed to parse ringtone settings");
|
|
||||||
ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() +
|
|
||||||
"/raw/librem_by_feandesign_call");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ringtoneUri != null && getActivity() != null) {
|
|
||||||
mediaPlayer = new MediaPlayer();
|
|
||||||
try {
|
|
||||||
mediaPlayer.setDataSource(getActivity(), ringtoneUri);
|
|
||||||
|
|
||||||
mediaPlayer.setLooping(true);
|
|
||||||
AudioAttributes audioAttributes = new AudioAttributes
|
|
||||||
.Builder()
|
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
|
||||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
|
||||||
.build();
|
|
||||||
mediaPlayer.setAudioAttributes(audioAttributes);
|
|
||||||
|
|
||||||
mediaPlayer.setOnPreparedListener(mp -> mediaPlayer.start());
|
|
||||||
|
|
||||||
mediaPlayer.prepareAsync();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Failed to set data source");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -94,7 +94,7 @@ import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
|||||||
import com.facebook.imagepipeline.image.CloseableImage
|
import com.facebook.imagepipeline.image.CloseableImage
|
||||||
import com.google.android.flexbox.FlexboxLayout
|
import com.google.android.flexbox.FlexboxLayout
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.activities.MagicCallActivity
|
import com.nextcloud.talk.activities.CallActivity
|
||||||
import com.nextcloud.talk.activities.MainActivity
|
import com.nextcloud.talk.activities.MainActivity
|
||||||
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
||||||
import com.nextcloud.talk.adapters.messages.IncomingPreviewMessageViewHolder
|
import com.nextcloud.talk.adapters.messages.IncomingPreviewMessageViewHolder
|
||||||
@ -232,7 +232,6 @@ class ChatController(args: Bundle) :
|
|||||||
val roomId: String
|
val roomId: String
|
||||||
val voiceOnly: Boolean
|
val voiceOnly: Boolean
|
||||||
var isFirstMessagesProcessing = true
|
var isFirstMessagesProcessing = true
|
||||||
var isLeavingForConversation: Boolean = false
|
|
||||||
var wasDetached: Boolean = false
|
var wasDetached: Boolean = false
|
||||||
var emojiPopup: EmojiPopup? = null
|
var emojiPopup: EmojiPopup? = null
|
||||||
|
|
||||||
@ -270,6 +269,8 @@ class ChatController(args: Bundle) :
|
|||||||
this.roomToken = args.getString(KEY_ROOM_TOKEN, "")
|
this.roomToken = args.getString(KEY_ROOM_TOKEN, "")
|
||||||
this.sharedText = args.getString(BundleKeys.KEY_SHARED_TEXT, "")
|
this.sharedText = args.getString(BundleKeys.KEY_SHARED_TEXT, "")
|
||||||
|
|
||||||
|
Log.d(TAG, "roomToken = " + roomToken)
|
||||||
|
|
||||||
if (args.containsKey(KEY_ACTIVE_CONVERSATION)) {
|
if (args.containsKey(KEY_ACTIVE_CONVERSATION)) {
|
||||||
this.currentConversation = Parcels.unwrap<Conversation>(args.getParcelable(KEY_ACTIVE_CONVERSATION))
|
this.currentConversation = Parcels.unwrap<Conversation>(args.getParcelable(KEY_ACTIVE_CONVERSATION))
|
||||||
}
|
}
|
||||||
@ -290,6 +291,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getRoomInfo() {
|
private fun getRoomInfo() {
|
||||||
|
Log.d(TAG, "getRoomInfo")
|
||||||
val shouldRepeat = CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "webinary-lobby")
|
val shouldRepeat = CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "webinary-lobby")
|
||||||
if (shouldRepeat) {
|
if (shouldRepeat) {
|
||||||
checkingLobbyStatus = true
|
checkingLobbyStatus = true
|
||||||
@ -309,6 +311,8 @@ class ChatController(args: Bundle) :
|
|||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
currentConversation = roomOverall.ocs.data
|
currentConversation = roomOverall.ocs.data
|
||||||
|
Log.d(TAG, "currentConversation.toString : " + currentConversation.toString())
|
||||||
|
Log.d(TAG, "currentConversation.sessionId : " + currentConversation?.sessionId)
|
||||||
loadAvatarForStatusBar()
|
loadAvatarForStatusBar()
|
||||||
|
|
||||||
setTitle()
|
setTitle()
|
||||||
@ -420,6 +424,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
override fun onViewBound(view: View) {
|
override fun onViewBound(view: View) {
|
||||||
actionBar?.show()
|
actionBar?.show()
|
||||||
|
Log.d(TAG, "onViewBound")
|
||||||
var adapterWasNull = false
|
var adapterWasNull = false
|
||||||
|
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
@ -577,15 +582,6 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
binding.messageInputView.setPadding(0, 0, 0, 0)
|
binding.messageInputView.setPadding(0, 0, 0, 0)
|
||||||
|
|
||||||
if (args.containsKey("showToggleChat") && args.getBoolean("showToggleChat")) {
|
|
||||||
binding.callControlToggleChat.visibility = View.VISIBLE
|
|
||||||
wasDetached = true
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.callControlToggleChat.setOnClickListener {
|
|
||||||
(activity as MagicCallActivity).showCall()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.messagesListView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
binding.messagesListView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
super.onScrollStateChanged(recyclerView, newState)
|
super.onScrollStateChanged(recyclerView, newState)
|
||||||
@ -1376,10 +1372,8 @@ class ChatController(args: Bundle) :
|
|||||||
activity?.findViewById<View>(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() }
|
activity?.findViewById<View>(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() }
|
||||||
}
|
}
|
||||||
|
|
||||||
isLeavingForConversation = false
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().currentRoomId = roomId
|
ApplicationWideCurrentRoomHolder.getInstance().currentRoomId = roomId
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = roomId
|
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = roomToken
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().isInCall = false
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
|
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
|
||||||
|
|
||||||
val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton)
|
val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton)
|
||||||
@ -1443,11 +1437,6 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
override fun onDetach(view: View) {
|
override fun onDetach(view: View) {
|
||||||
super.onDetach(view)
|
super.onDetach(view)
|
||||||
|
|
||||||
if (!isLeavingForConversation) {
|
|
||||||
// current room is still "active", we need the info
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().clear()
|
|
||||||
}
|
|
||||||
eventBus?.unregister(this)
|
eventBus?.unregister(this)
|
||||||
|
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
@ -1457,8 +1446,10 @@ class ChatController(args: Bundle) :
|
|||||||
if (conversationUser != null &&
|
if (conversationUser != null &&
|
||||||
activity != null &&
|
activity != null &&
|
||||||
!activity?.isChangingConfigurations!! &&
|
!activity?.isChangingConfigurations!! &&
|
||||||
!isLeavingForConversation
|
!ApplicationWideCurrentRoomHolder.getInstance().isInCall &&
|
||||||
|
!ApplicationWideCurrentRoomHolder.getInstance().isDialing
|
||||||
) {
|
) {
|
||||||
|
ApplicationWideCurrentRoomHolder.getInstance().clear()
|
||||||
wasDetached = true
|
wasDetached = true
|
||||||
leaveRoom()
|
leaveRoom()
|
||||||
}
|
}
|
||||||
@ -2129,7 +2120,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startACall(isVoiceOnlyCall: Boolean) {
|
private fun startACall(isVoiceOnlyCall: Boolean) {
|
||||||
isLeavingForConversation = true
|
ApplicationWideCurrentRoomHolder.getInstance().isDialing = true
|
||||||
val callIntent = getIntentForCall(isVoiceOnlyCall)
|
val callIntent = getIntentForCall(isVoiceOnlyCall)
|
||||||
if (callIntent != null) {
|
if (callIntent != null) {
|
||||||
startActivity(callIntent)
|
startActivity(callIntent)
|
||||||
@ -2151,7 +2142,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
return if (activity != null) {
|
return if (activity != null) {
|
||||||
val callIntent = Intent(activity, MagicCallActivity::class.java)
|
val callIntent = Intent(activity, CallActivity::class.java)
|
||||||
callIntent.putExtras(bundle)
|
callIntent.putExtras(bundle)
|
||||||
callIntent
|
callIntent
|
||||||
} else {
|
} else {
|
||||||
@ -2336,7 +2327,7 @@ class ChatController(args: Bundle) :
|
|||||||
menu.findItem(R.id.action_forward_message).isVisible =
|
menu.findItem(R.id.action_forward_message).isVisible =
|
||||||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType()
|
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType()
|
||||||
if (menu.hasVisibleItems()) {
|
if (menu.hasVisibleItems()) {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
||||||
setForceShowIcon(true)
|
setForceShowIcon(true)
|
||||||
}
|
}
|
||||||
show()
|
show()
|
||||||
@ -2509,7 +2500,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val conversationIntent = Intent(activity, MagicCallActivity::class.java)
|
val conversationIntent = Intent(activity, CallActivity::class.java)
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs.data.token)
|
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs.data.token)
|
||||||
|
@ -22,7 +22,6 @@ package com.nextcloud.talk.controllers;
|
|||||||
|
|
||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -45,7 +44,6 @@ import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
|
|||||||
import com.bluelinelabs.logansquare.LoganSquare;
|
import com.bluelinelabs.logansquare.LoganSquare;
|
||||||
import com.kennyc.bottomsheet.BottomSheet;
|
import com.kennyc.bottomsheet.BottomSheet;
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
import com.nextcloud.talk.activities.MagicCallActivity;
|
|
||||||
import com.nextcloud.talk.adapters.items.GenericTextHeaderItem;
|
import com.nextcloud.talk.adapters.items.GenericTextHeaderItem;
|
||||||
import com.nextcloud.talk.adapters.items.UserItem;
|
import com.nextcloud.talk.adapters.items.UserItem;
|
||||||
import com.nextcloud.talk.api.NcApi;
|
import com.nextcloud.talk.api.NcApi;
|
||||||
@ -106,7 +104,6 @@ import eu.davidea.flexibleadapter.FlexibleAdapter;
|
|||||||
import eu.davidea.flexibleadapter.SelectableAdapter;
|
import eu.davidea.flexibleadapter.SelectableAdapter;
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible;
|
|
||||||
import io.reactivex.Observer;
|
import io.reactivex.Observer;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
@ -897,13 +894,10 @@ public class ContactsController extends BaseController implements SearchView.OnQ
|
|||||||
@Override
|
@Override
|
||||||
public void onNext(RoomOverall roomOverall) {
|
public void onNext(RoomOverall roomOverall) {
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
Intent conversationIntent = new Intent(getActivity(), MagicCallActivity.class);
|
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY(), currentUser);
|
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY(), currentUser);
|
||||||
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), roomOverall.getOcs().getData().getToken());
|
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), roomOverall.getOcs().getData().getToken());
|
||||||
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), roomOverall.getOcs().getData().getRoomId());
|
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), roomOverall.getOcs().getData().getRoomId());
|
||||||
conversationIntent.putExtras(bundle);
|
|
||||||
|
|
||||||
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_ACTIVE_CONVERSATION(),
|
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_ACTIVE_CONVERSATION(),
|
||||||
Parcels.wrap(roomOverall.getOcs().getData()));
|
Parcels.wrap(roomOverall.getOcs().getData()));
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ import com.bluelinelabs.conductor.RouterTransaction;
|
|||||||
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
|
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
|
||||||
import com.bluelinelabs.logansquare.LoganSquare;
|
import com.bluelinelabs.logansquare.LoganSquare;
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
import com.nextcloud.talk.activities.MagicCallActivity;
|
|
||||||
import com.nextcloud.talk.api.NcApi;
|
import com.nextcloud.talk.api.NcApi;
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
import com.nextcloud.talk.controllers.base.BaseController;
|
import com.nextcloud.talk.controllers.base.BaseController;
|
||||||
@ -714,7 +713,6 @@ public class OperationsMenuController extends BaseController {
|
|||||||
eventBus.post(new BottomSheetLockEvent(true, 0,
|
eventBus.post(new BottomSheetLockEvent(true, 0,
|
||||||
true, true, dismissView));
|
true, true, dismissView));
|
||||||
|
|
||||||
Intent conversationIntent = new Intent(getActivity(), MagicCallActivity.class);
|
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), conversation.getToken());
|
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), conversation.getToken());
|
||||||
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), conversation.getRoomId());
|
bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), conversation.getRoomId());
|
||||||
@ -723,8 +721,6 @@ public class OperationsMenuController extends BaseController {
|
|||||||
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_ACTIVE_CONVERSATION(), Parcels.wrap(conversation));
|
bundle.putParcelable(BundleKeys.INSTANCE.getKEY_ACTIVE_CONVERSATION(), Parcels.wrap(conversation));
|
||||||
bundle.putString(BundleKeys.INSTANCE.getKEY_CONVERSATION_PASSWORD(), callPassword);
|
bundle.putString(BundleKeys.INSTANCE.getKEY_CONVERSATION_PASSWORD(), callPassword);
|
||||||
|
|
||||||
conversationIntent.putExtras(bundle);
|
|
||||||
|
|
||||||
if (getParentController() != null) {
|
if (getParentController() != null) {
|
||||||
ConductorRemapping.INSTANCE.remapChatController(getParentController().getRouter(), currentUser.getId(),
|
ConductorRemapping.INSTANCE.remapChatController(getParentController().getRouter(), currentUser.getId(),
|
||||||
conversation.getToken(), bundle, true);
|
conversation.getToken(), bundle, true);
|
||||||
|
@ -33,7 +33,6 @@ import com.nextcloud.talk.utils.ApiUtils;
|
|||||||
import com.nextcloud.talk.utils.LoggingUtils;
|
import com.nextcloud.talk.utils.LoggingUtils;
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils;
|
import com.nextcloud.talk.utils.database.user.UserUtils;
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||||
import com.nextcloud.talk.utils.singletons.AvatarStatusCodeHolder;
|
|
||||||
import com.nextcloud.talk.utils.ssl.MagicKeyManager;
|
import com.nextcloud.talk.utils.ssl.MagicKeyManager;
|
||||||
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
import com.nextcloud.talk.utils.ssl.MagicTrustManager;
|
||||||
import com.nextcloud.talk.utils.ssl.SSLSocketFactoryCompat;
|
import com.nextcloud.talk.utils.ssl.SSLSocketFactoryCompat;
|
||||||
@ -253,10 +252,6 @@ public class RestModule {
|
|||||||
|
|
||||||
Response response = chain.proceed(request);
|
Response response = chain.proceed(request);
|
||||||
|
|
||||||
if (request.url().encodedPath().contains("/avatar/")) {
|
|
||||||
AvatarStatusCodeHolder.getInstance().setStatusCode(response.code());
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ import com.facebook.imagepipeline.image.CloseableImage;
|
|||||||
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor;
|
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor;
|
||||||
import com.facebook.imagepipeline.request.ImageRequest;
|
import com.facebook.imagepipeline.request.ImageRequest;
|
||||||
import com.nextcloud.talk.R;
|
import com.nextcloud.talk.R;
|
||||||
import com.nextcloud.talk.activities.MagicCallActivity;
|
import com.nextcloud.talk.activities.CallActivity;
|
||||||
import com.nextcloud.talk.activities.MainActivity;
|
import com.nextcloud.talk.activities.MainActivity;
|
||||||
import com.nextcloud.talk.api.NcApi;
|
import com.nextcloud.talk.api.NcApi;
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||||
@ -590,7 +590,7 @@ public class NotificationWorker extends Worker {
|
|||||||
|
|
||||||
boolean startACall = decryptedPushMessage.getType().equals("call");
|
boolean startACall = decryptedPushMessage.getType().equals("call");
|
||||||
if (startACall) {
|
if (startACall) {
|
||||||
intent = new Intent(context, MagicCallActivity.class);
|
intent = new Intent(context, CallActivity.class);
|
||||||
} else {
|
} else {
|
||||||
intent = new Intent(context, MainActivity.class);
|
intent = new Intent(context, MainActivity.class);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public class ApplicationWideCurrentRoomHolder {
|
|||||||
private String currentRoomToken = "";
|
private String currentRoomToken = "";
|
||||||
private UserEntity userInRoom = new UserEntity();
|
private UserEntity userInRoom = new UserEntity();
|
||||||
private boolean inCall = false;
|
private boolean inCall = false;
|
||||||
|
private boolean isDialing = false;
|
||||||
private String session = "";
|
private String session = "";
|
||||||
|
|
||||||
public static ApplicationWideCurrentRoomHolder getInstance() {
|
public static ApplicationWideCurrentRoomHolder getInstance() {
|
||||||
@ -38,6 +39,7 @@ public class ApplicationWideCurrentRoomHolder {
|
|||||||
currentRoomId = "";
|
currentRoomId = "";
|
||||||
userInRoom = new UserEntity();
|
userInRoom = new UserEntity();
|
||||||
inCall = false;
|
inCall = false;
|
||||||
|
isDialing = false;
|
||||||
currentRoomToken = "";
|
currentRoomToken = "";
|
||||||
session = "";
|
session = "";
|
||||||
}
|
}
|
||||||
@ -74,6 +76,14 @@ public class ApplicationWideCurrentRoomHolder {
|
|||||||
this.inCall = inCall;
|
this.inCall = inCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDialing() {
|
||||||
|
return isDialing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialing(boolean dialing) {
|
||||||
|
isDialing = dialing;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSession() {
|
public String getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M19,11h-8v6h8v-6zM23,19L23,4.98C23,3.88 22.1,3 21,3L3,3c-1.1,0 -2,0.88 -2,1.98L1,19c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2zM21,19.02L3,19.02L3,4.97h18v14.05z"/>
|
||||||
|
</vector>
|
@ -1,39 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
~ Nextcloud Talk application
|
|
||||||
~
|
|
||||||
~ @author Mario Danic
|
|
||||||
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
|
||||||
~
|
|
||||||
~ This program is free software: you can redistribute it and/or modify
|
|
||||||
~ it under the terms of the GNU General Public License as published by
|
|
||||||
~ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
~ at your option) any later version.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful,
|
|
||||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
~ GNU General Public License for more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License
|
|
||||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
tools:context=".activities.MagicCallActivity">
|
|
||||||
|
|
||||||
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
|
||||||
android:id="@+id/controller_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
|
||||||
android:id="@+id/chatControllerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
@ -28,7 +28,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".activities.MagicCallActivity">
|
tools:context=".activities.CallActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/linearWrapperLayout"
|
android:id="@+id/linearWrapperLayout"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/conversationRelativeLayoutView"
|
android:id="@+id/conversationRelativeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@ -55,12 +55,12 @@
|
|||||||
android:stretchMode="columnWidth" />
|
android:stretchMode="columnWidth" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/selfVideoView"
|
android:id="@+id/selfVideoViewWrapper"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<org.webrtc.SurfaceViewRenderer
|
<org.webrtc.SurfaceViewRenderer
|
||||||
android:id="@+id/pip_video_view"
|
android:id="@+id/selfVideoRenderer"
|
||||||
android:layout_width="@dimen/large_preview_dimension"
|
android:layout_width="@dimen/large_preview_dimension"
|
||||||
android:layout_height="150dp"
|
android:layout_height="150dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
@ -70,7 +70,7 @@
|
|||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/call_control_switch_camera"
|
android:id="@+id/switchSelfVideoButton"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:layout_gravity="center_horizontal|bottom"
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
@ -89,7 +89,7 @@
|
|||||||
android:paddingTop="20dp">
|
android:paddingTop="20dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/callVoiceOrVideoTextView"
|
android:id="@+id/callModeTextView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
@ -122,6 +122,7 @@
|
|||||||
android:layout_centerVertical="true" />
|
android:layout_centerVertical="true" />
|
||||||
|
|
||||||
<include
|
<include
|
||||||
|
android:id="@+id/callStates"
|
||||||
layout="@layout/call_states"
|
layout="@layout/call_states"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -132,7 +133,7 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/callControlsLinearLayout"
|
android:id="@+id/callControls"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/call_controls_height"
|
android:layout_height="@dimen/call_controls_height"
|
||||||
android:layout_alignBottom="@id/linearWrapperLayout"
|
android:layout_alignBottom="@id/linearWrapperLayout"
|
||||||
@ -142,18 +143,17 @@
|
|||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/callControlToggleChat"
|
android:id="@+id/pictureInPictureButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="40dp"
|
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:elevation="10dp"
|
android:elevation="10dp"
|
||||||
app:backgroundImage="@color/call_buttons_background"
|
app:backgroundImage="@color/call_buttons_background"
|
||||||
app:placeholderImage="@drawable/ic_comment_white"
|
app:placeholderImage="@drawable/ic_baseline_picture_in_picture_alt_24"
|
||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/callControlEnableSpeaker"
|
android:id="@+id/speakerButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
@ -163,7 +163,7 @@
|
|||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/call_control_camera"
|
android:id="@+id/cameraButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
@ -174,7 +174,7 @@
|
|||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/call_control_microphone"
|
android:id="@+id/microphoneButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
@ -185,14 +185,46 @@
|
|||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/callControlHangupView"
|
android:id="@+id/hangupButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginEnd="40dp"
|
android:layout_marginEnd="10dp"
|
||||||
app:backgroundImage="@color/nc_darkRed"
|
app:backgroundImage="@color/nc_darkRed"
|
||||||
app:placeholderImage="@drawable/ic_call_end_white_24px"
|
app:placeholderImage="@drawable/ic_call_end_white_24px"
|
||||||
app:roundAsCircle="true" />
|
app:roundAsCircle="true" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/pipGroupCallOverlay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="invisible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pipCallConversationNameTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="-30dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:maxLines="3"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="our group call" />
|
||||||
|
|
||||||
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
app:backgroundImage="@drawable/ic_circular_group"
|
||||||
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -22,19 +22,13 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/controllerCallNotificationLayout"
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/backgroundImageView"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@null"
|
android:background="@color/grey950">
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@color/grey950"
|
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/callAnswerButtons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
@ -54,7 +48,7 @@
|
|||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/callControlHangupView"
|
android:id="@+id/hangupButton"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:layout_margin="24dp"
|
android:layout_margin="24dp"
|
||||||
@ -75,7 +69,7 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/incomingTextRelativeLayout"
|
android:id="@+id/incomingCallRelativeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
@ -119,10 +113,9 @@
|
|||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/avatarImageView"
|
android:id="@+id/avatarImageView"
|
||||||
android:layout_width="@dimen/avatar_size_very_big"
|
android:layout_width="@dimen/avatar_size_big"
|
||||||
android:layout_height="@dimen/avatar_size_very_big"
|
android:layout_height="@dimen/avatar_size_big"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
app:roundAsCircle="true"
|
app:roundAsCircle="true" />
|
||||||
tools:srcCompat="@tools:sample/avatars[0]" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -21,7 +21,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/callStateRelativeLayoutView"
|
android:id="@+id/callStateRelativeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
@ -40,19 +40,6 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
|
||||||
android:id="@+id/callControlToggleChat"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:elevation="10dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:backgroundImage="@color/call_buttons_background"
|
|
||||||
app:placeholderImage="@drawable/ic_call_black_24dp"
|
|
||||||
app:roundAsCircle="true"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -21,6 +21,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
<dimen name="activity_horizontal_margin">24dp</dimen>
|
<dimen name="activity_horizontal_margin">24dp</dimen>
|
||||||
|
|
||||||
<dimen name="avatar_size_very_big">120dp</dimen>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -33,8 +33,6 @@
|
|||||||
<dimen name="avatar_size">40dp</dimen>
|
<dimen name="avatar_size">40dp</dimen>
|
||||||
<dimen name="avatar_size_app_bar">30dp</dimen>
|
<dimen name="avatar_size_app_bar">30dp</dimen>
|
||||||
<dimen name="avatar_size_big">96dp</dimen>
|
<dimen name="avatar_size_big">96dp</dimen>
|
||||||
<dimen name="avatar_size_very_big">@dimen/avatar_fetching_size_very_big</dimen>
|
|
||||||
<dimen name="avatar_fetching_size_very_big">180dp</dimen>
|
|
||||||
|
|
||||||
<dimen name="chat_text_size">14sp</dimen>
|
<dimen name="chat_text_size">14sp</dimen>
|
||||||
<dimen name="message_bubble_corners_radius">6dp</dimen>
|
<dimen name="message_bubble_corners_radius">6dp</dimen>
|
||||||
|
@ -221,6 +221,10 @@
|
|||||||
<string name="nc_call_state_with_phone">%1$s with phone</string>
|
<string name="nc_call_state_with_phone">%1$s with phone</string>
|
||||||
<string name="nc_call_state_with_video">%1$s with video</string>
|
<string name="nc_call_state_with_video">%1$s with video</string>
|
||||||
|
|
||||||
|
<!-- Picture in Picture -->
|
||||||
|
<string name="nc_pip_microphone_mute">Mute microphone</string>
|
||||||
|
<string name="nc_pip_microphone_unmute">Enable microphone</string>
|
||||||
|
|
||||||
<!-- Notification channels -->
|
<!-- Notification channels -->
|
||||||
<string name="nc_notification_channel">%1$s on %2$s notification channel</string>
|
<string name="nc_notification_channel">%1$s on %2$s notification channel</string>
|
||||||
<string name="nc_notification_channel_calls">Calls notification channel</string>
|
<string name="nc_notification_channel_calls">Calls notification channel</string>
|
||||||
@ -468,4 +472,5 @@
|
|||||||
<string name="filename_progress">%1$s (%2$d)</string>
|
<string name="filename_progress">%1$s (%2$d)</string>
|
||||||
<string name="nc_dialog_invalid_password">Invalid password</string>
|
<string name="nc_dialog_invalid_password">Invalid password</string>
|
||||||
<string name="nc_dialog_reauth_or_delete">Do you want to reauthorize or delete this account?</string>
|
<string name="nc_dialog_reauth_or_delete">Do you want to reauthorize or delete this account?</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -51,10 +51,6 @@
|
|||||||
<item name="iconTint">@color/fontAppbar</item>
|
<item name="iconTint">@color/fontAppbar</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="CallTheme" parent="AppTheme">
|
|
||||||
<item name="android:navigationBarColor">@color/grey950</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="BottomNavigationView" parent="@style/Widget.MaterialComponents.BottomNavigationView">
|
<style name="BottomNavigationView" parent="@style/Widget.MaterialComponents.BottomNavigationView">
|
||||||
<item name="elevation">1dp</item>
|
<item name="elevation">1dp</item>
|
||||||
</style>
|
</style>
|
||||||
@ -187,6 +183,13 @@
|
|||||||
<item name="android:navigationBarColor">@color/colorPrimary</item>
|
<item name="android:navigationBarColor">@color/colorPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- Call Launch screen -->
|
||||||
|
<style name="AppTheme.CallLauncher">
|
||||||
|
<item name="android:windowBackground">@color/grey950</item>
|
||||||
|
<item name="android:statusBarColor">@color/grey950</item>
|
||||||
|
<item name="android:navigationBarColor">@color/grey950</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="Nextcloud.Material.TextButton" parent="Widget.MaterialComponents.Button.TextButton.Icon">
|
<style name="Nextcloud.Material.TextButton" parent="Widget.MaterialComponents.Button.TextButton.Icon">
|
||||||
<item name="android:typeface">sans</item>
|
<item name="android:typeface">sans</item>
|
||||||
<item name="android:textStyle">bold</item>
|
<item name="android:textStyle">bold</item>
|
||||||
|
@ -1 +1 @@
|
|||||||
569
|
568
|
@ -1,2 +1,2 @@
|
|||||||
DO NOT TOUCH; GENERATED BY DRONE
|
DO NOT TOUCH; GENERATED BY DRONE
|
||||||
<span class="mdl-layout-title">Lint Report: 1 error and 269 warnings</span>
|
<span class="mdl-layout-title">Lint Report: 1 error and 238 warnings</span>
|
||||||
|
Loading…
Reference in New Issue
Block a user