mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
Avoid to send conversation and user via intent
sending too much data via intent always is a bad pattern which can lead to TransactionTooLargeException. When OpenAI translation is enabled, the capabilities contain a ton of translation combinations. These capabilities are contained in 'currentUser' as well in 'selectedConversation'. So, TransactionTooLargeException was thrown. this PR: - avoids passing too much data as parcelables in intents (esp. conversation and user) - introduces MVVM patterns to load required data (esp conversation) from backend (for now via requests, in the future from database first) - introduces ConversationModel which is created out of the Conversation json model - loads user data via injection when possible - creates some quickfixes in ConversationBottomDialog, EntryMenuController and OperationsMenuController. Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
e4c06d8ee8
commit
817ea1ab64
@ -140,7 +140,7 @@
|
|||||||
android:theme="@style/AppTheme.CallLauncher" />
|
android:theme="@style/AppTheme.CallLauncher" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.CallNotificationActivity"
|
android:name=".callnotification.CallNotificationActivity"
|
||||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
|
@ -100,6 +100,7 @@ import com.nextcloud.talk.utils.NotificationUtils;
|
|||||||
import com.nextcloud.talk.utils.VibrationUtils;
|
import com.nextcloud.talk.utils.VibrationUtils;
|
||||||
import com.nextcloud.talk.utils.animations.PulseAnimation;
|
import com.nextcloud.talk.utils.animations.PulseAnimation;
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew;
|
||||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil;
|
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil;
|
||||||
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder;
|
||||||
@ -186,7 +187,6 @@ import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID;
|
|||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM;
|
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM;
|
||||||
import static com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY;
|
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication.class)
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
public class CallActivity extends CallBaseActivity {
|
public class CallActivity extends CallBaseActivity {
|
||||||
@ -199,6 +199,9 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
@Inject
|
@Inject
|
||||||
NcApi ncApi;
|
NcApi ncApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CurrentUserProviderNew currentUserProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
UserManager userManager;
|
UserManager userManager;
|
||||||
|
|
||||||
@ -386,10 +389,11 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
|
|
||||||
hideNavigationIfNoPipAvailable();
|
hideNavigationIfNoPipAvailable();
|
||||||
|
|
||||||
|
conversationUser = currentUserProvider.getCurrentUser().blockingGet();
|
||||||
|
|
||||||
Bundle extras = getIntent().getExtras();
|
Bundle extras = getIntent().getExtras();
|
||||||
roomId = extras.getString(KEY_ROOM_ID, "");
|
roomId = extras.getString(KEY_ROOM_ID, "");
|
||||||
roomToken = extras.getString(KEY_ROOM_TOKEN, "");
|
roomToken = extras.getString(KEY_ROOM_TOKEN, "");
|
||||||
conversationUser = extras.getParcelable(KEY_USER_ENTITY);
|
|
||||||
conversationPassword = extras.getString(KEY_CONVERSATION_PASSWORD, "");
|
conversationPassword = extras.getString(KEY_CONVERSATION_PASSWORD, "");
|
||||||
conversationName = extras.getString(KEY_CONVERSATION_NAME, "");
|
conversationName = extras.getString(KEY_CONVERSATION_NAME, "");
|
||||||
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false);
|
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false);
|
||||||
@ -1970,7 +1974,6 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
bundle.putBoolean(KEY_SWITCH_TO_ROOM, true);
|
bundle.putBoolean(KEY_SWITCH_TO_ROOM, true);
|
||||||
bundle.putBoolean(KEY_START_CALL_AFTER_ROOM_SWITCH, true);
|
bundle.putBoolean(KEY_START_CALL_AFTER_ROOM_SWITCH, true);
|
||||||
bundle.putString(KEY_ROOM_TOKEN, switchToRoomToken);
|
bundle.putString(KEY_ROOM_TOKEN, switchToRoomToken);
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser);
|
|
||||||
bundle.putBoolean(KEY_CALL_VOICE_ONLY, isVoiceOnlyCall);
|
bundle.putBoolean(KEY_CALL_VOICE_ONLY, isVoiceOnlyCall);
|
||||||
intent.putExtras(bundle);
|
intent.putExtras(bundle);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
@ -3151,7 +3154,7 @@ public class CallActivity extends CallBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void suppressFitsSystemWindows() {
|
public void suppressFitsSystemWindows() {
|
||||||
binding.controllerCallLayout.setFitsSystemWindows(false);
|
binding.controllerCallLayout.setFitsSystemWindows(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public abstract class CallBaseActivity extends BaseActivity {
|
|||||||
getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
|
getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideNavigationIfNoPipAvailable(){
|
public void hideNavigationIfNoPipAvailable(){
|
||||||
if (!isPipModePossible()) {
|
if (!isPipModePossible()) {
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
@ -160,9 +160,9 @@ public abstract class CallBaseActivity extends BaseActivity {
|
|||||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void updateUiForPipMode();
|
public abstract void updateUiForPipMode();
|
||||||
|
|
||||||
abstract void updateUiForNormalMode();
|
public abstract void updateUiForNormalMode();
|
||||||
|
|
||||||
abstract void suppressFitsSystemWindows();
|
public abstract void suppressFitsSystemWindows();
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ import com.nextcloud.talk.BuildConfig
|
|||||||
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.callnotification.CallNotificationActivity
|
||||||
import com.nextcloud.talk.chat.ChatActivity
|
import com.nextcloud.talk.chat.ChatActivity
|
||||||
import com.nextcloud.talk.controllers.ServerSelectionController
|
import com.nextcloud.talk.controllers.ServerSelectionController
|
||||||
import com.nextcloud.talk.controllers.WebViewLoginController
|
import com.nextcloud.talk.controllers.WebViewLoginController
|
||||||
@ -61,16 +62,13 @@ import com.nextcloud.talk.utils.ApiUtils
|
|||||||
import com.nextcloud.talk.utils.SecurityUtils
|
import com.nextcloud.talk.utils.SecurityUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.ADD_ACCOUNT
|
import com.nextcloud.talk.utils.bundle.BundleKeys.ADD_ACCOUNT
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.SingleObserver
|
import io.reactivex.SingleObserver
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import org.parceler.Parcels
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
@ -282,45 +280,12 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, currentUser)
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
|
|
||||||
// FIXME once APIv2 or later is used only, the createRoom already returns all the data
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
ncApi.getRoom(
|
chatIntent.putExtras(bundle)
|
||||||
credentials,
|
startActivity(chatIntent)
|
||||||
ApiUtils.getUrlForRoom(
|
|
||||||
apiVersion,
|
|
||||||
currentUser?.baseUrl,
|
|
||||||
roomOverall.ocs!!.data!!.token
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
bundle.putParcelable(
|
|
||||||
KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(roomOverall.ocs!!.data)
|
|
||||||
)
|
|
||||||
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
|
||||||
chatIntent.putExtras(bundle)
|
|
||||||
startActivity(chatIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
@ -337,7 +302,9 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
Log.d(TAG, "onNewIntent Activity: " + System.identityHashCode(this).toString())
|
Log.d(TAG, "onNewIntent Activity: " + System.identityHashCode(this).toString())
|
||||||
|
|
||||||
val user = intent.getParcelableExtra<User>(KEY_USER_ENTITY)
|
val internalUserId = intent.extras?.getLong(BundleKeys.KEY_INTERNAL_USER_ID)
|
||||||
|
val user = userManager.getUserWithId(internalUserId!!).blockingGet()
|
||||||
|
|
||||||
if (user != null && userManager.setUserAsActive(user).blockingGet()) {
|
if (user != null && userManager.setUserAsActive(user).blockingGet()) {
|
||||||
handleIntent(intent)
|
handleIntent(intent)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.activities
|
package com.nextcloud.talk.callnotification
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -30,36 +30,36 @@ import android.os.Handler
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import autodagger.AutoInjector
|
import autodagger.AutoInjector
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
|
import com.nextcloud.talk.activities.CallActivity
|
||||||
|
import com.nextcloud.talk.activities.CallBaseActivity
|
||||||
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
|
||||||
|
import com.nextcloud.talk.callnotification.viewmodel.CallNotificationViewModel
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.databinding.CallNotificationActivityBinding
|
import com.nextcloud.talk.databinding.CallNotificationActivityBinding
|
||||||
import com.nextcloud.talk.extensions.loadUserAvatar
|
import com.nextcloud.talk.extensions.loadUserAvatar
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
import com.nextcloud.talk.models.json.participants.Participant
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
import com.nextcloud.talk.users.UserManager
|
import com.nextcloud.talk.users.UserManager
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
|
import com.nextcloud.talk.utils.ConversationUtils
|
||||||
import com.nextcloud.talk.utils.NotificationUtils
|
import com.nextcloud.talk.utils.NotificationUtils
|
||||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||||
import io.reactivex.Observer
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
|
||||||
import okhttp3.Cache
|
import okhttp3.Cache
|
||||||
import org.parceler.Parcels
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -77,13 +77,18 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var userManager: UserManager
|
lateinit var userManager: UserManager
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
|
lateinit var callNotificationViewModel: CallNotificationViewModel
|
||||||
|
|
||||||
private val disposablesList: MutableList<Disposable> = ArrayList()
|
private val disposablesList: MutableList<Disposable> = ArrayList()
|
||||||
private var originalBundle: Bundle? = null
|
private var originalBundle: Bundle? = null
|
||||||
private var roomToken: String? = null
|
private var roomToken: String? = null
|
||||||
private var notificationTimestamp: Int? = null
|
private var notificationTimestamp: Int? = null
|
||||||
private var userBeingCalled: User? = null
|
private var userBeingCalled: User? = null
|
||||||
private var credentials: String? = null
|
private var credentials: String? = null
|
||||||
private var currentConversation: Conversation? = null
|
var currentConversation: ConversationModel? = null
|
||||||
private var leavingScreen = false
|
private var leavingScreen = false
|
||||||
private var handler: Handler? = null
|
private var handler: Handler? = null
|
||||||
private var binding: CallNotificationActivityBinding? = null
|
private var binding: CallNotificationActivityBinding? = null
|
||||||
@ -98,19 +103,20 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
val extras = intent.extras
|
val extras = intent.extras
|
||||||
roomToken = extras!!.getString(KEY_ROOM_TOKEN, "")
|
roomToken = extras!!.getString(KEY_ROOM_TOKEN, "")
|
||||||
notificationTimestamp = extras.getInt(BundleKeys.KEY_NOTIFICATION_TIMESTAMP)
|
notificationTimestamp = extras.getInt(BundleKeys.KEY_NOTIFICATION_TIMESTAMP)
|
||||||
currentConversation = Parcels.unwrap(extras.getParcelable(KEY_ROOM))
|
|
||||||
userBeingCalled = extras.getParcelable(KEY_USER_ENTITY)
|
val internalUserId = extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID)
|
||||||
|
userBeingCalled = userManager.getUserWithId(internalUserId).blockingGet()
|
||||||
|
|
||||||
originalBundle = extras
|
originalBundle = extras
|
||||||
credentials = ApiUtils.getCredentials(userBeingCalled!!.username, userBeingCalled!!.token)
|
credentials = ApiUtils.getCredentials(userBeingCalled!!.username, userBeingCalled!!.token)
|
||||||
|
|
||||||
|
callNotificationViewModel = ViewModelProvider(this, viewModelFactory)[CallNotificationViewModel::class.java]
|
||||||
|
|
||||||
|
initObservers()
|
||||||
|
|
||||||
if (userManager.setUserAsActive(userBeingCalled!!).blockingGet()) {
|
if (userManager.setUserAsActive(userBeingCalled!!).blockingGet()) {
|
||||||
setCallDescriptionText()
|
setCallDescriptionText()
|
||||||
if (currentConversation == null) {
|
callNotificationViewModel.getRoom(userBeingCalled!!, roomToken!!)
|
||||||
handleFromNotification()
|
|
||||||
} else {
|
|
||||||
setUpAfterConversationIsKnown()
|
|
||||||
}
|
|
||||||
initClickListeners()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +146,78 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
binding!!.hangupButton.setOnClickListener { hangup() }
|
binding!!.hangupButton.setOnClickListener { hangup() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initObservers() {
|
||||||
|
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||||
|
userBeingCalled,
|
||||||
|
intArrayOf(
|
||||||
|
ApiUtils.APIv4,
|
||||||
|
ApiUtils.APIv3,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
callNotificationViewModel.getRoomViewState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
is CallNotificationViewModel.GetRoomSuccessState -> {
|
||||||
|
currentConversation = state.conversationModel
|
||||||
|
|
||||||
|
binding!!.conversationNameTextView.text = currentConversation!!.displayName
|
||||||
|
if (currentConversation!!.type === ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
||||||
|
binding!!.avatarImageView.loadUserAvatar(
|
||||||
|
userBeingCalled!!,
|
||||||
|
currentConversation!!.name!!,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
binding!!.avatarImageView.setImageResource(R.drawable.ic_circular_group)
|
||||||
|
}
|
||||||
|
|
||||||
|
val notificationHandler = Handler(Looper.getMainLooper())
|
||||||
|
notificationHandler.post(object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
if (NotificationUtils.isNotificationVisible(context, notificationTimestamp!!.toInt())) {
|
||||||
|
notificationHandler.postDelayed(this, ONE_SECOND)
|
||||||
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
showAnswerControls()
|
||||||
|
|
||||||
|
if (apiVersion >= ApiUtils.APIv3) {
|
||||||
|
val hasCallFlags = hasSpreedFeatureCapability(
|
||||||
|
userBeingCalled,
|
||||||
|
"conversation-call-flags"
|
||||||
|
)
|
||||||
|
if (hasCallFlags) {
|
||||||
|
if (isInCallWithVideo(currentConversation!!.callFlag)) {
|
||||||
|
binding!!.incomingCallVoiceOrVideoTextView.text = String.format(
|
||||||
|
resources.getString(R.string.nc_call_video),
|
||||||
|
resources.getString(R.string.nc_app_product_name)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
binding!!.incomingCallVoiceOrVideoTextView.text = String.format(
|
||||||
|
resources.getString(R.string.nc_call_voice),
|
||||||
|
resources.getString(R.string.nc_app_product_name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initClickListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
is CallNotificationViewModel.GetRoomErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setCallDescriptionText() {
|
private fun setCallDescriptionText() {
|
||||||
val callDescriptionWithoutTypeInfo = String.format(
|
val callDescriptionWithoutTypeInfo = String.format(
|
||||||
resources.getString(R.string.nc_call_unknown),
|
resources.getString(R.string.nc_call_unknown),
|
||||||
@ -178,7 +256,7 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
)
|
)
|
||||||
originalBundle!!.putBoolean(
|
originalBundle!!.putBoolean(
|
||||||
BundleKeys.KEY_IS_MODERATOR,
|
BundleKeys.KEY_IS_MODERATOR,
|
||||||
currentConversation!!.isParticipantOwnerOrModerator
|
ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!)
|
||||||
)
|
)
|
||||||
|
|
||||||
val intent = Intent(this, CallActivity::class.java)
|
val intent = Intent(this, CallActivity::class.java)
|
||||||
@ -189,85 +267,10 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
|
||||||
private fun handleFromNotification() {
|
|
||||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
|
||||||
userBeingCalled,
|
|
||||||
intArrayOf(
|
|
||||||
ApiUtils.APIv4,
|
|
||||||
ApiUtils.APIv3,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ncApi!!.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, userBeingCalled!!.baseUrl, roomToken))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.retry(GET_ROOM_RETRY_COUNT)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
disposablesList.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
currentConversation = roomOverall.ocs!!.data
|
|
||||||
setUpAfterConversationIsKnown()
|
|
||||||
if (apiVersion >= 3) {
|
|
||||||
val hasCallFlags = hasSpreedFeatureCapability(
|
|
||||||
userBeingCalled,
|
|
||||||
"conversation-call-flags"
|
|
||||||
)
|
|
||||||
if (hasCallFlags) {
|
|
||||||
if (isInCallWithVideo(currentConversation!!.callFlag)) {
|
|
||||||
binding!!.incomingCallVoiceOrVideoTextView.text = String.format(
|
|
||||||
resources.getString(R.string.nc_call_video),
|
|
||||||
resources.getString(R.string.nc_app_product_name)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binding!!.incomingCallVoiceOrVideoTextView.text = String.format(
|
|
||||||
resources.getString(R.string.nc_call_voice),
|
|
||||||
resources.getString(R.string.nc_app_product_name)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, e.message, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isInCallWithVideo(callFlag: Int): Boolean {
|
private fun isInCallWithVideo(callFlag: Int): Boolean {
|
||||||
return (callFlag and Participant.InCallFlags.WITH_VIDEO) > 0
|
return (callFlag and Participant.InCallFlags.WITH_VIDEO) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpAfterConversationIsKnown() {
|
|
||||||
binding!!.conversationNameTextView.text = currentConversation!!.displayName
|
|
||||||
if (currentConversation!!.type === Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
|
|
||||||
binding!!.avatarImageView.loadUserAvatar(userBeingCalled!!, currentConversation!!.name!!, true, false)
|
|
||||||
} else {
|
|
||||||
binding!!.avatarImageView.setImageResource(R.drawable.ic_circular_group)
|
|
||||||
}
|
|
||||||
|
|
||||||
val notificationHandler = Handler(Looper.getMainLooper())
|
|
||||||
notificationHandler.post(object : Runnable {
|
|
||||||
override fun run() {
|
|
||||||
if (NotificationUtils.isNotificationVisible(context, notificationTimestamp!!.toInt())) {
|
|
||||||
notificationHandler.postDelayed(this, ONE_SECOND)
|
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
showAnswerControls()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
val notificationManager = NotificationManagerCompat.from(context)
|
val notificationManager = NotificationManagerCompat.from(context)
|
||||||
notificationManager.cancel(notificationTimestamp!!)
|
notificationManager.cancel(notificationTimestamp!!)
|
||||||
@ -303,23 +306,22 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun updateUiForPipMode() {
|
override fun updateUiForPipMode() {
|
||||||
binding!!.callAnswerButtons.visibility = View.INVISIBLE
|
binding!!.callAnswerButtons.visibility = View.INVISIBLE
|
||||||
binding!!.incomingCallRelativeLayout.visibility = View.INVISIBLE
|
binding!!.incomingCallRelativeLayout.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun updateUiForNormalMode() {
|
override fun updateUiForNormalMode() {
|
||||||
binding!!.callAnswerButtons.visibility = View.VISIBLE
|
binding!!.callAnswerButtons.visibility = View.VISIBLE
|
||||||
binding!!.incomingCallRelativeLayout.visibility = View.VISIBLE
|
binding!!.incomingCallRelativeLayout.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun suppressFitsSystemWindows() {
|
override fun suppressFitsSystemWindows() {
|
||||||
binding!!.controllerCallNotificationLayout.fitsSystemWindows = false
|
binding!!.controllerCallNotificationLayout.fitsSystemWindows = false
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "CallNotificationActivity"
|
const val TAG = "CallNotificationActivity"
|
||||||
const val GET_ROOM_RETRY_COUNT: Long = 3
|
|
||||||
const val ONE_SECOND: Long = 1000
|
const val ONE_SECOND: Long = 1000
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.callnotification.viewmodel
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.chat.data.ChatRepository
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class CallNotificationViewModel @Inject constructor(private val repository: ChatRepository) :
|
||||||
|
ViewModel() {
|
||||||
|
|
||||||
|
sealed interface ViewState
|
||||||
|
|
||||||
|
object GetRoomStartState : ViewState
|
||||||
|
object GetRoomErrorState : ViewState
|
||||||
|
open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
private val _getRoomViewState: MutableLiveData<ViewState> = MutableLiveData(GetRoomStartState)
|
||||||
|
val getRoomViewState: LiveData<ViewState>
|
||||||
|
get() = _getRoomViewState
|
||||||
|
|
||||||
|
fun getRoom(user: User, token: String) {
|
||||||
|
_getRoomViewState.value = GetRoomStartState
|
||||||
|
repository.getRoom(user, token)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(GetRoomObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class GetRoomObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_getRoomViewState.value = GetRoomSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when fetching room")
|
||||||
|
_getRoomViewState.value = GetRoomErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = CallNotificationViewModel::class.simpleName
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,6 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Parcelable
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
@ -85,6 +84,7 @@ import androidx.core.text.bold
|
|||||||
import androidx.core.widget.doAfterTextChanged
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import androidx.emoji2.text.EmojiCompat
|
import androidx.emoji2.text.EmojiCompat
|
||||||
import androidx.emoji2.widget.EmojiTextView
|
import androidx.emoji2.widget.EmojiTextView
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@ -130,6 +130,7 @@ import com.nextcloud.talk.adapters.messages.VoiceMessageInterface
|
|||||||
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.callbacks.MentionAutocompleteCallback
|
import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
|
||||||
|
import com.nextcloud.talk.chat.viewmodels.ChatViewModel
|
||||||
import com.nextcloud.talk.conversationinfo.ConversationInfoActivity
|
import com.nextcloud.talk.conversationinfo.ConversationInfoActivity
|
||||||
import com.nextcloud.talk.conversationlist.ConversationsListActivity
|
import com.nextcloud.talk.conversationlist.ConversationsListActivity
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
@ -142,15 +143,18 @@ import com.nextcloud.talk.jobs.ShareOperationWorker
|
|||||||
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
|
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
|
||||||
import com.nextcloud.talk.location.LocationPickerActivity
|
import com.nextcloud.talk.location.LocationPickerActivity
|
||||||
import com.nextcloud.talk.messagesearch.MessageSearchActivity
|
import com.nextcloud.talk.messagesearch.MessageSearchActivity
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationReadOnlyState
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
|
import com.nextcloud.talk.models.domain.LobbyState
|
||||||
|
import com.nextcloud.talk.models.domain.ObjectType
|
||||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.chat.ChatOverall
|
import com.nextcloud.talk.models.json.chat.ChatOverall
|
||||||
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
|
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage
|
||||||
import com.nextcloud.talk.models.json.chat.ReadStatus
|
import com.nextcloud.talk.models.json.chat.ReadStatus
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
import com.nextcloud.talk.models.json.mention.Mention
|
import com.nextcloud.talk.models.json.mention.Mention
|
||||||
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage
|
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage
|
||||||
@ -170,6 +174,7 @@ import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
|
|||||||
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
|
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.ContactUtils
|
import com.nextcloud.talk.utils.ContactUtils
|
||||||
|
import com.nextcloud.talk.utils.ConversationUtils
|
||||||
import com.nextcloud.talk.utils.DateConstants
|
import com.nextcloud.talk.utils.DateConstants
|
||||||
import com.nextcloud.talk.utils.DateUtils
|
import com.nextcloud.talk.utils.DateUtils
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
@ -181,7 +186,6 @@ import com.nextcloud.talk.utils.NotificationUtils
|
|||||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||||
import com.nextcloud.talk.utils.VibrationUtils
|
import com.nextcloud.talk.utils.VibrationUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS
|
||||||
@ -193,8 +197,8 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
|||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||||
import com.nextcloud.talk.utils.rx.DisposableSet
|
import com.nextcloud.talk.utils.rx.DisposableSet
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder
|
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder
|
||||||
@ -215,7 +219,6 @@ import io.reactivex.disposables.Disposable
|
|||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.parceler.Parcels
|
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -248,6 +251,9 @@ class ChatActivity :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var ncApi: NcApi
|
lateinit var ncApi: NcApi
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var currentUserProvider: CurrentUserProviderNew
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var reactionsRepository: ReactionsRepository
|
lateinit var reactionsRepository: ReactionsRepository
|
||||||
|
|
||||||
@ -257,6 +263,11 @@ class ChatActivity :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var dateUtils: DateUtils
|
lateinit var dateUtils: DateUtils
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
|
lateinit var chatViewModel: ChatViewModel
|
||||||
|
|
||||||
override val view: View
|
override val view: View
|
||||||
get() = binding.root
|
get() = binding.root
|
||||||
|
|
||||||
@ -267,7 +278,7 @@ class ChatActivity :
|
|||||||
var conversationUser: User? = null
|
var conversationUser: User? = null
|
||||||
private var roomPassword: String = ""
|
private var roomPassword: String = ""
|
||||||
var credentials: String? = null
|
var credentials: String? = null
|
||||||
var currentConversation: Conversation? = null
|
var currentConversation: ConversationModel? = null
|
||||||
private var globalLastKnownFutureMessageId = -1
|
private var globalLastKnownFutureMessageId = -1
|
||||||
private var globalLastKnownPastMessageId = -1
|
private var globalLastKnownPastMessageId = -1
|
||||||
var adapter: TalkMessagesListAdapter<ChatMessage>? = null
|
var adapter: TalkMessagesListAdapter<ChatMessage>? = null
|
||||||
@ -383,14 +394,17 @@ class ChatActivity :
|
|||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
setupSystemColors()
|
setupSystemColors()
|
||||||
|
|
||||||
|
conversationUser = currentUserProvider.currentUser.blockingGet()
|
||||||
|
|
||||||
handleIntent(intent)
|
handleIntent(intent)
|
||||||
|
|
||||||
|
chatViewModel = ViewModelProvider(this, viewModelFactory)[ChatViewModel::class.java]
|
||||||
|
|
||||||
binding.progressBar.visibility = View.VISIBLE
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
initAdapter()
|
|
||||||
binding.messagesListView.setAdapter(adapter)
|
|
||||||
|
|
||||||
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
||||||
|
|
||||||
|
initObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
@ -415,7 +429,6 @@ class ChatActivity :
|
|||||||
private fun handleIntent(intent: Intent) {
|
private fun handleIntent(intent: Intent) {
|
||||||
val extras: Bundle? = intent.extras
|
val extras: Bundle? = intent.extras
|
||||||
|
|
||||||
conversationUser = extras?.getParcelable(KEY_USER_ENTITY)
|
|
||||||
roomId = extras?.getString(KEY_ROOM_ID).orEmpty()
|
roomId = extras?.getString(KEY_ROOM_ID).orEmpty()
|
||||||
roomToken = extras?.getString(KEY_ROOM_TOKEN).orEmpty()
|
roomToken = extras?.getString(KEY_ROOM_TOKEN).orEmpty()
|
||||||
|
|
||||||
@ -426,11 +439,6 @@ class ChatActivity :
|
|||||||
Log.d(TAG, " roomToken was null or empty!")
|
Log.d(TAG, " roomToken was null or empty!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.hasExtra(KEY_ACTIVE_CONVERSATION)) {
|
|
||||||
currentConversation = Parcels.unwrap<Conversation>(extras?.getParcelable(KEY_ACTIVE_CONVERSATION))
|
|
||||||
participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
roomPassword = extras?.getString(BundleKeys.KEY_CONVERSATION_PASSWORD).orEmpty()
|
roomPassword = extras?.getString(BundleKeys.KEY_CONVERSATION_PASSWORD).orEmpty()
|
||||||
|
|
||||||
credentials = if (conversationUser?.userId == "?") {
|
credentials = if (conversationUser?.userId == "?") {
|
||||||
@ -455,6 +463,106 @@ class ChatActivity :
|
|||||||
active = false
|
active = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initObservers() {
|
||||||
|
chatViewModel.getRoomViewState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
is ChatViewModel.GetRoomSuccessState -> {
|
||||||
|
currentConversation = state.conversationModel
|
||||||
|
logConversationInfos("GetRoomSuccessState")
|
||||||
|
|
||||||
|
if (adapter == null) {
|
||||||
|
initAdapter()
|
||||||
|
binding.messagesListView.setAdapter(adapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutManager = binding.messagesListView.layoutManager as LinearLayoutManager?
|
||||||
|
|
||||||
|
loadAvatarForStatusBar()
|
||||||
|
setActionBarTitle()
|
||||||
|
participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!)
|
||||||
|
|
||||||
|
setupSwipeToReply()
|
||||||
|
setupMentionAutocomplete()
|
||||||
|
checkShowCallButtons()
|
||||||
|
checkShowMessageInputView()
|
||||||
|
checkLobbyState()
|
||||||
|
|
||||||
|
if (!validSessionId()) {
|
||||||
|
joinRoomWithPassword()
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "already inConversation. joinRoomWithPassword is skipped")
|
||||||
|
}
|
||||||
|
|
||||||
|
val delayForRecursiveCall = if (shouldShowLobby()) {
|
||||||
|
GET_ROOM_INFO_DELAY_LOBBY
|
||||||
|
} else {
|
||||||
|
GET_ROOM_INFO_DELAY_NORMAL
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getRoomInfoTimerHandler == null) {
|
||||||
|
getRoomInfoTimerHandler = Handler()
|
||||||
|
}
|
||||||
|
getRoomInfoTimerHandler?.postDelayed(
|
||||||
|
{
|
||||||
|
chatViewModel.getRoom(conversationUser!!, roomToken)
|
||||||
|
},
|
||||||
|
delayForRecursiveCall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ChatViewModel.GetRoomErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chatViewModel.joinRoomViewState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
is ChatViewModel.JoinRoomSuccessState -> {
|
||||||
|
currentConversation = state.conversationModel
|
||||||
|
|
||||||
|
sessionIdAfterRoomJoined = currentConversation!!.sessionId
|
||||||
|
ApplicationWideCurrentRoomHolder.getInstance().session = currentConversation!!.sessionId
|
||||||
|
ApplicationWideCurrentRoomHolder.getInstance().currentRoomId = currentConversation!!.roomId
|
||||||
|
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = currentConversation!!.token
|
||||||
|
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
|
||||||
|
|
||||||
|
logConversationInfos("joinRoomWithPassword#onNext")
|
||||||
|
|
||||||
|
if (isFirstMessagesProcessing) {
|
||||||
|
pullChatMessages(false)
|
||||||
|
} else {
|
||||||
|
pullChatMessages(true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webSocketInstance != null) {
|
||||||
|
webSocketInstance?.joinRoomWithRoomTokenAndSession(
|
||||||
|
roomToken,
|
||||||
|
sessionIdAfterRoomJoined
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (startCallFromNotification != null && startCallFromNotification ?: false) {
|
||||||
|
startCallFromNotification = false
|
||||||
|
startACall(voiceOnly, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startCallFromRoomSwitch) {
|
||||||
|
startCallFromRoomSwitch = false
|
||||||
|
startACall(voiceOnly, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ChatViewModel.JoinRoomErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
@ -484,18 +592,12 @@ class ChatActivity :
|
|||||||
|
|
||||||
cancelNotificationsForCurrentConversation()
|
cancelNotificationsForCurrentConversation()
|
||||||
|
|
||||||
if (TextUtils.isEmpty(roomToken)) {
|
chatViewModel.getRoom(conversationUser!!, roomToken)
|
||||||
handleFromNotification()
|
|
||||||
} else {
|
|
||||||
getRoomInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
actionBar?.show()
|
actionBar?.show()
|
||||||
|
|
||||||
setupSwipeToReply()
|
setupSwipeToReply()
|
||||||
|
|
||||||
layoutManager = binding?.messagesListView?.layoutManager as LinearLayoutManager?
|
|
||||||
|
|
||||||
binding?.popupBubbleView?.setRecyclerView(binding?.messagesListView)
|
binding?.popupBubbleView?.setRecyclerView(binding?.messagesListView)
|
||||||
|
|
||||||
binding?.popupBubbleView?.setPopupBubbleListener { context ->
|
binding?.popupBubbleView?.setPopupBubbleListener { context ->
|
||||||
@ -632,10 +734,8 @@ class ChatActivity :
|
|||||||
|
|
||||||
binding?.messageInputView?.button?.let { viewThemeUtils.platform.colorImageView(it, ColorRole.PRIMARY) }
|
binding?.messageInputView?.button?.let { viewThemeUtils.platform.colorImageView(it, ColorRole.PRIMARY) }
|
||||||
|
|
||||||
if (currentConversation != null && currentConversation?.roomId != null) {
|
loadAvatarForStatusBar()
|
||||||
loadAvatarForStatusBar()
|
setActionBarTitle()
|
||||||
setActionBarTitle()
|
|
||||||
}
|
|
||||||
|
|
||||||
viewThemeUtils.material.colorToolbarOverflowIcon(binding.chatToolbar)
|
viewThemeUtils.material.colorToolbarOverflowIcon(binding.chatToolbar)
|
||||||
}
|
}
|
||||||
@ -694,8 +794,11 @@ class ChatActivity :
|
|||||||
val messageHolders = MessageHolders()
|
val messageHolders = MessageHolders()
|
||||||
val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!)
|
val profileBottomSheet = ProfileBottomSheet(ncApi, conversationUser!!)
|
||||||
|
|
||||||
val payload =
|
val payload = MessagePayload(
|
||||||
MessagePayload(roomToken!!, currentConversation?.isParticipantOwnerOrModerator, profileBottomSheet)
|
roomToken,
|
||||||
|
ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!),
|
||||||
|
profileBottomSheet
|
||||||
|
)
|
||||||
|
|
||||||
messageHolders.setIncomingTextConfig(
|
messageHolders.setIncomingTextConfig(
|
||||||
IncomingTextMessageViewHolder::class.java,
|
IncomingTextMessageViewHolder::class.java,
|
||||||
@ -1080,68 +1183,6 @@ class ChatActivity :
|
|||||||
!CapabilitiesUtilNew.isTypingStatusPrivate(conversationUser!!)
|
!CapabilitiesUtilNew.isTypingStatusPrivate(conversationUser!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRoomInfo() {
|
|
||||||
logConversationInfos("getRoomInfo")
|
|
||||||
|
|
||||||
conversationUser?.let {
|
|
||||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
|
||||||
|
|
||||||
val startNanoTime = System.nanoTime()
|
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - calling: $startNanoTime")
|
|
||||||
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, it.baseUrl, roomToken))
|
|
||||||
?.subscribeOn(Schedulers.io())
|
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
?.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
disposables.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - got response: $startNanoTime")
|
|
||||||
currentConversation = roomOverall.ocs!!.data
|
|
||||||
|
|
||||||
logConversationInfos("getRoomInfo#onNext")
|
|
||||||
|
|
||||||
loadAvatarForStatusBar()
|
|
||||||
setActionBarTitle()
|
|
||||||
participantPermissions = ParticipantPermissions(it, currentConversation!!)
|
|
||||||
|
|
||||||
setupSwipeToReply()
|
|
||||||
setupMentionAutocomplete()
|
|
||||||
checkShowCallButtons()
|
|
||||||
checkShowMessageInputView()
|
|
||||||
checkLobbyState()
|
|
||||||
|
|
||||||
if (!validSessionId()) {
|
|
||||||
joinRoomWithPassword()
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "already inConversation. joinRoomWithPassword is skipped")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, "getRoomInfo - getRoom - ERROR", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - onComplete: $startNanoTime")
|
|
||||||
|
|
||||||
val delayForRecursiveCall = if (shouldShowLobby()) {
|
|
||||||
GET_ROOM_INFO_DELAY_LOBBY
|
|
||||||
} else {
|
|
||||||
GET_ROOM_INFO_DELAY_NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getRoomInfoTimerHandler == null) {
|
|
||||||
getRoomInfoTimerHandler = Handler()
|
|
||||||
}
|
|
||||||
getRoomInfoTimerHandler?.postDelayed({ getRoomInfo() }, delayForRecursiveCall)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupSwipeToReply() {
|
private fun setupSwipeToReply() {
|
||||||
if (this::participantPermissions.isInitialized &&
|
if (this::participantPermissions.isInitialized &&
|
||||||
participantPermissions.hasChatPermission() &&
|
participantPermissions.hasChatPermission() &&
|
||||||
@ -1162,46 +1203,11 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFromNotification() {
|
private fun loadAvatarForStatusBar() {
|
||||||
var apiVersion = 1
|
if (currentConversation == null) {
|
||||||
// FIXME Can this be called for guests?
|
return
|
||||||
if (conversationUser != null) {
|
|
||||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "handleFromNotification - getRooms - calling")
|
|
||||||
ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, conversationUser?.baseUrl), false)
|
|
||||||
?.subscribeOn(Schedulers.io())?.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
?.subscribe(object : Observer<RoomsOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
disposables.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomsOverall: RoomsOverall) {
|
|
||||||
Log.d(TAG, "handleFromNotification - getRooms - got response")
|
|
||||||
for (conversation in roomsOverall.ocs!!.data!!) {
|
|
||||||
if (roomId == conversation.roomId) {
|
|
||||||
roomToken = conversation.token!!
|
|
||||||
currentConversation = conversation
|
|
||||||
participantPermissions = ParticipantPermissions(conversationUser!!, currentConversation!!)
|
|
||||||
setActionBarTitle()
|
|
||||||
getRoomInfo()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, "handleFromNotification - getRooms - ERROR: ", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadAvatarForStatusBar() {
|
|
||||||
if (isOneToOneConversation()) {
|
if (isOneToOneConversation()) {
|
||||||
var url = ApiUtils.getUrlForAvatar(
|
var url = ApiUtils.getUrlForAvatar(
|
||||||
conversationUser!!.baseUrl,
|
conversationUser!!.baseUrl,
|
||||||
@ -1254,18 +1260,18 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isOneToOneConversation() = currentConversation != null && currentConversation?.type != null &&
|
fun isOneToOneConversation() = currentConversation != null && currentConversation?.type != null &&
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
||||||
|
|
||||||
private fun isGroupConversation() = currentConversation != null && currentConversation?.type != null &&
|
private fun isGroupConversation() = currentConversation != null && currentConversation?.type != null &&
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_GROUP_CALL
|
currentConversation?.type == ConversationType.ROOM_GROUP_CALL
|
||||||
|
|
||||||
private fun isPublicConversation() = currentConversation != null && currentConversation?.type != null &&
|
private fun isPublicConversation() = currentConversation != null && currentConversation?.type != null &&
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_PUBLIC_CALL
|
currentConversation?.type == ConversationType.ROOM_PUBLIC_CALL
|
||||||
|
|
||||||
private fun switchToRoom(token: String, startCallAfterRoomSwitch: Boolean, isVoiceOnlyCall: Boolean) {
|
private fun switchToRoom(token: String, startCallAfterRoomSwitch: Boolean, isVoiceOnlyCall: Boolean) {
|
||||||
if (conversationUser != null) {
|
if (conversationUser != null) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (currentConversation?.objectType == Conversation.ObjectType.ROOM) {
|
if (currentConversation?.objectType == ObjectType.ROOM) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context.resources.getString(R.string.switch_to_main_room),
|
context.resources.getString(R.string.switch_to_main_room),
|
||||||
@ -1281,7 +1287,6 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, token)
|
bundle.putString(KEY_ROOM_TOKEN, token)
|
||||||
|
|
||||||
if (startCallAfterRoomSwitch) {
|
if (startCallAfterRoomSwitch) {
|
||||||
@ -1697,8 +1702,8 @@ class ChatActivity :
|
|||||||
private fun shouldShowLobby(): Boolean {
|
private fun shouldShowLobby(): Boolean {
|
||||||
if (currentConversation != null) {
|
if (currentConversation != null) {
|
||||||
return CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
|
return CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
|
||||||
currentConversation?.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
|
currentConversation?.lobbyState == LobbyState.LOBBY_STATE_MODERATORS_ONLY &&
|
||||||
currentConversation?.canModerate(conversationUser!!) == false &&
|
!ConversationUtils.canModerate(currentConversation!!, conversationUser!!) &&
|
||||||
!participantPermissions.canIgnoreLobby()
|
!participantPermissions.canIgnoreLobby()
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -1733,12 +1738,12 @@ class ChatActivity :
|
|||||||
private fun isReadOnlyConversation(): Boolean {
|
private fun isReadOnlyConversation(): Boolean {
|
||||||
return currentConversation?.conversationReadOnlyState != null &&
|
return currentConversation?.conversationReadOnlyState != null &&
|
||||||
currentConversation?.conversationReadOnlyState ==
|
currentConversation?.conversationReadOnlyState ==
|
||||||
Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY
|
ConversationReadOnlyState.CONVERSATION_READ_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLobbyState() {
|
private fun checkLobbyState() {
|
||||||
if (currentConversation != null &&
|
if (currentConversation != null &&
|
||||||
currentConversation?.isLobbyViewApplicable(conversationUser!!) == true
|
ConversationUtils.isLobbyViewApplicable(currentConversation!!, conversationUser!!)
|
||||||
) {
|
) {
|
||||||
if (shouldShowLobby()) {
|
if (shouldShowLobby()) {
|
||||||
binding?.lobby?.lobbyView?.visibility = View.VISIBLE
|
binding?.lobby?.lobbyView?.visibility = View.VISIBLE
|
||||||
@ -2119,7 +2124,7 @@ class ChatActivity :
|
|||||||
|
|
||||||
private fun showConversationInfoScreen() {
|
private fun showConversationInfoScreen() {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
||||||
bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation())
|
bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation())
|
||||||
|
|
||||||
@ -2274,65 +2279,8 @@ class ChatActivity :
|
|||||||
|
|
||||||
val startNanoTime = System.nanoTime()
|
val startNanoTime = System.nanoTime()
|
||||||
Log.d(TAG, "joinRoomWithPassword - joinRoom - calling: $startNanoTime")
|
Log.d(TAG, "joinRoomWithPassword - joinRoom - calling: $startNanoTime")
|
||||||
ncApi.joinRoom(
|
|
||||||
credentials,
|
|
||||||
ApiUtils.getUrlForParticipantsActive(apiVersion, conversationUser?.baseUrl, roomToken),
|
|
||||||
roomPassword
|
|
||||||
)
|
|
||||||
?.subscribeOn(Schedulers.io())
|
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
?.retry(RETRIES)
|
|
||||||
?.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
disposables.add(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
chatViewModel.joinRoom(conversationUser!!, roomToken, roomPassword)
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
Log.d(TAG, "joinRoomWithPassword - joinRoom - got response: $startNanoTime")
|
|
||||||
|
|
||||||
val conversation = roomOverall.ocs!!.data!!
|
|
||||||
currentConversation = conversation
|
|
||||||
|
|
||||||
sessionIdAfterRoomJoined = conversation.sessionId
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().session = conversation.sessionId
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().currentRoomId = conversation.roomId
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = conversation.token
|
|
||||||
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
|
|
||||||
|
|
||||||
logConversationInfos("joinRoomWithPassword#onNext")
|
|
||||||
|
|
||||||
if (isFirstMessagesProcessing) {
|
|
||||||
pullChatMessages(false)
|
|
||||||
} else {
|
|
||||||
pullChatMessages(true, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webSocketInstance != null) {
|
|
||||||
webSocketInstance?.joinRoomWithRoomTokenAndSession(
|
|
||||||
roomToken!!,
|
|
||||||
sessionIdAfterRoomJoined
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (startCallFromNotification != null && startCallFromNotification ?: false) {
|
|
||||||
startCallFromNotification = false
|
|
||||||
startACall(voiceOnly, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startCallFromRoomSwitch) {
|
|
||||||
startCallFromRoomSwitch = false
|
|
||||||
startACall(voiceOnly, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, "joinRoomWithPassword - joinRoom - ERROR", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "sessionID was valid -> skip joinRoom")
|
Log.d(TAG, "sessionID was valid -> skip joinRoom")
|
||||||
|
|
||||||
@ -2801,9 +2749,9 @@ class ChatActivity :
|
|||||||
GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD > 0
|
GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD > 0
|
||||||
)
|
)
|
||||||
chatMessage.isOneToOneConversation =
|
chatMessage.isOneToOneConversation =
|
||||||
(currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
|
(currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
|
||||||
chatMessage.isFormerOneToOneConversation =
|
chatMessage.isFormerOneToOneConversation =
|
||||||
(currentConversation?.type == Conversation.ConversationType.FORMER_ONE_TO_ONE)
|
(currentConversation?.type == ConversationType.FORMER_ONE_TO_ONE)
|
||||||
it.addToStart(chatMessage, shouldScroll)
|
it.addToStart(chatMessage, shouldScroll)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2845,9 +2793,9 @@ class ChatActivity :
|
|||||||
|
|
||||||
val chatMessage = chatMessageList[i]
|
val chatMessage = chatMessageList[i]
|
||||||
chatMessage.isOneToOneConversation =
|
chatMessage.isOneToOneConversation =
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
||||||
chatMessage.isFormerOneToOneConversation =
|
chatMessage.isFormerOneToOneConversation =
|
||||||
(currentConversation?.type == Conversation.ConversationType.FORMER_ONE_TO_ONE)
|
(currentConversation?.type == ConversationType.FORMER_ONE_TO_ONE)
|
||||||
chatMessage.activeUser = conversationUser
|
chatMessage.activeUser = conversationUser
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3032,10 +2980,9 @@ class ChatActivity :
|
|||||||
val intent = Intent(this, SharedItemsActivity::class.java)
|
val intent = Intent(this, SharedItemsActivity::class.java)
|
||||||
intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName)
|
intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName)
|
||||||
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
|
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
|
||||||
intent.putExtra(KEY_USER_ENTITY, conversationUser as Parcelable)
|
|
||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR,
|
SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR,
|
||||||
currentConversation?.isParticipantOwnerOrModerator
|
ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!)
|
||||||
)
|
)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
@ -3119,12 +3066,11 @@ class ChatActivity :
|
|||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
||||||
bundle.putString(KEY_ROOM_ID, roomId)
|
bundle.putString(KEY_ROOM_ID, roomId)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
|
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, roomPassword)
|
||||||
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl)
|
bundle.putString(BundleKeys.KEY_MODIFIED_BASE_URL, conversationUser?.baseUrl)
|
||||||
bundle.putString(KEY_CONVERSATION_NAME, it.displayName)
|
bundle.putString(KEY_CONVERSATION_NAME, it.displayName)
|
||||||
bundle.putInt(KEY_RECORDING_STATE, it.callRecording)
|
bundle.putInt(KEY_RECORDING_STATE, it.callRecording)
|
||||||
bundle.putBoolean(KEY_IS_MODERATOR, it.isParticipantOwnerOrModerator)
|
bundle.putBoolean(KEY_IS_MODERATOR, ConversationUtils.isParticipantOwnerOrModerator(it))
|
||||||
bundle.putBoolean(
|
bundle.putBoolean(
|
||||||
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO,
|
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO,
|
||||||
participantPermissions.canPublishAudio()
|
participantPermissions.canPublishAudio()
|
||||||
@ -3141,7 +3087,7 @@ class ChatActivity :
|
|||||||
bundle.putBoolean(BundleKeys.KEY_CALL_WITHOUT_NOTIFICATION, true)
|
bundle.putBoolean(BundleKeys.KEY_CALL_WITHOUT_NOTIFICATION, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it.objectType == Conversation.ObjectType.ROOM) {
|
if (it.objectType == ObjectType.ROOM) {
|
||||||
bundle.putBoolean(KEY_IS_BREAKOUT_ROOM, true)
|
bundle.putBoolean(KEY_IS_BREAKOUT_ROOM, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3156,12 +3102,12 @@ class ChatActivity :
|
|||||||
override fun onClickReaction(chatMessage: ChatMessage, emoji: String) {
|
override fun onClickReaction(chatMessage: ChatMessage, emoji: String) {
|
||||||
VibrationUtils.vibrateShort(context)
|
VibrationUtils.vibrateShort(context)
|
||||||
if (chatMessage.reactionsSelf?.contains(emoji) == true) {
|
if (chatMessage.reactionsSelf?.contains(emoji) == true) {
|
||||||
reactionsRepository.deleteReaction(currentConversation!!, chatMessage, emoji)
|
reactionsRepository.deleteReaction(roomToken, chatMessage, emoji)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
?.subscribe(ReactionDeletedObserver())
|
?.subscribe(ReactionDeletedObserver())
|
||||||
} else {
|
} else {
|
||||||
reactionsRepository.addReaction(currentConversation!!, chatMessage, emoji)
|
reactionsRepository.addReaction(roomToken, chatMessage, emoji)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
?.subscribe(ReactionAddedObserver())
|
?.subscribe(ReactionAddedObserver())
|
||||||
@ -3171,7 +3117,7 @@ class ChatActivity :
|
|||||||
override fun onLongClickReactions(chatMessage: ChatMessage) {
|
override fun onLongClickReactions(chatMessage: ChatMessage) {
|
||||||
ShowReactionsDialog(
|
ShowReactionsDialog(
|
||||||
this,
|
this,
|
||||||
currentConversation,
|
roomToken,
|
||||||
chatMessage,
|
chatMessage,
|
||||||
conversationUser,
|
conversationUser,
|
||||||
participantPermissions.hasChatPermission(),
|
participantPermissions.hasChatPermission(),
|
||||||
@ -3339,48 +3285,15 @@ class ChatActivity :
|
|||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
|
|
||||||
// FIXME once APIv2+ is used only, the createRoom already returns all the data
|
leaveRoom {
|
||||||
ncApi.getRoom(
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
credentials,
|
chatIntent.putExtras(bundle)
|
||||||
ApiUtils.getUrlForRoom(
|
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
apiVersion,
|
startActivity(chatIntent)
|
||||||
conversationUser?.baseUrl,
|
}
|
||||||
roomOverall.ocs!!.data!!.token
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
bundle.putParcelable(
|
|
||||||
KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(roomOverall.ocs!!.data!!)
|
|
||||||
)
|
|
||||||
|
|
||||||
leaveRoom {
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
|
||||||
chatIntent.putExtras(bundle)
|
|
||||||
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
||||||
startActivity(chatIntent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, e.message, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
@ -3471,7 +3384,7 @@ class ChatActivity :
|
|||||||
conversationUser?.userId?.isNotEmpty() == true && conversationUser!!.userId != "?" &&
|
conversationUser?.userId?.isNotEmpty() == true && conversationUser!!.userId != "?" &&
|
||||||
message.user.id.startsWith("users/") &&
|
message.user.id.startsWith("users/") &&
|
||||||
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
|
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
|
||||||
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
||||||
isShowMessageDeletionButton(message) || // delete
|
isShowMessageDeletionButton(message) || // delete
|
||||||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() || // forward
|
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() || // forward
|
||||||
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID && // mark as unread
|
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID && // mark as unread
|
||||||
@ -3540,7 +3453,7 @@ class ChatActivity :
|
|||||||
messageTemp.isDeleted = true
|
messageTemp.isDeleted = true
|
||||||
|
|
||||||
messageTemp.isOneToOneConversation =
|
messageTemp.isOneToOneConversation =
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
||||||
messageTemp.activeUser = conversationUser
|
messageTemp.activeUser = conversationUser
|
||||||
|
|
||||||
adapter?.update(messageTemp)
|
adapter?.update(messageTemp)
|
||||||
@ -3550,7 +3463,7 @@ class ChatActivity :
|
|||||||
val messageTemp = message as ChatMessage
|
val messageTemp = message as ChatMessage
|
||||||
|
|
||||||
messageTemp.isOneToOneConversation =
|
messageTemp.isOneToOneConversation =
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
||||||
messageTemp.activeUser = conversationUser
|
messageTemp.activeUser = conversationUser
|
||||||
|
|
||||||
adapter?.update(messageTemp)
|
adapter?.update(messageTemp)
|
||||||
@ -3598,7 +3511,7 @@ class ChatActivity :
|
|||||||
val isUserAllowedByPrivileges = if (message.actorId == conversationUser!!.userId) {
|
val isUserAllowedByPrivileges = if (message.actorId == conversationUser!!.userId) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
currentConversation!!.canModerate(conversationUser!!)
|
ConversationUtils.canModerate(currentConversation!!, conversationUser!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
val isOlderThanSixHours = message
|
val isOlderThanSixHours = message
|
||||||
@ -3652,7 +3565,7 @@ class ChatActivity :
|
|||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
|
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
|
||||||
if (currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
if (currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
||||||
currentConversation?.name != userMentionClickEvent.userId
|
currentConversation?.name != userMentionClickEvent.userId
|
||||||
) {
|
) {
|
||||||
var apiVersion = 1
|
var apiVersion = 1
|
||||||
@ -3683,42 +3596,21 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val conversationIntent = Intent(context, CallActivity::class.java)
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
bundle.putBoolean(KEY_IS_MODERATOR, roomOverall.ocs!!.data!!.isParticipantOwnerOrModerator)
|
|
||||||
|
|
||||||
if (conversationUser != null) {
|
leaveRoom {
|
||||||
bundle.putParcelable(
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
KEY_ACTIVE_CONVERSATION,
|
chatIntent.putExtras(bundle)
|
||||||
Parcels.wrap(roomOverall.ocs!!.data)
|
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
)
|
startActivity(chatIntent)
|
||||||
conversationIntent.putExtras(bundle)
|
|
||||||
|
|
||||||
leaveRoom {
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
|
||||||
chatIntent.putExtras(bundle)
|
|
||||||
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
||||||
startActivity(chatIntent)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
conversationIntent.putExtras(bundle)
|
|
||||||
startActivity(conversationIntent)
|
|
||||||
Handler().postDelayed(
|
|
||||||
{
|
|
||||||
if (!isDestroyed) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
POP_CURRENT_CONTROLLER_DELAY
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
// unused atm
|
Log.e(TAG, "error after clicking on user mention chip", e)
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onComplete() {
|
override fun onComplete() {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.chat.data
|
||||||
|
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
|
||||||
|
import io.reactivex.Observable
|
||||||
|
|
||||||
|
interface ChatRepository {
|
||||||
|
fun getRoom(user: User, roomToken: String): Observable<ConversationModel>
|
||||||
|
fun joinRoom(user: User, roomToken: String, roomPassword: String): Observable<ConversationModel>
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.chat.data
|
||||||
|
|
||||||
|
import com.nextcloud.talk.api.NcApi
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
|
import io.reactivex.Observable
|
||||||
|
|
||||||
|
class ChatRepositoryImpl(private val ncApi: NcApi) : ChatRepository {
|
||||||
|
override fun getRoom(
|
||||||
|
user: User,
|
||||||
|
roomToken: String
|
||||||
|
): Observable<ConversationModel> {
|
||||||
|
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||||
|
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||||
|
|
||||||
|
return ncApi.getRoom(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForRoom(apiVersion, user.baseUrl, roomToken)
|
||||||
|
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun joinRoom(
|
||||||
|
user: User,
|
||||||
|
roomToken: String,
|
||||||
|
roomPassword: String
|
||||||
|
): Observable<ConversationModel> {
|
||||||
|
val credentials: String = ApiUtils.getCredentials(user.username, user.token)
|
||||||
|
val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.APIv4, 1))
|
||||||
|
|
||||||
|
return ncApi.joinRoom(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForParticipantsActive(apiVersion, user.baseUrl, roomToken),
|
||||||
|
roomPassword
|
||||||
|
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.chat.viewmodels
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.chat.data.ChatRepository
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ChatViewModel @Inject constructor(private val repository: ChatRepository) :
|
||||||
|
ViewModel() {
|
||||||
|
|
||||||
|
sealed interface ViewState
|
||||||
|
|
||||||
|
object GetRoomStartState : ViewState
|
||||||
|
object GetRoomErrorState : ViewState
|
||||||
|
open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
private val _getRoomViewState: MutableLiveData<ViewState> = MutableLiveData(GetRoomStartState)
|
||||||
|
val getRoomViewState: LiveData<ViewState>
|
||||||
|
get() = _getRoomViewState
|
||||||
|
|
||||||
|
object JoinRoomStartState : ViewState
|
||||||
|
object JoinRoomErrorState : ViewState
|
||||||
|
open class JoinRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
private val _joinRoomViewState: MutableLiveData<ViewState> = MutableLiveData(JoinRoomStartState)
|
||||||
|
val joinRoomViewState: LiveData<ViewState>
|
||||||
|
get() = _joinRoomViewState
|
||||||
|
|
||||||
|
fun getRoom(user: User, token: String) {
|
||||||
|
_getRoomViewState.value = GetRoomStartState
|
||||||
|
repository.getRoom(user, token)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(GetRoomObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun joinRoom(user: User, token: String, roomPassword: String) {
|
||||||
|
_getRoomViewState.value = JoinRoomStartState
|
||||||
|
repository.joinRoom(user, token, roomPassword)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.retry(JOIN_ROOM_RETRY_COUNT)
|
||||||
|
?.subscribe(JoinRoomObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class GetRoomObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_getRoomViewState.value = GetRoomSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when fetching room")
|
||||||
|
_getRoomViewState.value = GetRoomErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class JoinRoomObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_joinRoomViewState.value = JoinRoomSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when fetching room")
|
||||||
|
_joinRoomViewState.value = JoinRoomErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = ChatViewModel::class.simpleName
|
||||||
|
const val JOIN_ROOM_RETRY_COUNT: Long = 3
|
||||||
|
}
|
||||||
|
}
|
@ -338,46 +338,13 @@ class ContactsActivity :
|
|||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser)
|
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
|
|
||||||
// FIXME once APIv2 or later is used only, the createRoom already returns all the data
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
ncApi.getRoom(
|
chatIntent.putExtras(bundle)
|
||||||
credentials,
|
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
ApiUtils.getUrlForRoom(
|
startActivity(chatIntent)
|
||||||
apiVersion,
|
|
||||||
currentUser!!.baseUrl,
|
|
||||||
roomOverall.ocs!!.data!!.token
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
bundle.putParcelable(
|
|
||||||
BundleKeys.KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(roomOverall.ocs!!.data!!)
|
|
||||||
)
|
|
||||||
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
|
||||||
chatIntent.putExtras(bundle)
|
|
||||||
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
||||||
startActivity(chatIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
@ -818,13 +785,8 @@ class ContactsActivity :
|
|||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser)
|
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
bundle.putParcelable(
|
|
||||||
BundleKeys.KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(roomOverall.ocs!!.data!!)
|
|
||||||
)
|
|
||||||
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
chatIntent.putExtras(bundle)
|
chatIntent.putExtras(bundle)
|
||||||
|
@ -23,14 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.controllers.bottomsheet
|
package com.nextcloud.talk.controllers.bottomsheet
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
@ -40,21 +39,28 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
|
|||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.nextcloud.android.common.ui.theme.utils.ColorRole
|
import com.nextcloud.android.common.ui.theme.utils.ColorRole
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
|
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
|
||||||
import com.nextcloud.talk.controllers.base.BaseController
|
import com.nextcloud.talk.controllers.base.BaseController
|
||||||
import com.nextcloud.talk.controllers.util.viewBinding
|
import com.nextcloud.talk.controllers.util.viewBinding
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.databinding.ControllerEntryMenuBinding
|
import com.nextcloud.talk.databinding.ControllerEntryMenuBinding
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.users.UserManager
|
import com.nextcloud.talk.users.UserManager
|
||||||
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.UriUtils
|
import com.nextcloud.talk.utils.UriUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
||||||
import com.vanniktech.emoji.EmojiPopup
|
import com.vanniktech.emoji.EmojiPopup
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import okhttp3.internal.immutableListOf
|
import okhttp3.internal.immutableListOf
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.parceler.Parcels
|
|
||||||
import org.parceler.Parcels.unwrap
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
@ -65,6 +71,9 @@ class EntryMenuController(args: Bundle) :
|
|||||||
) {
|
) {
|
||||||
private val binding: ControllerEntryMenuBinding? by viewBinding(ControllerEntryMenuBinding::bind)
|
private val binding: ControllerEntryMenuBinding? by viewBinding(ControllerEntryMenuBinding::bind)
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var ncApi: NcApi
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var eventBus: EventBus
|
lateinit var eventBus: EventBus
|
||||||
|
|
||||||
@ -73,12 +82,13 @@ class EntryMenuController(args: Bundle) :
|
|||||||
|
|
||||||
private val operation: ConversationOperationEnum
|
private val operation: ConversationOperationEnum
|
||||||
private var conversation: Conversation? = null
|
private var conversation: Conversation? = null
|
||||||
private var shareIntent: Intent? = null
|
|
||||||
private val packageName: String
|
private val packageName: String
|
||||||
private val name: String
|
private val name: String
|
||||||
private val callUrl: String
|
|
||||||
private var emojiPopup: EmojiPopup? = null
|
private var emojiPopup: EmojiPopup? = null
|
||||||
private val originalBundle: Bundle
|
private val originalBundle: Bundle
|
||||||
|
private var currentUser: User? = null
|
||||||
|
private val roomToken: String
|
||||||
|
|
||||||
override val appBarLayoutType: AppBarLayoutType
|
override val appBarLayoutType: AppBarLayoutType
|
||||||
get() = AppBarLayoutType.SEARCH_BAR
|
get() = AppBarLayoutType.SEARCH_BAR
|
||||||
@ -100,74 +110,121 @@ class EntryMenuController(args: Bundle) :
|
|||||||
override fun onViewBound(view: View) {
|
override fun onViewBound(view: View) {
|
||||||
super.onViewBound(view)
|
super.onViewBound(view)
|
||||||
|
|
||||||
if (conversation != null && operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
|
currentUser = userManager.currentUser.blockingGet()
|
||||||
binding?.textEdit?.setText(conversation!!.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding?.textEdit?.setOnEditorActionListener { v, actionId, event ->
|
if (operation == ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM) {
|
||||||
@Suppress("IMPLICIT_BOXING_IN_IDENTITY_EQUALS")
|
var labelText = ""
|
||||||
if (actionId === EditorInfo.IME_ACTION_DONE && binding?.okButton?.isEnabled == true) {
|
labelText = resources!!.getString(R.string.nc_conversation_link)
|
||||||
binding?.okButton?.callOnClick()
|
binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
|
||||||
return@setOnEditorActionListener true
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
textEditAddChangedListener()
|
textEditAddChangedListener()
|
||||||
|
|
||||||
var labelText = ""
|
binding?.textInputLayout?.let { viewThemeUtils.material.colorTextInputLayout(it) }
|
||||||
when (operation) {
|
binding?.okButton?.let { viewThemeUtils.material.colorMaterialButtonText(it) }
|
||||||
ConversationOperationEnum.OPS_CODE_INVITE_USERS, ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> {
|
|
||||||
labelText = resources!!.getString(R.string.nc_call_name)
|
|
||||||
binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT
|
|
||||||
binding?.smileyButton?.visibility = View.VISIBLE
|
|
||||||
emojiPopup = binding?.let {
|
|
||||||
EmojiPopup(
|
|
||||||
rootView = view,
|
|
||||||
editText = it.textEdit,
|
|
||||||
onEmojiPopupShownListener = {
|
|
||||||
viewThemeUtils.platform.colorImageView(it.smileyButton, ColorRole.PRIMARY)
|
|
||||||
},
|
|
||||||
onEmojiPopupDismissListener = {
|
|
||||||
it.smileyButton.imageTintList = ColorStateList.valueOf(
|
|
||||||
ResourcesCompat.getColor(resources!!, R.color.medium_emphasis_text, context.theme)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onEmojiClickListener = {
|
|
||||||
binding?.textEdit?.editableText?.append(" ")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
|
binding?.textInputLayout?.hint = labelText
|
||||||
// 99 is joining a conversation via password
|
binding?.textInputLayout?.requestFocus()
|
||||||
labelText = resources!!.getString(R.string.nc_password)
|
|
||||||
binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
|
||||||
}
|
|
||||||
|
|
||||||
ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> {
|
binding?.smileyButton?.setOnClickListener { onSmileyClick() }
|
||||||
labelText = resources!!.getString(R.string.nc_conversation_link)
|
binding?.okButton?.setOnClickListener { onOkButtonClick() }
|
||||||
binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) {
|
|
||||||
binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
|
|
||||||
} else {
|
} else {
|
||||||
binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_NONE
|
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv1))
|
||||||
|
ncApi.getRoom(
|
||||||
|
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
|
||||||
|
ApiUtils.getUrlForRoom(apiVersion, currentUser!!.baseUrl, roomToken)
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.retry(1)
|
||||||
|
.subscribe(object : Observer<RoomOverall> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("Detekt.LongMethod")
|
||||||
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
|
conversation = roomOverall.ocs!!.data
|
||||||
|
|
||||||
|
if (conversation != null && operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
|
||||||
|
binding?.textEdit?.setText(conversation!!.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding?.textEdit?.setOnEditorActionListener { v, actionId, event ->
|
||||||
|
@Suppress("IMPLICIT_BOXING_IN_IDENTITY_EQUALS")
|
||||||
|
if (actionId === EditorInfo.IME_ACTION_DONE && binding?.okButton?.isEnabled == true) {
|
||||||
|
binding?.okButton?.callOnClick()
|
||||||
|
return@setOnEditorActionListener true
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
textEditAddChangedListener()
|
||||||
|
|
||||||
|
var labelText = ""
|
||||||
|
when (operation) {
|
||||||
|
ConversationOperationEnum.OPS_CODE_INVITE_USERS,
|
||||||
|
ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> {
|
||||||
|
labelText = resources!!.getString(R.string.nc_call_name)
|
||||||
|
binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT
|
||||||
|
binding?.smileyButton?.visibility = View.VISIBLE
|
||||||
|
emojiPopup = binding?.let {
|
||||||
|
EmojiPopup(
|
||||||
|
rootView = view,
|
||||||
|
editText = it.textEdit,
|
||||||
|
onEmojiPopupShownListener = {
|
||||||
|
viewThemeUtils.platform.colorImageView(it.smileyButton, ColorRole.PRIMARY)
|
||||||
|
},
|
||||||
|
onEmojiPopupDismissListener = {
|
||||||
|
it.smileyButton.imageTintList = ColorStateList.valueOf(
|
||||||
|
ResourcesCompat.getColor(
|
||||||
|
resources!!,
|
||||||
|
R.color.medium_emphasis_text,
|
||||||
|
context.theme
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onEmojiClickListener = {
|
||||||
|
binding?.textEdit?.editableText?.append(" ")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
|
||||||
|
// 99 is joining a conversation via password
|
||||||
|
labelText = resources!!.getString(R.string.nc_password)
|
||||||
|
binding?.textEdit?.inputType =
|
||||||
|
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) {
|
||||||
|
binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
|
||||||
|
} else {
|
||||||
|
binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
binding?.textInputLayout?.let { viewThemeUtils.material.colorTextInputLayout(it) }
|
||||||
|
binding?.okButton?.let { viewThemeUtils.material.colorMaterialButtonText(it) }
|
||||||
|
|
||||||
|
binding?.textInputLayout?.hint = labelText
|
||||||
|
binding?.textInputLayout?.requestFocus()
|
||||||
|
|
||||||
|
binding?.smileyButton?.setOnClickListener { onSmileyClick() }
|
||||||
|
binding?.okButton?.setOnClickListener { onOkButtonClick() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e("EntryMenuController", "error")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
binding?.textInputLayout?.let { viewThemeUtils.material.colorTextInputLayout(it) }
|
|
||||||
binding?.okButton?.let { viewThemeUtils.material.colorMaterialButtonText(it) }
|
|
||||||
|
|
||||||
binding?.textInputLayout?.hint = labelText
|
|
||||||
binding?.textInputLayout?.requestFocus()
|
|
||||||
|
|
||||||
binding?.smileyButton?.setOnClickListener { onSmileyClick() }
|
|
||||||
binding?.okButton?.setOnClickListener { onOkButtonClick() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun textEditAddChangedListener() {
|
private fun textEditAddChangedListener() {
|
||||||
@ -242,7 +299,8 @@ class EntryMenuController(args: Bundle) :
|
|||||||
) {
|
) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
conversation!!.name = binding?.textEdit?.text.toString()
|
conversation!!.name = binding?.textEdit?.text.toString()
|
||||||
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||||
|
bundle.putString(BundleKeys.KEY_NEW_ROOM_NAME, binding?.textEdit?.text.toString())
|
||||||
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
||||||
router.pushController(
|
router.pushController(
|
||||||
RouterTransaction.with(OperationsMenuController(bundle))
|
RouterTransaction.with(OperationsMenuController(bundle))
|
||||||
@ -274,16 +332,9 @@ class EntryMenuController(args: Bundle) :
|
|||||||
|
|
||||||
private fun joinRoom() {
|
private fun joinRoom() {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||||
bundle.putString(BundleKeys.KEY_CALL_URL, callUrl)
|
|
||||||
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding?.textEdit?.text.toString())
|
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding?.textEdit?.text.toString())
|
||||||
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
|
||||||
if (originalBundle.containsKey(BundleKeys.KEY_SERVER_CAPABILITIES)) {
|
|
||||||
bundle.putParcelable(
|
|
||||||
BundleKeys.KEY_SERVER_CAPABILITIES,
|
|
||||||
originalBundle.getParcelable(BundleKeys.KEY_SERVER_CAPABILITIES)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
router.pushController(
|
router.pushController(
|
||||||
RouterTransaction.with(OperationsMenuController(bundle))
|
RouterTransaction.with(OperationsMenuController(bundle))
|
||||||
.pushChangeHandler(HorizontalChangeHandler())
|
.pushChangeHandler(HorizontalChangeHandler())
|
||||||
@ -296,15 +347,10 @@ class EntryMenuController(args: Bundle) :
|
|||||||
|
|
||||||
originalBundle = args
|
originalBundle = args
|
||||||
operation = args.getSerializable(BundleKeys.KEY_OPERATION_CODE) as ConversationOperationEnum
|
operation = args.getSerializable(BundleKeys.KEY_OPERATION_CODE) as ConversationOperationEnum
|
||||||
if (args.containsKey(BundleKeys.KEY_ROOM)) {
|
roomToken = args.getString(KEY_ROOM_TOKEN, "")
|
||||||
conversation = unwrap<Conversation>(args.getParcelable<Parcelable>(BundleKeys.KEY_ROOM))
|
|
||||||
}
|
|
||||||
if (args.containsKey(BundleKeys.KEY_SHARE_INTENT)) {
|
|
||||||
shareIntent = unwrap<Intent>(args.getParcelable<Parcelable>(BundleKeys.KEY_SHARE_INTENT))
|
|
||||||
}
|
|
||||||
name = args.getString(BundleKeys.KEY_APP_ITEM_NAME, "")
|
name = args.getString(BundleKeys.KEY_APP_ITEM_NAME, "")
|
||||||
packageName = args.getString(BundleKeys.KEY_APP_ITEM_PACKAGE_NAME, "")
|
packageName = args.getString(BundleKeys.KEY_APP_ITEM_PACKAGE_NAME, "")
|
||||||
callUrl = args.getString(BundleKeys.KEY_CALL_URL, "")
|
// callUrl = args.getString(BundleKeys.KEY_CALL_URL, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.controllers.bottomsheet
|
package com.nextcloud.talk.controllers.bottomsheet
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -42,7 +40,6 @@ import com.nextcloud.talk.databinding.ControllerOperationsMenuBinding
|
|||||||
import com.nextcloud.talk.events.ConversationsListFetchDataEvent
|
import com.nextcloud.talk.events.ConversationsListFetchDataEvent
|
||||||
import com.nextcloud.talk.events.OpenConversationEvent
|
import com.nextcloud.talk.events.OpenConversationEvent
|
||||||
import com.nextcloud.talk.models.RetrofitBucket
|
import com.nextcloud.talk.models.RetrofitBucket
|
||||||
import com.nextcloud.talk.models.json.capabilities.Capabilities
|
|
||||||
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
|
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
|
||||||
@ -53,19 +50,17 @@ import com.nextcloud.talk.users.UserManager
|
|||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
import com.nextcloud.talk.utils.NoSupportedApiException
|
import com.nextcloud.talk.utils.NoSupportedApiException
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_URL
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_URL
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_PASSWORD
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_PASSWORD
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TYPE
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TYPE
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INVITED_GROUP
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INVITED_GROUP
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INVITED_PARTICIPANTS
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INVITED_PARTICIPANTS
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NEW_ROOM_NAME
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SERVER_CAPABILITIES
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
@ -100,13 +95,14 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
private var currentUser: User? = null
|
private var currentUser: User? = null
|
||||||
private val callPassword: String
|
private val callPassword: String
|
||||||
private val callUrl: String
|
private val callUrl: String
|
||||||
|
private var roomToken: String
|
||||||
|
private val roomNameNew: String
|
||||||
private var baseUrl: String? = null
|
private var baseUrl: String? = null
|
||||||
private var conversationToken: String? = null
|
private var conversationToken: String? = null
|
||||||
private var disposable: Disposable? = null
|
private var disposable: Disposable? = null
|
||||||
private var conversationType: ConversationType? = null
|
private var conversationType: ConversationType? = null
|
||||||
private var invitedUsers: ArrayList<String>? = ArrayList()
|
private var invitedUsers: ArrayList<String>? = ArrayList()
|
||||||
private var invitedGroups: ArrayList<String>? = ArrayList()
|
private var invitedGroups: ArrayList<String>? = ArrayList()
|
||||||
private var serverCapabilities: Capabilities? = null
|
|
||||||
private var credentials: String? = null
|
private var credentials: String? = null
|
||||||
private val conversationName: String
|
private val conversationName: String
|
||||||
|
|
||||||
@ -128,42 +124,44 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
baseUrl = callUrl.substring(0, callUrl.indexOf("/call"))
|
baseUrl = callUrl.substring(0, callUrl.indexOf("/call"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(baseUrl) && baseUrl != currentUser!!.baseUrl) {
|
|
||||||
if (serverCapabilities != null) {
|
if (roomToken.isNotEmpty()) {
|
||||||
try {
|
val apiVersion = apiVersion()
|
||||||
useBundledCapabilitiesForGuest()
|
ncApi.getRoom(
|
||||||
} catch (e: IOException) {
|
credentials,
|
||||||
// Fall back to fetching capabilities again
|
ApiUtils.getUrlForRoom(apiVersion, currentUser!!.baseUrl, roomToken)
|
||||||
fetchCapabilitiesForGuest()
|
)
|
||||||
}
|
.subscribeOn(Schedulers.io())
|
||||||
} else {
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
fetchCapabilitiesForGuest()
|
.retry(1)
|
||||||
}
|
.subscribe(object : Observer<RoomOverall> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
disposable = d
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
|
conversation = roomOverall.ocs!!.data
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(baseUrl) && baseUrl != currentUser!!.baseUrl) {
|
||||||
|
fetchCapabilitiesForGuest()
|
||||||
|
} else {
|
||||||
|
processOperation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "error while fetching room", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
processOperation()
|
processOperation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
private fun useBundledCapabilitiesForGuest() {
|
|
||||||
currentUser = User()
|
|
||||||
currentUser!!.baseUrl = baseUrl
|
|
||||||
currentUser!!.userId = "?"
|
|
||||||
try {
|
|
||||||
currentUser!!.capabilities = serverCapabilities
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.e("OperationsMenu", "Failed to serialize capabilities")
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
checkCapabilities(currentUser!!)
|
|
||||||
processOperation()
|
|
||||||
} catch (e: NoSupportedApiException) {
|
|
||||||
showResultImage(everythingOK = false, isGuestSupportError = false)
|
|
||||||
Log.d(TAG, "No supported server version found", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fetchCapabilitiesForGuest() {
|
private fun fetchCapabilitiesForGuest() {
|
||||||
ncApi.getCapabilities(null, ApiUtils.getUrlForCapabilities(baseUrl))
|
ncApi.getCapabilities(null, ApiUtils.getUrlForCapabilities(baseUrl))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
@ -218,6 +216,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
ConversationOperationEnum.OPS_CODE_MARK_AS_UNREAD -> operationMarkAsUnread()
|
ConversationOperationEnum.OPS_CODE_MARK_AS_UNREAD -> operationMarkAsUnread()
|
||||||
ConversationOperationEnum.OPS_CODE_REMOVE_FAVORITE,
|
ConversationOperationEnum.OPS_CODE_REMOVE_FAVORITE,
|
||||||
ConversationOperationEnum.OPS_CODE_ADD_FAVORITE -> operationToggleFavorite()
|
ConversationOperationEnum.OPS_CODE_ADD_FAVORITE -> operationToggleFavorite()
|
||||||
|
|
||||||
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> operationJoinRoom()
|
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> operationJoinRoom()
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
@ -287,7 +286,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
currentUser!!.baseUrl,
|
currentUser!!.baseUrl,
|
||||||
conversation!!.token
|
conversation!!.token
|
||||||
),
|
),
|
||||||
conversation!!.name
|
roomNameNew
|
||||||
)
|
)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -427,17 +426,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
if (conversation!!.hasPassword && conversation!!.isGuest) {
|
if (conversation!!.hasPassword && conversation!!.isGuest) {
|
||||||
eventBus.post(ConversationsListFetchDataEvent())
|
eventBus.post(ConversationsListFetchDataEvent())
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken)
|
||||||
bundle.putString(KEY_CALL_URL, callUrl)
|
|
||||||
try {
|
|
||||||
bundle.putParcelable(
|
|
||||||
KEY_SERVER_CAPABILITIES,
|
|
||||||
Parcels.wrap<Capabilities>(currentUser!!.capabilities)
|
|
||||||
)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.e(TAG, "Failed to parse capabilities for guest")
|
|
||||||
showResultImage(everythingOK = false, isGuestSupportError = false)
|
|
||||||
}
|
|
||||||
bundle.putSerializable(KEY_OPERATION_CODE, ConversationOperationEnum.OPS_CODE_JOIN_ROOM)
|
bundle.putSerializable(KEY_OPERATION_CODE, ConversationOperationEnum.OPS_CODE_JOIN_ROOM)
|
||||||
router.pushController(
|
router.pushController(
|
||||||
RouterTransaction.with(EntryMenuController(bundle))
|
RouterTransaction.with(EntryMenuController(bundle))
|
||||||
@ -519,16 +508,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
binding?.resultTextView?.setText(R.string.nc_all_ok_operation)
|
binding?.resultTextView?.setText(R.string.nc_all_ok_operation)
|
||||||
} else {
|
} else {
|
||||||
binding?.resultTextView?.setTextColor(resources!!.getColor(R.color.nc_darkRed, null))
|
binding?.resultTextView?.setTextColor(resources!!.getColor(R.color.nc_darkRed, null))
|
||||||
if (!isGuestSupportError) {
|
binding?.resultTextView?.setText(R.string.nc_failed_to_perform_operation)
|
||||||
binding?.resultTextView?.setText(R.string.nc_failed_to_perform_operation)
|
|
||||||
} else {
|
|
||||||
binding?.resultTextView?.setText(R.string.nc_failed_signaling_settings)
|
|
||||||
binding?.webButton?.setOnClickListener {
|
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(callUrl))
|
|
||||||
startActivity(browserIntent)
|
|
||||||
}
|
|
||||||
binding?.webButton?.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
binding?.resultTextView?.visibility = View.VISIBLE
|
binding?.resultTextView?.visibility = View.VISIBLE
|
||||||
if (everythingOK) {
|
if (everythingOK) {
|
||||||
@ -608,6 +588,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
override fun onSubscribe(d: Disposable) {
|
override fun onSubscribe(d: Disposable) {
|
||||||
// unused atm
|
// unused atm
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNext(addParticipantOverall: AddParticipantOverall) {
|
override fun onNext(addParticipantOverall: AddParticipantOverall) {
|
||||||
// unused atm
|
// unused atm
|
||||||
}
|
}
|
||||||
@ -653,6 +634,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
override fun onSubscribe(d: Disposable) {
|
override fun onSubscribe(d: Disposable) {
|
||||||
// unused atm
|
// unused atm
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNext(addParticipantOverall: AddParticipantOverall) {
|
override fun onNext(addParticipantOverall: AddParticipantOverall) {
|
||||||
// unused atm
|
// unused atm
|
||||||
}
|
}
|
||||||
@ -679,8 +661,6 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
bundle.putString(KEY_ROOM_TOKEN, conversation!!.token)
|
bundle.putString(KEY_ROOM_TOKEN, conversation!!.token)
|
||||||
bundle.putString(KEY_ROOM_ID, conversation!!.roomId)
|
bundle.putString(KEY_ROOM_ID, conversation!!.roomId)
|
||||||
bundle.putString(KEY_CONVERSATION_NAME, conversation!!.displayName)
|
bundle.putString(KEY_CONVERSATION_NAME, conversation!!.displayName)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, currentUser)
|
|
||||||
bundle.putParcelable(KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation))
|
|
||||||
bundle.putString(KEY_CONVERSATION_PASSWORD, callPassword)
|
bundle.putString(KEY_CONVERSATION_PASSWORD, callPassword)
|
||||||
eventBus.post(OpenConversationEvent(conversation, bundle))
|
eventBus.post(OpenConversationEvent(conversation, bundle))
|
||||||
}
|
}
|
||||||
@ -755,11 +735,10 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
operation = args.getSerializable(KEY_OPERATION_CODE) as ConversationOperationEnum?
|
operation = args.getSerializable(KEY_OPERATION_CODE) as ConversationOperationEnum?
|
||||||
if (args.containsKey(KEY_ROOM)) {
|
|
||||||
conversation = Parcels.unwrap(args.getParcelable(KEY_ROOM))
|
|
||||||
}
|
|
||||||
callPassword = args.getString(KEY_CONVERSATION_PASSWORD, "")
|
callPassword = args.getString(KEY_CONVERSATION_PASSWORD, "")
|
||||||
callUrl = args.getString(KEY_CALL_URL, "")
|
callUrl = args.getString(KEY_CALL_URL, "")
|
||||||
|
roomToken = args.getString(KEY_ROOM_TOKEN, "")
|
||||||
|
roomNameNew = args.getString(KEY_NEW_ROOM_NAME, "")
|
||||||
if (args.containsKey(KEY_INVITED_PARTICIPANTS)) {
|
if (args.containsKey(KEY_INVITED_PARTICIPANTS)) {
|
||||||
invitedUsers = args.getStringArrayList(KEY_INVITED_PARTICIPANTS)
|
invitedUsers = args.getStringArrayList(KEY_INVITED_PARTICIPANTS)
|
||||||
}
|
}
|
||||||
@ -769,9 +748,6 @@ class OperationsMenuController(args: Bundle) : BaseController(
|
|||||||
if (args.containsKey(KEY_CONVERSATION_TYPE)) {
|
if (args.containsKey(KEY_CONVERSATION_TYPE)) {
|
||||||
conversationType = Parcels.unwrap(args.getParcelable(KEY_CONVERSATION_TYPE))
|
conversationType = Parcels.unwrap(args.getParcelable(KEY_CONVERSATION_TYPE))
|
||||||
}
|
}
|
||||||
if (args.containsKey(KEY_SERVER_CAPABILITIES)) {
|
|
||||||
serverCapabilities = Parcels.unwrap(args.getParcelable(KEY_SERVER_CAPABILITIES))
|
|
||||||
}
|
|
||||||
conversationName = args.getString(KEY_CONVERSATION_NAME, "")
|
conversationName = args.getString(KEY_CONVERSATION_NAME, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
@ -86,6 +85,7 @@ import com.nextcloud.talk.utils.DateConstants
|
|||||||
import com.nextcloud.talk.utils.DateUtils
|
import com.nextcloud.talk.utils.DateUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
|
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
@ -95,7 +95,6 @@ import io.reactivex.disposables.Disposable
|
|||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.parceler.Parcels
|
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@ -110,6 +109,9 @@ class ConversationInfoActivity :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var ncApi: NcApi
|
lateinit var ncApi: NcApi
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var currentUserProvider: CurrentUserProviderNew
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var conversationsRepository: ConversationsRepository
|
lateinit var conversationsRepository: ConversationsRepository
|
||||||
|
|
||||||
@ -152,7 +154,8 @@ class ConversationInfoActivity :
|
|||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
setupSystemColors()
|
setupSystemColors()
|
||||||
|
|
||||||
conversationUser = intent.getParcelableExtra(BundleKeys.KEY_USER_ENTITY)!!
|
conversationUser = currentUserProvider.currentUser.blockingGet()
|
||||||
|
|
||||||
conversationToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
|
conversationToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
|
||||||
hasAvatarSpacing = intent.getBooleanExtra(BundleKeys.KEY_ROOM_ONE_TO_ONE, false)
|
hasAvatarSpacing = intent.getBooleanExtra(BundleKeys.KEY_ROOM_ONE_TO_ONE, false)
|
||||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
||||||
@ -225,11 +228,6 @@ class ConversationInfoActivity :
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
if (item.itemId == R.id.edit) {
|
if (item.itemId == R.id.edit) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, conversationUser)
|
|
||||||
bundle.putParcelable(
|
|
||||||
BundleKeys.KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(conversation)
|
|
||||||
)
|
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
|
||||||
|
|
||||||
val intent = Intent(this, ConversationInfoEditActivity::class.java)
|
val intent = Intent(this, ConversationInfoEditActivity::class.java)
|
||||||
@ -270,7 +268,6 @@ class ConversationInfoActivity :
|
|||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
intent.putExtra(BundleKeys.KEY_CONVERSATION_NAME, conversation?.displayName)
|
intent.putExtra(BundleKeys.KEY_CONVERSATION_NAME, conversation?.displayName)
|
||||||
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
|
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, conversationToken)
|
||||||
intent.putExtra(BundleKeys.KEY_USER_ENTITY, conversationUser as Parcelable)
|
|
||||||
intent.putExtra(SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, conversation?.isParticipantOwnerOrModerator)
|
intent.putExtra(SharedItemsActivity.KEY_USER_IS_OWNER_OR_MODERATOR, conversation?.isParticipantOwnerOrModerator)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
@ -34,34 +34,31 @@ import android.view.View
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.net.toFile
|
import androidx.core.net.toFile
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import autodagger.AutoInjector
|
import autodagger.AutoInjector
|
||||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
import com.github.dhaval2404.imagepicker.ImagePicker
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.activities.BaseActivity
|
import com.nextcloud.talk.activities.BaseActivity
|
||||||
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.conversationinfoedit.viewmodel.ConversationInfoEditViewModel
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.databinding.ActivityConversationInfoEditBinding
|
import com.nextcloud.talk.databinding.ActivityConversationInfoEditBinding
|
||||||
import com.nextcloud.talk.extensions.loadConversationAvatar
|
import com.nextcloud.talk.extensions.loadConversationAvatar
|
||||||
import com.nextcloud.talk.extensions.loadSystemAvatar
|
import com.nextcloud.talk.extensions.loadSystemAvatar
|
||||||
import com.nextcloud.talk.extensions.loadUserAvatar
|
import com.nextcloud.talk.extensions.loadUserAvatar
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepository
|
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.Mimetype
|
|
||||||
import com.nextcloud.talk.utils.PickImage
|
import com.nextcloud.talk.utils.PickImage
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
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
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
|
||||||
import org.parceler.Parcels
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -75,13 +72,18 @@ class ConversationInfoEditActivity :
|
|||||||
lateinit var ncApi: NcApi
|
lateinit var ncApi: NcApi
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var conversationsRepository: ConversationsRepository
|
lateinit var currentUserProvider: CurrentUserProviderNew
|
||||||
|
|
||||||
private lateinit var conversationToken: String
|
@Inject
|
||||||
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
|
lateinit var conversationInfoEditViewModel: ConversationInfoEditViewModel
|
||||||
|
|
||||||
|
private lateinit var roomToken: String
|
||||||
private lateinit var conversationUser: User
|
private lateinit var conversationUser: User
|
||||||
private lateinit var credentials: String
|
private lateinit var credentials: String
|
||||||
|
|
||||||
private var conversation: Conversation? = null
|
private var conversation: ConversationModel? = null
|
||||||
|
|
||||||
private lateinit var pickImage: PickImage
|
private lateinit var pickImage: PickImage
|
||||||
|
|
||||||
@ -96,12 +98,14 @@ class ConversationInfoEditActivity :
|
|||||||
|
|
||||||
val extras: Bundle? = intent.extras
|
val extras: Bundle? = intent.extras
|
||||||
|
|
||||||
conversationUser = extras?.getParcelable(BundleKeys.KEY_USER_ENTITY)!!
|
conversationUser = currentUserProvider.currentUser.blockingGet()
|
||||||
conversationToken = extras.getString(BundleKeys.KEY_ROOM_TOKEN)!!
|
|
||||||
|
|
||||||
if (conversation == null && intent.hasExtra(BundleKeys.KEY_ACTIVE_CONVERSATION)) {
|
roomToken = extras?.getString(BundleKeys.KEY_ROOM_TOKEN)!!
|
||||||
conversation = Parcels.unwrap<Conversation>(extras.getParcelable(BundleKeys.KEY_ACTIVE_CONVERSATION))
|
|
||||||
}
|
conversationInfoEditViewModel =
|
||||||
|
ViewModelProvider(this, viewModelFactory)[ConversationInfoEditViewModel::class.java]
|
||||||
|
|
||||||
|
conversationInfoEditViewModel.getRoom(conversationUser, roomToken)
|
||||||
|
|
||||||
viewThemeUtils.material.colorTextInputLayout(binding.conversationNameInputLayout)
|
viewThemeUtils.material.colorTextInputLayout(binding.conversationNameInputLayout)
|
||||||
viewThemeUtils.material.colorTextInputLayout(binding.conversationDescriptionInputLayout)
|
viewThemeUtils.material.colorTextInputLayout(binding.conversationDescriptionInputLayout)
|
||||||
@ -109,21 +113,57 @@ class ConversationInfoEditActivity :
|
|||||||
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
credentials = ApiUtils.getCredentials(conversationUser.username, conversationUser.token)
|
||||||
|
|
||||||
pickImage = PickImage(this, conversationUser)
|
pickImage = PickImage(this, conversationUser)
|
||||||
|
|
||||||
|
initObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
loadConversationAvatar()
|
private fun initObservers() {
|
||||||
|
conversationInfoEditViewModel.viewState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
is ConversationInfoEditViewModel.GetRoomSuccessState -> {
|
||||||
|
conversation = state.conversationModel
|
||||||
|
|
||||||
binding.conversationName.setText(conversation!!.displayName)
|
binding.conversationName.setText(conversation!!.displayName)
|
||||||
|
|
||||||
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
||||||
binding.conversationDescription.setText(conversation!!.description)
|
binding.conversationDescription.setText(conversation!!.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CapabilitiesUtilNew.isConversationDescriptionEndpointAvailable(conversationUser)) {
|
if (!CapabilitiesUtilNew.isConversationDescriptionEndpointAvailable(conversationUser)) {
|
||||||
binding.conversationDescription.isEnabled = false
|
binding.conversationDescription.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
loadConversationAvatar()
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoEditViewModel.GetRoomErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoEditViewModel.UploadAvatarSuccessState -> {
|
||||||
|
conversation = state.conversationModel
|
||||||
|
loadConversationAvatar()
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoEditViewModel.UploadAvatarErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoEditViewModel.DeleteAvatarSuccessState -> {
|
||||||
|
conversation = state.conversationModel
|
||||||
|
loadConversationAvatar()
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoEditViewModel.DeleteAvatarErrorState -> {
|
||||||
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,98 +324,27 @@ class ConversationInfoEditActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun uploadAvatar(file: File?) {
|
private fun uploadAvatar(file: File) {
|
||||||
val builder = MultipartBody.Builder()
|
conversationInfoEditViewModel.uploadConversationAvatar(conversationUser, file, roomToken)
|
||||||
builder.setType(MultipartBody.FORM)
|
|
||||||
builder.addFormDataPart(
|
|
||||||
"file",
|
|
||||||
file!!.name,
|
|
||||||
file.asRequestBody(Mimetype.IMAGE_PREFIX_GENERIC.toMediaTypeOrNull())
|
|
||||||
)
|
|
||||||
val filePart: MultipartBody.Part = MultipartBody.Part.createFormData(
|
|
||||||
"file",
|
|
||||||
file.name,
|
|
||||||
file.asRequestBody(Mimetype.IMAGE_JPG.toMediaTypeOrNull())
|
|
||||||
)
|
|
||||||
|
|
||||||
// upload file
|
|
||||||
ncApi.uploadConversationAvatar(
|
|
||||||
credentials,
|
|
||||||
ApiUtils.getUrlForConversationAvatar(1, conversationUser.baseUrl, conversation!!.token),
|
|
||||||
filePart
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
conversation = roomOverall.ocs!!.data
|
|
||||||
loadConversationAvatar()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Toast.makeText(
|
|
||||||
applicationContext,
|
|
||||||
context.getString(R.string.default_error_msg),
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
Log.e(TAG, "Error uploading avatar", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteAvatar() {
|
private fun deleteAvatar() {
|
||||||
ncApi.deleteConversationAvatar(
|
conversationInfoEditViewModel.deleteConversationAvatar(conversationUser, roomToken)
|
||||||
credentials,
|
|
||||||
ApiUtils.getUrlForConversationAvatar(1, conversationUser.baseUrl, conversationToken)
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
conversation = roomOverall.ocs!!.data
|
|
||||||
loadConversationAvatar()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Toast.makeText(
|
|
||||||
applicationContext,
|
|
||||||
context.getString(R.string.default_error_msg),
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
Log.e(TAG, "Failed to delete avatar", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadConversationAvatar() {
|
private fun loadConversationAvatar() {
|
||||||
setupAvatarOptions()
|
setupAvatarOptions()
|
||||||
|
|
||||||
when (conversation!!.type) {
|
when (conversation!!.type) {
|
||||||
Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) {
|
ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) {
|
||||||
conversation!!.name?.let { binding.avatarImage.loadUserAvatar(conversationUser, it, true, false) }
|
conversation!!.name?.let { binding.avatarImage.loadUserAvatar(conversationUser, it, true, false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Conversation.ConversationType.ROOM_GROUP_CALL, Conversation.ConversationType.ROOM_PUBLIC_CALL -> {
|
ConversationType.ROOM_GROUP_CALL, ConversationType.ROOM_PUBLIC_CALL -> {
|
||||||
binding.avatarImage.loadConversationAvatar(conversationUser, conversation!!, false, viewThemeUtils)
|
binding.avatarImage.loadConversationAvatar(conversationUser, conversation!!, false, viewThemeUtils)
|
||||||
}
|
}
|
||||||
|
|
||||||
Conversation.ConversationType.ROOM_SYSTEM -> {
|
ConversationType.ROOM_SYSTEM -> {
|
||||||
binding.avatarImage.loadSystemAvatar()
|
binding.avatarImage.loadSystemAvatar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.conversationinfoedit.data
|
||||||
|
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface ConversationInfoEditRepository {
|
||||||
|
|
||||||
|
fun uploadConversationAvatar(user: User, file: File, roomToken: String): Observable<ConversationModel>
|
||||||
|
|
||||||
|
fun deleteConversationAvatar(user: User, roomToken: String): Observable<ConversationModel>
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.conversationinfoedit.data
|
||||||
|
|
||||||
|
import com.nextcloud.talk.api.NcApi
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
|
import com.nextcloud.talk.utils.Mimetype
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserProvider: CurrentUserProviderNew) :
|
||||||
|
ConversationInfoEditRepository {
|
||||||
|
|
||||||
|
val currentUser: User = currentUserProvider.currentUser.blockingGet()
|
||||||
|
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||||
|
|
||||||
|
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.APIv4, ApiUtils.APIv3, 1))
|
||||||
|
|
||||||
|
override fun uploadConversationAvatar(user: User, file: File, roomToken: String): Observable<ConversationModel> {
|
||||||
|
val builder = MultipartBody.Builder()
|
||||||
|
builder.setType(MultipartBody.FORM)
|
||||||
|
builder.addFormDataPart(
|
||||||
|
"file",
|
||||||
|
file!!.name,
|
||||||
|
file.asRequestBody(Mimetype.IMAGE_PREFIX_GENERIC.toMediaTypeOrNull())
|
||||||
|
)
|
||||||
|
val filePart: MultipartBody.Part = MultipartBody.Part.createFormData(
|
||||||
|
"file",
|
||||||
|
file.name,
|
||||||
|
file.asRequestBody(Mimetype.IMAGE_JPG.toMediaTypeOrNull())
|
||||||
|
)
|
||||||
|
|
||||||
|
return ncApi.uploadConversationAvatar(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl, roomToken),
|
||||||
|
filePart
|
||||||
|
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deleteConversationAvatar(user: User, roomToken: String): Observable<ConversationModel> {
|
||||||
|
return ncApi.deleteConversationAvatar(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForConversationAvatar(1, user.baseUrl, roomToken)
|
||||||
|
).map { ConversationModel.mapToConversationModel(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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.conversationinfoedit.viewmodel
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.chat.data.ChatRepository
|
||||||
|
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ConversationInfoEditViewModel @Inject constructor(
|
||||||
|
private val repository: ChatRepository,
|
||||||
|
private val conversationInfoEditRepository: ConversationInfoEditRepository
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
sealed interface ViewState
|
||||||
|
|
||||||
|
object GetRoomStartState : ViewState
|
||||||
|
object GetRoomErrorState : ViewState
|
||||||
|
open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
object UploadAvatarErrorState : ViewState
|
||||||
|
open class UploadAvatarSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
object DeleteAvatarErrorState : ViewState
|
||||||
|
open class DeleteAvatarSuccessState(val conversationModel: ConversationModel) : ViewState
|
||||||
|
|
||||||
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(GetRoomStartState)
|
||||||
|
val viewState: LiveData<ViewState>
|
||||||
|
get() = _viewState
|
||||||
|
|
||||||
|
fun getRoom(user: User, token: String) {
|
||||||
|
_viewState.value = GetRoomStartState
|
||||||
|
repository.getRoom(user, token)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(GetRoomObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun uploadConversationAvatar(user: User, file: File, roomToken: String) {
|
||||||
|
conversationInfoEditRepository.uploadConversationAvatar(user, file, roomToken)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(UploadConversationAvatarObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteConversationAvatar(user: User, roomToken: String) {
|
||||||
|
conversationInfoEditRepository.deleteConversationAvatar(user, roomToken)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(DeleteConversationAvatarObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class GetRoomObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_viewState.value = GetRoomSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when fetching room")
|
||||||
|
_viewState.value = GetRoomErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class UploadConversationAvatarObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_viewState.value = UploadAvatarSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when uploading avatar")
|
||||||
|
_viewState.value = UploadAvatarErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DeleteConversationAvatarObserver : Observer<ConversationModel> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(conversationModel: ConversationModel) {
|
||||||
|
_viewState.value = DeleteAvatarSuccessState(conversationModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error when deleting avatar")
|
||||||
|
_viewState.value = DeleteAvatarErrorState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = ConversationInfoEditViewModel::class.simpleName
|
||||||
|
}
|
||||||
|
}
|
@ -106,17 +106,14 @@ import com.nextcloud.talk.utils.FileUtils
|
|||||||
import com.nextcloud.talk.utils.Mimetype
|
import com.nextcloud.talk.utils.Mimetype
|
||||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACTIVE_CONVERSATION
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_MSG_FLAG
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_MSG_FLAG
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_MSG_TEXT
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FORWARD_MSG_TEXT
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NEW_CONVERSATION
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NEW_CONVERSATION
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARED_TEXT
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARED_TEXT
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isServerEOL
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isServerEOL
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUnifiedSearchAvailable
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.isUnifiedSearchAvailable
|
||||||
@ -134,7 +131,6 @@ import io.reactivex.schedulers.Schedulers
|
|||||||
import org.apache.commons.lang3.builder.CompareToBuilder
|
import org.apache.commons.lang3.builder.CompareToBuilder
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.parceler.Parcels
|
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -1074,7 +1070,6 @@ class ConversationsListActivity :
|
|||||||
if (clickedItem != null) {
|
if (clickedItem != null) {
|
||||||
val conversation = (clickedItem as ConversationItem).model
|
val conversation = (clickedItem as ConversationItem).model
|
||||||
conversationsListBottomDialog = ConversationsListBottomDialog(
|
conversationsListBottomDialog = ConversationsListBottomDialog(
|
||||||
this,
|
|
||||||
this,
|
this,
|
||||||
userManager.currentUser.blockingGet(),
|
userManager.currentUser.blockingGet(),
|
||||||
conversation
|
conversation
|
||||||
@ -1185,8 +1180,6 @@ class ConversationsListActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, currentUser)
|
|
||||||
bundle.putParcelable(KEY_ACTIVE_CONVERSATION, Parcels.wrap(selectedConversation))
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, selectedConversation!!.token)
|
bundle.putString(KEY_ROOM_TOKEN, selectedConversation!!.token)
|
||||||
bundle.putString(KEY_ROOM_ID, selectedConversation!!.roomId)
|
bundle.putString(KEY_ROOM_ID, selectedConversation!!.roomId)
|
||||||
bundle.putString(KEY_SHARED_TEXT, textToPaste)
|
bundle.putString(KEY_SHARED_TEXT, textToPaste)
|
||||||
@ -1229,38 +1222,35 @@ class ConversationsListActivity :
|
|||||||
if (conversationMenuBundle != null &&
|
if (conversationMenuBundle != null &&
|
||||||
isInternalUserEqualsCurrentUser(currentUser, conversationMenuBundle)
|
isInternalUserEqualsCurrentUser(currentUser, conversationMenuBundle)
|
||||||
) {
|
) {
|
||||||
val conversation = Parcels.unwrap<Conversation>(conversationMenuBundle!!.getParcelable(KEY_ROOM))
|
binding?.floatingActionButton?.let {
|
||||||
if (conversation != null) {
|
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
|
||||||
binding?.floatingActionButton?.let {
|
.setIcon(
|
||||||
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
|
viewThemeUtils.dialog
|
||||||
.setIcon(
|
.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)
|
||||||
viewThemeUtils.dialog
|
|
||||||
.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)
|
|
||||||
)
|
|
||||||
.setTitle(R.string.nc_delete_call)
|
|
||||||
.setMessage(R.string.nc_delete_conversation_more)
|
|
||||||
.setPositiveButton(R.string.nc_delete) { _, _ ->
|
|
||||||
val data = Data.Builder()
|
|
||||||
data.putLong(
|
|
||||||
KEY_INTERNAL_USER_ID,
|
|
||||||
conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID)
|
|
||||||
)
|
|
||||||
data.putString(KEY_ROOM_TOKEN, conversation.token)
|
|
||||||
conversationMenuBundle = null
|
|
||||||
deleteConversation(data.build())
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.nc_cancel) { _, _ ->
|
|
||||||
conversationMenuBundle = null
|
|
||||||
}
|
|
||||||
|
|
||||||
viewThemeUtils.dialog
|
|
||||||
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
|
|
||||||
val dialog = dialogBuilder.show()
|
|
||||||
viewThemeUtils.platform.colorTextButtons(
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
|
||||||
)
|
)
|
||||||
}
|
.setTitle(R.string.nc_delete_call)
|
||||||
|
.setMessage(R.string.nc_delete_conversation_more)
|
||||||
|
.setPositiveButton(R.string.nc_delete) { _, _ ->
|
||||||
|
val data = Data.Builder()
|
||||||
|
data.putLong(
|
||||||
|
KEY_INTERNAL_USER_ID,
|
||||||
|
conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID)
|
||||||
|
)
|
||||||
|
data.putString(KEY_ROOM_TOKEN, bundle.getString(KEY_ROOM_TOKEN))
|
||||||
|
conversationMenuBundle = null
|
||||||
|
deleteConversation(data.build())
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.nc_cancel) { _, _ ->
|
||||||
|
conversationMenuBundle = null
|
||||||
|
}
|
||||||
|
|
||||||
|
viewThemeUtils.dialog
|
||||||
|
.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
|
||||||
|
val dialog = dialogBuilder.show()
|
||||||
|
viewThemeUtils.platform.colorTextButtons(
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
package com.nextcloud.talk.dagger.modules
|
package com.nextcloud.talk.dagger.modules
|
||||||
|
|
||||||
import com.nextcloud.talk.api.NcApi
|
import com.nextcloud.talk.api.NcApi
|
||||||
|
import com.nextcloud.talk.chat.data.ChatRepository
|
||||||
|
import com.nextcloud.talk.chat.data.ChatRepositoryImpl
|
||||||
|
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository
|
||||||
|
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepositoryImpl
|
||||||
import com.nextcloud.talk.data.source.local.TalkDatabase
|
import com.nextcloud.talk.data.source.local.TalkDatabase
|
||||||
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepository
|
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepository
|
||||||
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepositoryImpl
|
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepositoryImpl
|
||||||
@ -123,4 +127,16 @@ class RepositoryModule {
|
|||||||
TranslateRepository {
|
TranslateRepository {
|
||||||
return TranslateRepositoryImpl(ncApi)
|
return TranslateRepositoryImpl(ncApi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideChatRepository(ncApi: NcApi):
|
||||||
|
ChatRepository {
|
||||||
|
return ChatRepositoryImpl(ncApi)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideConversationInfoEditRepository(ncApi: NcApi, userProvider: CurrentUserProviderNew):
|
||||||
|
ConversationInfoEditRepository {
|
||||||
|
return ConversationInfoEditRepositoryImpl(ncApi, userProvider)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ package com.nextcloud.talk.dagger.modules
|
|||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import com.nextcloud.talk.callnotification.viewmodel.CallNotificationViewModel
|
||||||
|
import com.nextcloud.talk.chat.viewmodels.ChatViewModel
|
||||||
|
import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel
|
||||||
import com.nextcloud.talk.messagesearch.MessageSearchViewModel
|
import com.nextcloud.talk.messagesearch.MessageSearchViewModel
|
||||||
import com.nextcloud.talk.openconversations.viewmodels.OpenConversationsViewModel
|
import com.nextcloud.talk.openconversations.viewmodels.OpenConversationsViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel
|
||||||
@ -112,5 +115,20 @@ abstract class ViewModelModule {
|
|||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@ViewModelKey(OpenConversationsViewModel::class)
|
@ViewModelKey(OpenConversationsViewModel::class)
|
||||||
abstract fun openConversationsViewModelModel(viewModel: OpenConversationsViewModel): ViewModel
|
abstract fun openConversationsViewModel(viewModel: OpenConversationsViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(ChatViewModel::class)
|
||||||
|
abstract fun chatViewModel(viewModel: ChatViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(CallNotificationViewModel::class)
|
||||||
|
abstract fun callNotificationViewModel(viewModel: CallNotificationViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(ConversationInfoEditViewModel::class)
|
||||||
|
abstract fun conversationInfoEditViewModel(viewModel: ConversationInfoEditViewModel): ViewModel
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@ abstract class TalkDatabase : RoomDatabase() {
|
|||||||
|
|
||||||
return Room
|
return Room
|
||||||
.databaseBuilder(context.applicationContext, TalkDatabase::class.java, dbName)
|
.databaseBuilder(context.applicationContext, TalkDatabase::class.java, dbName)
|
||||||
|
// comment out openHelperFactory to view the database entries in Android Studio for debugging
|
||||||
.openHelperFactory(factory)
|
.openHelperFactory(factory)
|
||||||
.addMigrations(Migrations.MIGRATION_6_8, Migrations.MIGRATION_7_8)
|
.addMigrations(Migrations.MIGRATION_6_8, Migrations.MIGRATION_7_8)
|
||||||
.allowMainThreadQueries()
|
.allowMainThreadQueries()
|
||||||
|
@ -44,6 +44,8 @@ import coil.transform.RoundedCornersTransformation
|
|||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
@ -52,11 +54,26 @@ import com.nextcloud.talk.utils.DisplayUtils
|
|||||||
private const val ROUNDING_PIXEL = 16f
|
private const val ROUNDING_PIXEL = 16f
|
||||||
private const val TAG = "ImageViewExtensions"
|
private const val TAG = "ImageViewExtensions"
|
||||||
|
|
||||||
|
@Deprecated("use other constructor that expects com.nextcloud.talk.models.domain.ConversationModel")
|
||||||
fun ImageView.loadConversationAvatar(
|
fun ImageView.loadConversationAvatar(
|
||||||
user: User,
|
user: User,
|
||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
ignoreCache: Boolean,
|
ignoreCache: Boolean,
|
||||||
viewThemeUtils: ViewThemeUtils?
|
viewThemeUtils: ViewThemeUtils?
|
||||||
|
): io.reactivex.disposables.Disposable {
|
||||||
|
return loadConversationAvatar(
|
||||||
|
user,
|
||||||
|
ConversationModel.mapToConversationModel(conversation),
|
||||||
|
ignoreCache,
|
||||||
|
viewThemeUtils
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ImageView.loadConversationAvatar(
|
||||||
|
user: User,
|
||||||
|
conversation: ConversationModel,
|
||||||
|
ignoreCache: Boolean,
|
||||||
|
viewThemeUtils: ViewThemeUtils?
|
||||||
): io.reactivex.disposables.Disposable {
|
): io.reactivex.disposables.Disposable {
|
||||||
val imageRequestUri = ApiUtils.getUrlForConversationAvatarWithVersion(
|
val imageRequestUri = ApiUtils.getUrlForConversationAvatarWithVersion(
|
||||||
1,
|
1,
|
||||||
@ -68,10 +85,10 @@ fun ImageView.loadConversationAvatar(
|
|||||||
|
|
||||||
if (conversation.avatarVersion.isNullOrEmpty() && viewThemeUtils != null) {
|
if (conversation.avatarVersion.isNullOrEmpty() && viewThemeUtils != null) {
|
||||||
when (conversation.type) {
|
when (conversation.type) {
|
||||||
Conversation.ConversationType.ROOM_GROUP_CALL ->
|
ConversationType.ROOM_GROUP_CALL ->
|
||||||
return loadDefaultGroupCallAvatar(viewThemeUtils)
|
return loadDefaultGroupCallAvatar(viewThemeUtils)
|
||||||
|
|
||||||
Conversation.ConversationType.ROOM_PUBLIC_CALL ->
|
ConversationType.ROOM_PUBLIC_CALL ->
|
||||||
return loadDefaultPublicCallAvatar(viewThemeUtils)
|
return loadDefaultPublicCallAvatar(viewThemeUtils)
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
@ -82,10 +99,10 @@ fun ImageView.loadConversationAvatar(
|
|||||||
// when no own images are set. (although these default avatars can not be themed for the android app..)
|
// when no own images are set. (although these default avatars can not be themed for the android app..)
|
||||||
val errorPlaceholder =
|
val errorPlaceholder =
|
||||||
when (conversation.type) {
|
when (conversation.type) {
|
||||||
Conversation.ConversationType.ROOM_GROUP_CALL ->
|
ConversationType.ROOM_GROUP_CALL ->
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_circular_group)
|
ContextCompat.getDrawable(context, R.drawable.ic_circular_group)
|
||||||
|
|
||||||
Conversation.ConversationType.ROOM_PUBLIC_CALL ->
|
ConversationType.ROOM_PUBLIC_CALL ->
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_circular_link)
|
ContextCompat.getDrawable(context, R.drawable.ic_circular_link)
|
||||||
|
|
||||||
else -> ContextCompat.getDrawable(context, R.drawable.account_circle_96dp)
|
else -> ContextCompat.getDrawable(context, R.drawable.account_circle_96dp)
|
||||||
|
@ -55,12 +55,12 @@ import autodagger.AutoInjector
|
|||||||
import com.bluelinelabs.logansquare.LoganSquare
|
import com.bluelinelabs.logansquare.LoganSquare
|
||||||
import com.nextcloud.talk.BuildConfig
|
import com.nextcloud.talk.BuildConfig
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.activities.CallNotificationActivity
|
|
||||||
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
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||||
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
|
import com.nextcloud.talk.arbitrarystorage.ArbitraryStorageManager
|
||||||
|
import com.nextcloud.talk.callnotification.CallNotificationActivity
|
||||||
import com.nextcloud.talk.models.SignatureVerification
|
import com.nextcloud.talk.models.SignatureVerification
|
||||||
import com.nextcloud.talk.models.json.chat.ChatUtils.Companion.getParsedMessage
|
import com.nextcloud.talk.models.json.chat.ChatUtils.Companion.getParsedMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
@ -94,7 +94,6 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_TIMESTAMP
|
|||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARE_RECORDING_TO_CHAT_URL
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHARE_RECORDING_TO_CHAT_URL
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder
|
import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
@ -197,7 +196,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
||||||
bundle.putInt(KEY_NOTIFICATION_TIMESTAMP, pushMessage.timestamp.toInt())
|
bundle.putInt(KEY_NOTIFICATION_TIMESTAMP, pushMessage.timestamp.toInt())
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification.user)
|
bundle.putLong(KEY_INTERNAL_USER_ID, signatureVerification.user!!.id!!)
|
||||||
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, true)
|
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, true)
|
||||||
fullScreenIntent.putExtras(bundle)
|
fullScreenIntent.putExtras(bundle)
|
||||||
fullScreenIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
fullScreenIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
@ -680,7 +679,6 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
shareRecordingIntent.putExtra(KEY_SYSTEM_NOTIFICATION_ID, systemNotificationId)
|
shareRecordingIntent.putExtra(KEY_SYSTEM_NOTIFICATION_ID, systemNotificationId)
|
||||||
shareRecordingIntent.putExtra(KEY_SHARE_RECORDING_TO_CHAT_URL, shareToChatUrl)
|
shareRecordingIntent.putExtra(KEY_SHARE_RECORDING_TO_CHAT_URL, shareToChatUrl)
|
||||||
shareRecordingIntent.putExtra(KEY_ROOM_TOKEN, pushMessage.id)
|
shareRecordingIntent.putExtra(KEY_ROOM_TOKEN, pushMessage.id)
|
||||||
shareRecordingIntent.putExtra(KEY_USER_ENTITY, signatureVerification.user)
|
|
||||||
|
|
||||||
val intentFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
val intentFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
@ -924,7 +922,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification.user)
|
bundle.putLong(KEY_INTERNAL_USER_ID, signatureVerification.user!!.id!!)
|
||||||
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
return intent
|
return intent
|
||||||
@ -935,7 +933,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification.user)
|
bundle.putLong(KEY_INTERNAL_USER_ID, signatureVerification.user!!.id!!)
|
||||||
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ import com.nextcloud.talk.utils.FileUtils
|
|||||||
import com.nextcloud.talk.utils.NotificationUtils
|
import com.nextcloud.talk.utils.NotificationUtils
|
||||||
import com.nextcloud.talk.utils.RemoteFileUtils
|
import com.nextcloud.talk.utils.RemoteFileUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
@ -244,7 +244,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
||||||
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
bundle.putString(KEY_ROOM_TOKEN, roomToken)
|
||||||
bundle.putParcelable(KEY_USER_ENTITY, currentUser)
|
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!)
|
||||||
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, false)
|
||||||
|
|
||||||
intent.putExtras(bundle)
|
intent.putExtras(bundle)
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
package com.nextcloud.talk.models.domain
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
|
||||||
|
class ConversationModel(
|
||||||
|
var roomId: String?,
|
||||||
|
var token: String? = null,
|
||||||
|
var name: String? = null,
|
||||||
|
var displayName: String? = null,
|
||||||
|
var description: String? = null,
|
||||||
|
var type: ConversationType? = null,
|
||||||
|
var lastPing: Long = 0,
|
||||||
|
var participantType: ParticipantType? = null,
|
||||||
|
var hasPassword: Boolean = false,
|
||||||
|
var sessionId: String? = null,
|
||||||
|
var actorId: String? = null,
|
||||||
|
var actorType: String? = null,
|
||||||
|
var password: String? = null,
|
||||||
|
var favorite: Boolean = false,
|
||||||
|
var lastActivity: Long = 0,
|
||||||
|
var unreadMessages: Int = 0,
|
||||||
|
var unreadMention: Boolean = false,
|
||||||
|
// var lastMessage: .....? = null,
|
||||||
|
var objectType: ObjectType? = null,
|
||||||
|
var notificationLevel: NotificationLevel? = null,
|
||||||
|
var conversationReadOnlyState: ConversationReadOnlyState? = null,
|
||||||
|
var lobbyState: LobbyState? = null,
|
||||||
|
var lobbyTimer: Long? = null,
|
||||||
|
var lastReadMessage: Int = 0,
|
||||||
|
var hasCall: Boolean = false,
|
||||||
|
var callFlag: Int = 0,
|
||||||
|
var canStartCall: Boolean = false,
|
||||||
|
var canLeaveConversation: Boolean? = null,
|
||||||
|
var canDeleteConversation: Boolean? = null,
|
||||||
|
var unreadMentionDirect: Boolean? = null,
|
||||||
|
var notificationCalls: Int? = null,
|
||||||
|
var permissions: Int = 0,
|
||||||
|
var messageExpiration: Int = 0,
|
||||||
|
var status: String? = null,
|
||||||
|
var statusIcon: String? = null,
|
||||||
|
var statusMessage: String? = null,
|
||||||
|
var statusClearAt: Long? = 0,
|
||||||
|
var callRecording: Int = 0,
|
||||||
|
var avatarVersion: String? = null,
|
||||||
|
var hasCustomAvatar: Boolean? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun mapToConversationModel(
|
||||||
|
conversation: Conversation
|
||||||
|
): ConversationModel {
|
||||||
|
return ConversationModel(
|
||||||
|
roomId = conversation.roomId,
|
||||||
|
token = conversation.token,
|
||||||
|
name = conversation.name,
|
||||||
|
displayName = conversation.displayName,
|
||||||
|
description = conversation.description,
|
||||||
|
type = conversation.type?.let { ConversationType.valueOf(it.name) },
|
||||||
|
lastPing = conversation.lastPing,
|
||||||
|
participantType = conversation.participantType?.let { ParticipantType.valueOf(it.name) },
|
||||||
|
hasPassword = conversation.hasPassword,
|
||||||
|
sessionId = conversation.sessionId,
|
||||||
|
actorId = conversation.actorId,
|
||||||
|
actorType = conversation.actorType,
|
||||||
|
password = conversation.password,
|
||||||
|
favorite = conversation.favorite,
|
||||||
|
lastActivity = conversation.lastActivity,
|
||||||
|
unreadMessages = conversation.unreadMessages,
|
||||||
|
unreadMention = conversation.unreadMention,
|
||||||
|
// lastMessage = conversation.lastMessage, to do...
|
||||||
|
objectType = conversation.objectType?.let { ObjectType.valueOf(it.name) },
|
||||||
|
notificationLevel = conversation.notificationLevel?.let {
|
||||||
|
NotificationLevel.valueOf(
|
||||||
|
it.name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
conversationReadOnlyState = conversation.conversationReadOnlyState?.let {
|
||||||
|
ConversationReadOnlyState.valueOf(
|
||||||
|
it.name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
lobbyState = conversation.lobbyState?.let { LobbyState.valueOf(it.name) },
|
||||||
|
lobbyTimer = conversation.lobbyTimer,
|
||||||
|
lastReadMessage = conversation.lastReadMessage,
|
||||||
|
hasCall = conversation.hasCall,
|
||||||
|
callFlag = conversation.callFlag,
|
||||||
|
canStartCall = conversation.canStartCall,
|
||||||
|
canLeaveConversation = conversation.canLeaveConversation,
|
||||||
|
canDeleteConversation = conversation.canDeleteConversation,
|
||||||
|
unreadMentionDirect = conversation.unreadMentionDirect,
|
||||||
|
notificationCalls = conversation.notificationCalls,
|
||||||
|
permissions = conversation.permissions,
|
||||||
|
messageExpiration = conversation.messageExpiration,
|
||||||
|
status = conversation.status,
|
||||||
|
statusIcon = conversation.statusIcon,
|
||||||
|
statusMessage = conversation.statusMessage,
|
||||||
|
statusClearAt = conversation.statusClearAt,
|
||||||
|
callRecording = conversation.callRecording,
|
||||||
|
avatarVersion = conversation.avatarVersion,
|
||||||
|
hasCustomAvatar = conversation.hasCustomAvatar
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ConversationType {
|
||||||
|
DUMMY,
|
||||||
|
ROOM_TYPE_ONE_TO_ONE_CALL,
|
||||||
|
ROOM_GROUP_CALL,
|
||||||
|
ROOM_PUBLIC_CALL,
|
||||||
|
ROOM_SYSTEM,
|
||||||
|
FORMER_ONE_TO_ONE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ParticipantType {
|
||||||
|
DUMMY, OWNER, MODERATOR, USER, GUEST, USER_FOLLOWING_LINK, GUEST_MODERATOR
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ObjectType {
|
||||||
|
DEFAULT,
|
||||||
|
SHARE_PASSWORD,
|
||||||
|
FILE,
|
||||||
|
ROOM
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class NotificationLevel {
|
||||||
|
DEFAULT, ALWAYS, MENTION, NEVER
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ConversationReadOnlyState {
|
||||||
|
CONVERSATION_READ_WRITE, CONVERSATION_READ_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class LobbyState {
|
||||||
|
LOBBY_STATE_ALL_PARTICIPANTS, LOBBY_STATE_MODERATORS_ONLY
|
||||||
|
}
|
@ -158,39 +158,47 @@ data class Conversation(
|
|||||||
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
|
||||||
constructor() : this(null, null)
|
constructor() : this(null, null)
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
val isPublic: Boolean
|
val isPublic: Boolean
|
||||||
get() = ConversationType.ROOM_PUBLIC_CALL == type
|
get() = ConversationType.ROOM_PUBLIC_CALL == type
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
val isGuest: Boolean
|
val isGuest: Boolean
|
||||||
get() = ParticipantType.GUEST == participantType ||
|
get() = ParticipantType.GUEST == participantType ||
|
||||||
ParticipantType.GUEST_MODERATOR == participantType ||
|
ParticipantType.GUEST_MODERATOR == participantType ||
|
||||||
ParticipantType.USER_FOLLOWING_LINK == participantType
|
ParticipantType.USER_FOLLOWING_LINK == participantType
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
val isParticipantOwnerOrModerator: Boolean
|
val isParticipantOwnerOrModerator: Boolean
|
||||||
get() = ParticipantType.OWNER == participantType ||
|
get() = ParticipantType.OWNER == participantType ||
|
||||||
ParticipantType.GUEST_MODERATOR == participantType ||
|
ParticipantType.GUEST_MODERATOR == participantType ||
|
||||||
ParticipantType.MODERATOR == participantType
|
ParticipantType.MODERATOR == participantType
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
private fun isLockedOneToOne(conversationUser: User): Boolean {
|
private fun isLockedOneToOne(conversationUser: User): Boolean {
|
||||||
return type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
|
return type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
|
||||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
|
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
fun canModerate(conversationUser: User): Boolean {
|
fun canModerate(conversationUser: User): Boolean {
|
||||||
return isParticipantOwnerOrModerator &&
|
return isParticipantOwnerOrModerator &&
|
||||||
!isLockedOneToOne(conversationUser) &&
|
!isLockedOneToOne(conversationUser) &&
|
||||||
type != ConversationType.FORMER_ONE_TO_ONE
|
type != ConversationType.FORMER_ONE_TO_ONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
fun isLobbyViewApplicable(conversationUser: User): Boolean {
|
fun isLobbyViewApplicable(conversationUser: User): Boolean {
|
||||||
return !canModerate(conversationUser) &&
|
return !canModerate(conversationUser) &&
|
||||||
(type == ConversationType.ROOM_GROUP_CALL || type == ConversationType.ROOM_PUBLIC_CALL)
|
(type == ConversationType.ROOM_GROUP_CALL || type == ConversationType.ROOM_PUBLIC_CALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
fun isNameEditable(conversationUser: User): Boolean {
|
fun isNameEditable(conversationUser: User): Boolean {
|
||||||
return canModerate(conversationUser) && ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != type
|
return canModerate(conversationUser) && ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
fun canLeave(): Boolean {
|
fun canLeave(): Boolean {
|
||||||
return if (canLeaveConversation != null) {
|
return if (canLeaveConversation != null) {
|
||||||
// Available since APIv2
|
// Available since APIv2
|
||||||
@ -200,6 +208,7 @@ data class Conversation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ConversationUtil")
|
||||||
fun canDelete(conversationUser: User): Boolean {
|
fun canDelete(conversationUser: User): Boolean {
|
||||||
return if (canDeleteConversation != null) {
|
return if (canDeleteConversation != null) {
|
||||||
// Available since APIv2
|
// Available since APIv2
|
||||||
|
@ -79,10 +79,7 @@ class ListOpenConversationsActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun adapterOnClick(conversation: OpenConversation) {
|
private fun adapterOnClick(conversation: OpenConversation) {
|
||||||
val user = userProvider.currentUser.blockingGet()
|
|
||||||
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, user)
|
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.roomToken)
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.roomToken)
|
||||||
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
|
@ -37,6 +37,7 @@ import com.nextcloud.talk.data.user.model.User
|
|||||||
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
@ -48,16 +49,22 @@ class PollMainDialogFragment : DialogFragment() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var viewThemeUtils: ViewThemeUtils
|
lateinit var viewThemeUtils: ViewThemeUtils
|
||||||
|
|
||||||
|
var currentUserProvider: CurrentUserProviderNew? = null
|
||||||
|
@Inject set
|
||||||
|
|
||||||
private lateinit var binding: DialogPollMainBinding
|
private lateinit var binding: DialogPollMainBinding
|
||||||
private lateinit var viewModel: PollMainViewModel
|
private lateinit var viewModel: PollMainViewModel
|
||||||
|
|
||||||
|
lateinit var user: User
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
|
|
||||||
viewModel = ViewModelProvider(this, viewModelFactory)[PollMainViewModel::class.java]
|
viewModel = ViewModelProvider(this, viewModelFactory)[PollMainViewModel::class.java]
|
||||||
|
|
||||||
val user: User = arguments?.getParcelable(KEY_USER_ENTITY)!!
|
user = currentUserProvider?.currentUser?.blockingGet()!!
|
||||||
|
|
||||||
val roomToken = arguments?.getString(KEY_ROOM_TOKEN)!!
|
val roomToken = arguments?.getString(KEY_ROOM_TOKEN)!!
|
||||||
val isOwnerOrModerator = arguments?.getBoolean(KEY_OWNER_OR_MODERATOR)!!
|
val isOwnerOrModerator = arguments?.getBoolean(KEY_OWNER_OR_MODERATOR)!!
|
||||||
val pollId = arguments?.getString(KEY_POLL_ID)!!
|
val pollId = arguments?.getString(KEY_POLL_ID)!!
|
||||||
|
@ -56,8 +56,6 @@ class ShareRecordingToChatReceiver : BroadcastReceiver() {
|
|||||||
lateinit var currentUser: User
|
lateinit var currentUser: User
|
||||||
private var systemNotificationId: Int? = null
|
private var systemNotificationId: Int? = null
|
||||||
private var link: String? = null
|
private var link: String? = null
|
||||||
var roomToken: String? = null
|
|
||||||
var conversationOfShareTarget: User? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
@ -68,9 +66,6 @@ class ShareRecordingToChatReceiver : BroadcastReceiver() {
|
|||||||
systemNotificationId = intent!!.getIntExtra(KEY_SYSTEM_NOTIFICATION_ID, 0)
|
systemNotificationId = intent!!.getIntExtra(KEY_SYSTEM_NOTIFICATION_ID, 0)
|
||||||
link = intent.getStringExtra(BundleKeys.KEY_SHARE_RECORDING_TO_CHAT_URL)
|
link = intent.getStringExtra(BundleKeys.KEY_SHARE_RECORDING_TO_CHAT_URL)
|
||||||
|
|
||||||
roomToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)
|
|
||||||
conversationOfShareTarget = intent.getParcelableExtra<User>(BundleKeys.KEY_USER_ENTITY)
|
|
||||||
|
|
||||||
val id = intent.getLongExtra(KEY_INTERNAL_USER_ID, userManager.currentUser.blockingGet().id!!)
|
val id = intent.getLongExtra(KEY_INTERNAL_USER_ID, userManager.currentUser.blockingGet().id!!)
|
||||||
currentUser = userManager.getUserWithId(id).blockingGet()
|
currentUser = userManager.getUserWithId(id).blockingGet()
|
||||||
|
|
||||||
|
@ -23,19 +23,18 @@ package com.nextcloud.talk.repositories.reactions
|
|||||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
|
||||||
interface ReactionsRepository {
|
interface ReactionsRepository {
|
||||||
|
|
||||||
fun addReaction(
|
fun addReaction(
|
||||||
currentConversation: Conversation,
|
roomToken: String,
|
||||||
message: ChatMessage,
|
message: ChatMessage,
|
||||||
emoji: String
|
emoji: String
|
||||||
): Observable<ReactionAddedModel>
|
): Observable<ReactionAddedModel>
|
||||||
|
|
||||||
fun deleteReaction(
|
fun deleteReaction(
|
||||||
currentConversation: Conversation,
|
roomToken: String,
|
||||||
message: ChatMessage,
|
message: ChatMessage,
|
||||||
emoji: String
|
emoji: String
|
||||||
): Observable<ReactionDeletedModel>
|
): Observable<ReactionDeletedModel>
|
||||||
|
@ -25,7 +25,6 @@ import com.nextcloud.talk.data.user.model.User
|
|||||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
|
||||||
import com.nextcloud.talk.models.json.generic.GenericMeta
|
import com.nextcloud.talk.models.json.generic.GenericMeta
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
@ -38,7 +37,7 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||||||
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
|
||||||
|
|
||||||
override fun addReaction(
|
override fun addReaction(
|
||||||
currentConversation: Conversation,
|
roomToken: String,
|
||||||
message: ChatMessage,
|
message: ChatMessage,
|
||||||
emoji: String
|
emoji: String
|
||||||
): Observable<ReactionAddedModel> {
|
): Observable<ReactionAddedModel> {
|
||||||
@ -46,7 +45,7 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForMessageReaction(
|
ApiUtils.getUrlForMessageReaction(
|
||||||
currentUser.baseUrl,
|
currentUser.baseUrl,
|
||||||
currentConversation.token,
|
roomToken,
|
||||||
message.id
|
message.id
|
||||||
),
|
),
|
||||||
emoji
|
emoji
|
||||||
@ -54,7 +53,7 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteReaction(
|
override fun deleteReaction(
|
||||||
currentConversation: Conversation,
|
roomToken: String,
|
||||||
message: ChatMessage,
|
message: ChatMessage,
|
||||||
emoji: String
|
emoji: String
|
||||||
): Observable<ReactionDeletedModel> {
|
): Observable<ReactionDeletedModel> {
|
||||||
@ -62,7 +61,7 @@ class ReactionsRepositoryImpl(private val ncApi: NcApi, currentUserProvider: Cur
|
|||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForMessageReaction(
|
ApiUtils.getUrlForMessageReaction(
|
||||||
currentUser.baseUrl,
|
currentUser.baseUrl,
|
||||||
currentConversation.token,
|
roomToken,
|
||||||
message.id
|
message.id
|
||||||
),
|
),
|
||||||
emoji
|
emoji
|
||||||
|
@ -49,12 +49,15 @@ import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
|||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class SharedItemsActivity : AppCompatActivity() {
|
class SharedItemsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var currentUserProvider: CurrentUserProviderNew
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
@ -70,7 +73,9 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
val roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
|
val roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
|
||||||
val conversationName = intent.getStringExtra(KEY_CONVERSATION_NAME)
|
val conversationName = intent.getStringExtra(KEY_CONVERSATION_NAME)
|
||||||
val user = intent.getParcelableExtra<User>(KEY_USER_ENTITY)!!
|
|
||||||
|
val user = currentUserProvider.currentUser.blockingGet()
|
||||||
|
|
||||||
val isUserConversationOwnerOrModerator = intent.getBooleanExtra(KEY_USER_IS_OWNER_OR_MODERATOR, false)
|
val isUserConversationOwnerOrModerator = intent.getBooleanExtra(KEY_USER_IS_OWNER_OR_MODERATOR, false)
|
||||||
|
|
||||||
binding = ActivitySharedItemsBinding.inflate(layoutInflater)
|
binding = ActivitySharedItemsBinding.inflate(layoutInflater)
|
||||||
|
@ -46,7 +46,6 @@ 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
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import org.parceler.Parcels
|
|
||||||
|
|
||||||
private const val TAG = "ProfileBottomSheet"
|
private const val TAG = "ProfileBottomSheet"
|
||||||
|
|
||||||
@ -144,46 +143,13 @@ class ProfileBottomSheet(val ncApi: NcApi, val userModel: User) {
|
|||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, userModel)
|
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.ocs!!.data!!.token)
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
|
|
||||||
// FIXME once APIv2+ is used only, the createRoom already returns all the data
|
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||||
ncApi.getRoom(
|
chatIntent.putExtras(bundle)
|
||||||
credentials,
|
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
ApiUtils.getUrlForRoom(
|
context.startActivity(chatIntent)
|
||||||
apiVersion,
|
|
||||||
userModel.baseUrl,
|
|
||||||
roomOverall.ocs!!.data!!.token
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(object : Observer<RoomOverall> {
|
|
||||||
override fun onSubscribe(d: Disposable) {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
|
||||||
bundle.putParcelable(
|
|
||||||
BundleKeys.KEY_ACTIVE_CONVERSATION,
|
|
||||||
Parcels.wrap(roomOverall.ocs!!.data)
|
|
||||||
)
|
|
||||||
|
|
||||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
|
||||||
chatIntent.putExtras(bundle)
|
|
||||||
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
||||||
context.startActivity(chatIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
Log.e(TAG, e.message, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
// unused atm
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
|
@ -203,7 +203,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
|
|||||||
dismiss();
|
dismiss();
|
||||||
|
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(user, status);
|
SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(status);
|
||||||
setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
|
setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status");
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "status was null");
|
Log.w(TAG, "status was null");
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.ui.dialog
|
package com.nextcloud.talk.ui.dialog
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -55,16 +54,13 @@ import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
|||||||
import com.nextcloud.talk.users.UserManager
|
import com.nextcloud.talk.users.UserManager
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_OPERATION_CODE
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
import org.parceler.Parcels
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class ConversationsListBottomDialog(
|
class ConversationsListBottomDialog(
|
||||||
val activity: Activity,
|
val activity: ConversationsListActivity,
|
||||||
val controller: ConversationsListActivity,
|
|
||||||
val currentUser: User,
|
val currentUser: User,
|
||||||
val conversation: Conversation
|
val conversation: Conversation
|
||||||
) : BottomSheetDialog(activity) {
|
) : BottomSheetDialog(activity) {
|
||||||
@ -175,9 +171,8 @@ class ConversationsListBottomDialog(
|
|||||||
if (!TextUtils.isEmpty(conversation.token)) {
|
if (!TextUtils.isEmpty(conversation.token)) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!)
|
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id!!)
|
||||||
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
|
bundle.putString(KEY_ROOM_TOKEN, conversation.token)
|
||||||
|
activity.showDeleteConversationDialog(bundle)
|
||||||
controller.showDeleteConversationDialog(bundle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dismiss()
|
dismiss()
|
||||||
@ -198,8 +193,8 @@ class ConversationsListBottomDialog(
|
|||||||
|
|
||||||
private fun executeOperationsMenuController(operation: ConversationOperationEnum) {
|
private fun executeOperationsMenuController(operation: ConversationOperationEnum) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
|
|
||||||
bundle.putSerializable(KEY_OPERATION_CODE, operation)
|
bundle.putSerializable(KEY_OPERATION_CODE, operation)
|
||||||
|
bundle.putString(KEY_ROOM_TOKEN, conversation.token)
|
||||||
|
|
||||||
binding.operationItemsLayout.visibility = View.GONE
|
binding.operationItemsLayout.visibility = View.GONE
|
||||||
|
|
||||||
@ -211,13 +206,13 @@ class ConversationsListBottomDialog(
|
|||||||
.popChangeHandler(HorizontalChangeHandler())
|
.popChangeHandler(HorizontalChangeHandler())
|
||||||
)
|
)
|
||||||
|
|
||||||
controller.fetchRooms()
|
activity.fetchRooms()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun executeEntryMenuController(operation: ConversationOperationEnum) {
|
private fun executeEntryMenuController(operation: ConversationOperationEnum) {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
|
|
||||||
bundle.putSerializable(KEY_OPERATION_CODE, operation)
|
bundle.putSerializable(KEY_OPERATION_CODE, operation)
|
||||||
|
bundle.putString(KEY_ROOM_TOKEN, conversation.token)
|
||||||
|
|
||||||
binding.operationItemsLayout.visibility = View.GONE
|
binding.operationItemsLayout.visibility = View.GONE
|
||||||
|
|
||||||
|
@ -40,10 +40,12 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||||||
import com.nextcloud.talk.chat.ChatActivity
|
import com.nextcloud.talk.chat.ChatActivity
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
import com.nextcloud.talk.databinding.DialogMessageActionsBinding
|
import com.nextcloud.talk.databinding.DialogMessageActionsBinding
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationReadOnlyState
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
import com.nextcloud.talk.models.domain.ReactionAddedModel
|
||||||
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
import com.nextcloud.talk.models.domain.ReactionDeletedModel
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
|
||||||
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
|
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
@ -63,7 +65,7 @@ class MessageActionsDialog(
|
|||||||
private val chatActivity: ChatActivity,
|
private val chatActivity: ChatActivity,
|
||||||
private val message: ChatMessage,
|
private val message: ChatMessage,
|
||||||
private val user: User?,
|
private val user: User?,
|
||||||
private val currentConversation: Conversation?,
|
private val currentConversation: ConversationModel?,
|
||||||
private val showMessageDeletionButton: Boolean,
|
private val showMessageDeletionButton: Boolean,
|
||||||
private val hasChatPermission: Boolean
|
private val hasChatPermission: Boolean
|
||||||
) : BottomSheetDialog(chatActivity) {
|
) : BottomSheetDialog(chatActivity) {
|
||||||
@ -100,7 +102,7 @@ class MessageActionsDialog(
|
|||||||
message.replyable &&
|
message.replyable &&
|
||||||
hasUserId(user) &&
|
hasUserId(user) &&
|
||||||
hasUserActorId(message) &&
|
hasUserActorId(message) &&
|
||||||
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
||||||
)
|
)
|
||||||
initMenuDeleteMessage(showMessageDeletionButton)
|
initMenuDeleteMessage(showMessageDeletionButton)
|
||||||
initMenuForwardMessage(
|
initMenuForwardMessage(
|
||||||
@ -226,7 +228,7 @@ class MessageActionsDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isPermitted(hasChatPermission: Boolean): Boolean {
|
private fun isPermitted(hasChatPermission: Boolean): Boolean {
|
||||||
return hasChatPermission && Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY !=
|
return hasChatPermission && ConversationReadOnlyState.CONVERSATION_READ_ONLY !=
|
||||||
currentConversation?.conversationReadOnlyState
|
currentConversation?.conversationReadOnlyState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,12 +340,12 @@ class MessageActionsDialog(
|
|||||||
|
|
||||||
private fun clickOnEmoji(message: ChatMessage, emoji: String) {
|
private fun clickOnEmoji(message: ChatMessage, emoji: String) {
|
||||||
if (message.reactionsSelf?.contains(emoji) == true) {
|
if (message.reactionsSelf?.contains(emoji) == true) {
|
||||||
reactionsRepository.deleteReaction(currentConversation!!, message, emoji)
|
reactionsRepository.deleteReaction(currentConversation!!.token!!, message, emoji)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
?.subscribe(ReactionDeletedObserver())
|
?.subscribe(ReactionDeletedObserver())
|
||||||
} else {
|
} else {
|
||||||
reactionsRepository.addReaction(currentConversation!!, message, emoji)
|
reactionsRepository.addReaction(currentConversation!!.token!!, message, emoji)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
?.subscribe(ReactionAddedObserver())
|
?.subscribe(ReactionAddedObserver())
|
||||||
|
@ -60,6 +60,7 @@ import com.nextcloud.talk.models.json.status.predefined.PredefinedStatusOverall
|
|||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
|
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||||
import com.vanniktech.emoji.EmojiPopup
|
import com.vanniktech.emoji.EmojiPopup
|
||||||
import com.vanniktech.emoji.installDisableKeyboardInput
|
import com.vanniktech.emoji.installDisableKeyboardInput
|
||||||
import com.vanniktech.emoji.installForceSingleEmoji
|
import com.vanniktech.emoji.installForceSingleEmoji
|
||||||
@ -113,6 +114,9 @@ class SetStatusDialogFragment :
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var viewThemeUtils: ViewThemeUtils
|
lateinit var viewThemeUtils: ViewThemeUtils
|
||||||
|
|
||||||
|
var currentUserProvider: CurrentUserProviderNew? = null
|
||||||
|
@Inject set
|
||||||
|
|
||||||
lateinit var credentials: String
|
lateinit var credentials: String
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -121,7 +125,7 @@ class SetStatusDialogFragment :
|
|||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
|
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
|
currentUser = currentUserProvider?.currentUser?.blockingGet()
|
||||||
currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
|
currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
|
||||||
|
|
||||||
credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
|
credentials = ApiUtils.getCredentials(currentUser?.username, currentUser?.token)
|
||||||
@ -559,9 +563,8 @@ class SetStatusDialogFragment :
|
|||||||
private val TAG = SetStatusDialogFragment::class.simpleName
|
private val TAG = SetStatusDialogFragment::class.simpleName
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newInstance(user: User, status: Status): SetStatusDialogFragment {
|
fun newInstance(status: Status): SetStatusDialogFragment {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putParcelable(ARG_CURRENT_USER_PARAM, user)
|
|
||||||
args.putParcelable(ARG_CURRENT_STATUS_PARAM, status)
|
args.putParcelable(ARG_CURRENT_STATUS_PARAM, status)
|
||||||
|
|
||||||
val dialogFragment = SetStatusDialogFragment()
|
val dialogFragment = SetStatusDialogFragment()
|
||||||
|
@ -44,7 +44,6 @@ import com.nextcloud.talk.data.user.model.User
|
|||||||
import com.nextcloud.talk.databinding.DialogMessageReactionsBinding
|
import com.nextcloud.talk.databinding.DialogMessageReactionsBinding
|
||||||
import com.nextcloud.talk.databinding.ItemReactionsTabBinding
|
import com.nextcloud.talk.databinding.ItemReactionsTabBinding
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
import com.nextcloud.talk.models.json.reactions.ReactionsOverall
|
import com.nextcloud.talk.models.json.reactions.ReactionsOverall
|
||||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||||
@ -59,7 +58,7 @@ import javax.inject.Inject
|
|||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class ShowReactionsDialog(
|
class ShowReactionsDialog(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
private val currentConversation: Conversation?,
|
private val roomToken: String,
|
||||||
private val chatMessage: ChatMessage,
|
private val chatMessage: ChatMessage,
|
||||||
private val user: User?,
|
private val user: User?,
|
||||||
private val hasChatPermission: Boolean,
|
private val hasChatPermission: Boolean,
|
||||||
@ -156,7 +155,7 @@ class ShowReactionsDialog(
|
|||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForMessageReaction(
|
ApiUtils.getUrlForMessageReaction(
|
||||||
user?.baseUrl,
|
user?.baseUrl,
|
||||||
currentConversation!!.token,
|
roomToken,
|
||||||
chatMessage.id
|
chatMessage.id
|
||||||
),
|
),
|
||||||
emoji
|
emoji
|
||||||
@ -211,7 +210,7 @@ class ShowReactionsDialog(
|
|||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForMessageReaction(
|
ApiUtils.getUrlForMessageReaction(
|
||||||
user?.baseUrl,
|
user?.baseUrl,
|
||||||
currentConversation!!.token,
|
roomToken,
|
||||||
message.id
|
message.id
|
||||||
),
|
),
|
||||||
emoji
|
emoji
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.nextcloud.talk.utils
|
||||||
|
|
||||||
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationType
|
||||||
|
import com.nextcloud.talk.models.domain.ParticipantType
|
||||||
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
* @author Marcel Hibbe
|
||||||
|
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
object ConversationUtils {
|
||||||
|
private val TAG = ConversationUtils::class.java.simpleName
|
||||||
|
|
||||||
|
fun isPublic(conversation: ConversationModel): Boolean {
|
||||||
|
return ConversationType.ROOM_PUBLIC_CALL == conversation.type
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isGuest(conversation: ConversationModel): Boolean {
|
||||||
|
return ParticipantType.GUEST == conversation.participantType ||
|
||||||
|
ParticipantType.GUEST_MODERATOR == conversation.participantType ||
|
||||||
|
ParticipantType.USER_FOLLOWING_LINK == conversation.participantType
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isParticipantOwnerOrModerator(conversation: ConversationModel): Boolean {
|
||||||
|
return ParticipantType.OWNER == conversation.participantType ||
|
||||||
|
ParticipantType.GUEST_MODERATOR == conversation.participantType ||
|
||||||
|
ParticipantType.MODERATOR == conversation.participantType
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isLockedOneToOne(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||||
|
return conversation.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
|
||||||
|
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canModerate(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||||
|
return isParticipantOwnerOrModerator(conversation) &&
|
||||||
|
!isLockedOneToOne(conversation, conversationUser) &&
|
||||||
|
conversation.type != ConversationType.FORMER_ONE_TO_ONE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isLobbyViewApplicable(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||||
|
return !canModerate(conversation, conversationUser) &&
|
||||||
|
(
|
||||||
|
conversation.type == ConversationType.ROOM_GROUP_CALL ||
|
||||||
|
conversation.type == ConversationType.ROOM_PUBLIC_CALL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNameEditable(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||||
|
return canModerate(conversation, conversationUser) &&
|
||||||
|
ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != conversation.type
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canLeave(conversation: ConversationModel): Boolean {
|
||||||
|
return if (conversation.canLeaveConversation != null) {
|
||||||
|
// Available since APIv2
|
||||||
|
conversation.canLeaveConversation!!
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canDelete(conversation: ConversationModel, conversationUser: User): Boolean {
|
||||||
|
return if (conversation.canDeleteConversation != null) {
|
||||||
|
// Available since APIv2
|
||||||
|
conversation.canDeleteConversation!!
|
||||||
|
} else {
|
||||||
|
canModerate(conversation, conversationUser)
|
||||||
|
// Fallback for APIv1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@
|
|||||||
package com.nextcloud.talk.utils
|
package com.nextcloud.talk.utils
|
||||||
|
|
||||||
import com.nextcloud.talk.data.user.model.User
|
import com.nextcloud.talk.data.user.model.User
|
||||||
|
import com.nextcloud.talk.models.domain.ConversationModel
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
||||||
|
|
||||||
@ -31,9 +32,15 @@ import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
|
|||||||
*/
|
*/
|
||||||
class ParticipantPermissions(
|
class ParticipantPermissions(
|
||||||
private val user: User,
|
private val user: User,
|
||||||
private val conversation: Conversation
|
private val conversation: ConversationModel
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@Deprecated("Use ChatRepository.ConversationModel")
|
||||||
|
constructor(user: User, conversation: Conversation) : this(
|
||||||
|
user,
|
||||||
|
ConversationModel.mapToConversationModel(conversation)
|
||||||
|
)
|
||||||
|
|
||||||
val isDefault = (conversation.permissions and DEFAULT) == DEFAULT
|
val isDefault = (conversation.permissions and DEFAULT) == DEFAULT
|
||||||
val isCustom = (conversation.permissions and CUSTOM) == CUSTOM
|
val isCustom = (conversation.permissions and CUSTOM) == CUSTOM
|
||||||
private val canStartCall = (conversation.permissions and START_CALL) == START_CALL
|
private val canStartCall = (conversation.permissions and START_CALL) == START_CALL
|
||||||
|
@ -33,19 +33,17 @@ object BundleKeys {
|
|||||||
const val KEY_BASE_URL = "KEY_BASE_URL"
|
const val KEY_BASE_URL = "KEY_BASE_URL"
|
||||||
const val KEY_IS_ACCOUNT_IMPORT = "KEY_IS_ACCOUNT_IMPORT"
|
const val KEY_IS_ACCOUNT_IMPORT = "KEY_IS_ACCOUNT_IMPORT"
|
||||||
const val KEY_ORIGINAL_PROTOCOL = "KEY_ORIGINAL_PROTOCOL"
|
const val KEY_ORIGINAL_PROTOCOL = "KEY_ORIGINAL_PROTOCOL"
|
||||||
const val KEY_ROOM = "KEY_CONVERSATION"
|
|
||||||
const val KEY_OPERATION_CODE = "KEY_OPERATION_CODE"
|
const val KEY_OPERATION_CODE = "KEY_OPERATION_CODE"
|
||||||
const val KEY_SHARE_INTENT = "KEY_SHARE_INTENT"
|
|
||||||
const val KEY_APP_ITEM_PACKAGE_NAME = "KEY_APP_ITEM_PACKAGE_NAME"
|
const val KEY_APP_ITEM_PACKAGE_NAME = "KEY_APP_ITEM_PACKAGE_NAME"
|
||||||
const val KEY_APP_ITEM_NAME = "KEY_APP_ITEM_NAME"
|
const val KEY_APP_ITEM_NAME = "KEY_APP_ITEM_NAME"
|
||||||
const val KEY_CONVERSATION_PASSWORD = "KEY_CONVERSATION_PASSWORD"
|
const val KEY_CONVERSATION_PASSWORD = "KEY_CONVERSATION_PASSWORD"
|
||||||
const val KEY_ROOM_TOKEN = "KEY_ROOM_TOKEN"
|
const val KEY_ROOM_TOKEN = "KEY_ROOM_TOKEN"
|
||||||
const val KEY_ROOM_ONE_TO_ONE = "KEY_ROOM_ONE_TO_ONE"
|
const val KEY_ROOM_ONE_TO_ONE = "KEY_ROOM_ONE_TO_ONE"
|
||||||
const val KEY_USER_ENTITY = "KEY_USER_ENTITY"
|
|
||||||
const val KEY_NEW_CONVERSATION = "KEY_NEW_CONVERSATION"
|
const val KEY_NEW_CONVERSATION = "KEY_NEW_CONVERSATION"
|
||||||
const val KEY_ADD_PARTICIPANTS = "KEY_ADD_PARTICIPANTS"
|
const val KEY_ADD_PARTICIPANTS = "KEY_ADD_PARTICIPANTS"
|
||||||
const val KEY_EXISTING_PARTICIPANTS = "KEY_EXISTING_PARTICIPANTS"
|
const val KEY_EXISTING_PARTICIPANTS = "KEY_EXISTING_PARTICIPANTS"
|
||||||
const val KEY_CALL_URL = "KEY_CALL_URL"
|
const val KEY_CALL_URL = "KEY_CALL_URL"
|
||||||
|
const val KEY_NEW_ROOM_NAME = "KEY_NEW_ROOM_NAME"
|
||||||
const val KEY_MODIFIED_BASE_URL = "KEY_MODIFIED_BASE_URL"
|
const val KEY_MODIFIED_BASE_URL = "KEY_MODIFIED_BASE_URL"
|
||||||
const val KEY_NOTIFICATION_SUBJECT = "KEY_NOTIFICATION_SUBJECT"
|
const val KEY_NOTIFICATION_SUBJECT = "KEY_NOTIFICATION_SUBJECT"
|
||||||
const val KEY_NOTIFICATION_SIGNATURE = "KEY_NOTIFICATION_SIGNATURE"
|
const val KEY_NOTIFICATION_SIGNATURE = "KEY_NOTIFICATION_SIGNATURE"
|
||||||
@ -59,8 +57,6 @@ object BundleKeys {
|
|||||||
const val KEY_RECORDING_STATE = "KEY_RECORDING_STATE"
|
const val KEY_RECORDING_STATE = "KEY_RECORDING_STATE"
|
||||||
const val KEY_CALL_VOICE_ONLY = "KEY_CALL_VOICE_ONLY"
|
const val KEY_CALL_VOICE_ONLY = "KEY_CALL_VOICE_ONLY"
|
||||||
const val KEY_CALL_WITHOUT_NOTIFICATION = "KEY_CALL_WITHOUT_NOTIFICATION"
|
const val KEY_CALL_WITHOUT_NOTIFICATION = "KEY_CALL_WITHOUT_NOTIFICATION"
|
||||||
const val KEY_ACTIVE_CONVERSATION = "KEY_ACTIVE_CONVERSATION"
|
|
||||||
const val KEY_SERVER_CAPABILITIES = "KEY_SERVER_CAPABILITIES"
|
|
||||||
const val KEY_FROM_NOTIFICATION_START_CALL = "KEY_FROM_NOTIFICATION_START_CALL"
|
const val KEY_FROM_NOTIFICATION_START_CALL = "KEY_FROM_NOTIFICATION_START_CALL"
|
||||||
const val KEY_ROOM_ID = "KEY_ROOM_ID"
|
const val KEY_ROOM_ID = "KEY_ROOM_ID"
|
||||||
const val KEY_ARE_CALL_SOUNDS = "KEY_ARE_CALL_SOUNDS"
|
const val KEY_ARE_CALL_SOUNDS = "KEY_ARE_CALL_SOUNDS"
|
||||||
|
Loading…
Reference in New Issue
Block a user