Merge pull request #4527 from nextcloud/style/noid/lowerDetektScore

Lower detekt score
This commit is contained in:
Marcel Hibbe 2024-12-10 09:13:25 +01:00 committed by GitHub
commit 54d1512fff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 704 additions and 674 deletions

View file

@ -239,41 +239,13 @@ class ServerSelectionActivity : BaseActivity() {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ status: Status ->
val productName = resources!!.getString(R.string.nc_server_product_name)
val versionString: String = status.version!!.substring(0, status.version!!.indexOf("."))
val version: Int = versionString.toInt()
if (isServerStatusQueryable(status) && version >= MIN_SERVER_MAJOR_VERSION) {
findServerTalkApp(url)
} else if (!status.installed) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_not_installed),
productName
)
)
} else if (status.needsUpgrade) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_db_upgrade_needed),
productName
)
)
} else if (status.maintenance) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_maintenance),
productName
)
)
} else if (!status.version!!.startsWith("13.")) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_version),
resources!!.getString(R.string.nc_app_product_name),
productName
)
)
} else {
showErrorTextForStatus(status)
}
}, { throwable: Throwable ->
if (checkForcedHttps) {
@ -303,6 +275,39 @@ class ServerSelectionActivity : BaseActivity() {
}
}
private fun showErrorTextForStatus(status: Status) {
if (!status.installed) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_not_installed),
resources!!.getString(R.string.nc_server_product_name)
)
)
} else if (status.needsUpgrade) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_db_upgrade_needed),
resources!!.getString(R.string.nc_server_product_name)
)
)
} else if (status.maintenance) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_maintenance),
resources!!.getString(R.string.nc_server_product_name)
)
)
} else if (!status.version!!.startsWith("13.")) {
setErrorText(
String.format(
resources!!.getString(R.string.nc_server_version),
resources!!.getString(R.string.nc_app_product_name),
resources!!.getString(R.string.nc_server_product_name)
)
)
}
}
private fun findServerTalkApp(queryUrl: String) {
ncApi.getCapabilities(ApiUtils.getUrlForCapabilities(queryUrl))
.subscribeOn(Schedulers.io())
@ -364,7 +369,7 @@ class ServerSelectionActivity : BaseActivity() {
return status.installed && !status.maintenance && !status.needsUpgrade
}
private fun setErrorText(text: String) {
private fun setErrorText(text: String?) {
binding.errorWrapper.visibility = View.VISIBLE
binding.errorText.text = text
hideserverEntryProgressBar()

View file

@ -220,11 +220,11 @@ class WebViewLoginActivity : BaseActivity() {
}
override fun onReceivedClientCertRequest(view: WebView, request: ClientCertRequest) {
val user = userManager.currentUser.blockingGet()
var alias: String? = null
if (!reauthorizeAccount) {
alias = appPreferences.temporaryClientCertAlias
}
val user = userManager.currentUser.blockingGet()
if (TextUtils.isEmpty(alias) && user != null) {
alias = user.clientCertificate
}

View file

@ -371,27 +371,11 @@ class CallActivity : CallBaseActivity() {
binding = CallActivityBinding.inflate(layoutInflater)
setContentView(binding!!.root)
hideNavigationIfNoPipAvailable()
conversationUser = currentUserProvider.currentUser.blockingGet()
val extras = intent.extras
roomId = extras!!.getString(KEY_ROOM_ID, "")
roomToken = extras.getString(KEY_ROOM_TOKEN, "")
conversationPassword = extras.getString(KEY_CONVERSATION_PASSWORD, "")
conversationName = extras.getString(KEY_CONVERSATION_NAME, "")
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false)
isCallWithoutNotification = extras.getBoolean(KEY_CALL_WITHOUT_NOTIFICATION, false)
canPublishAudioStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO)
canPublishVideoStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO)
isModerator = extras.getBoolean(KEY_IS_MODERATOR, false)
isOneToOneConversation = extras.getBoolean(KEY_ROOM_ONE_TO_ONE, false)
processExtras(intent.extras!!)
conversationUser = currentUserProvider.currentUser.blockingGet()
if (extras.containsKey(KEY_FROM_NOTIFICATION_START_CALL)) {
isIncomingCallFromNotification = extras.getBoolean(KEY_FROM_NOTIFICATION_START_CALL)
}
if (extras.containsKey(KEY_IS_BREAKOUT_ROOM)) {
isBreakoutRoom = extras.getBoolean(KEY_IS_BREAKOUT_ROOM)
}
credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token)
baseUrl = extras.getString(KEY_MODIFIED_BASE_URL, "")
if (TextUtils.isEmpty(baseUrl)) {
baseUrl = conversationUser!!.baseUrl
}
@ -399,28 +383,30 @@ class CallActivity : CallBaseActivity() {
setCallState(CallStatus.CONNECTING)
raiseHandViewModel = ViewModelProvider(this, viewModelFactory).get(RaiseHandViewModel::class.java)
raiseHandViewModel!!.setData(roomToken!!, isBreakoutRoom)
raiseHandViewModel!!.viewState.observe(this) { viewState: RaiseHandViewModel.ViewState? ->
var raised = false
if (viewState is RaisedHandState) {
binding!!.lowerHandButton.visibility = View.VISIBLE
raised = true
} else if (viewState is LoweredHandState) {
binding!!.lowerHandButton.visibility = View.GONE
raised = false
}
if (isConnectionEstablished) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
peerConnectionWrapper.raiseHand(raised)
}
}
initRaiseHandViewModel()
initCallRecordingViewModel(intent.extras!!.getInt(KEY_RECORDING_STATE))
initClickListeners(isModerator, isOneToOneConversation)
binding!!.microphoneButton.setOnTouchListener(MicrophoneButtonTouchListener())
pulseAnimation = PulseAnimation.create().with(binding!!.microphoneButton)
.setDuration(PULSE_ANIMATION_DURATION)
.setRepeatCount(PulseAnimation.INFINITE)
.setRepeatMode(PulseAnimation.REVERSE)
basicInitialization()
callParticipants = HashMap()
participantDisplayItems = HashMap()
initViews()
updateSelfVideoViewPosition()
reactionAnimator = ReactionAnimator(context, binding!!.reactionAnimationWrapper, viewThemeUtils)
checkRecordingConsentAndInitiateCall()
}
private fun initCallRecordingViewModel(recordingState: Int) {
callRecordingViewModel = ViewModelProvider(this, viewModelFactory).get(
CallRecordingViewModel::class.java
)
callRecordingViewModel!!.setData(roomToken!!)
callRecordingViewModel!!.setRecordingState(extras.getInt(KEY_RECORDING_STATE))
callRecordingViewModel!!.setRecordingState(recordingState)
callRecordingViewModel!!.viewState.observe(this) { viewState: CallRecordingViewModel.ViewState? ->
if (viewState is RecordingStartedState) {
binding!!.callRecordingIndicator.setImageResource(R.drawable.record_stop)
@ -473,20 +459,48 @@ class CallActivity : CallBaseActivity() {
binding!!.callRecordingIndicator.visibility = View.GONE
}
}
initClickListeners(isModerator, isOneToOneConversation)
binding!!.microphoneButton.setOnTouchListener(MicrophoneButtonTouchListener())
pulseAnimation = PulseAnimation.create().with(binding!!.microphoneButton)
.setDuration(PULSE_ANIMATION_DURATION)
.setRepeatCount(PulseAnimation.INFINITE)
.setRepeatMode(PulseAnimation.REVERSE)
basicInitialization()
callParticipants = HashMap()
participantDisplayItems = HashMap()
initViews()
updateSelfVideoViewPosition()
reactionAnimator = ReactionAnimator(context, binding!!.reactionAnimationWrapper, viewThemeUtils)
}
checkRecordingConsentAndInitiateCall()
private fun initRaiseHandViewModel() {
raiseHandViewModel = ViewModelProvider(this, viewModelFactory).get(RaiseHandViewModel::class.java)
raiseHandViewModel!!.setData(roomToken!!, isBreakoutRoom)
raiseHandViewModel!!.viewState.observe(this) { viewState: RaiseHandViewModel.ViewState? ->
var raised = false
if (viewState is RaisedHandState) {
binding!!.lowerHandButton.visibility = View.VISIBLE
raised = true
} else if (viewState is LoweredHandState) {
binding!!.lowerHandButton.visibility = View.GONE
raised = false
}
if (isConnectionEstablished) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
peerConnectionWrapper.raiseHand(raised)
}
}
}
}
private fun processExtras(extras: Bundle) {
roomId = extras.getString(KEY_ROOM_ID, "")
roomToken = extras.getString(KEY_ROOM_TOKEN, "")
conversationPassword = extras.getString(KEY_CONVERSATION_PASSWORD, "")
conversationName = extras.getString(KEY_CONVERSATION_NAME, "")
isVoiceOnlyCall = extras.getBoolean(KEY_CALL_VOICE_ONLY, false)
isCallWithoutNotification = extras.getBoolean(KEY_CALL_WITHOUT_NOTIFICATION, false)
canPublishAudioStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO)
canPublishVideoStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO)
isModerator = extras.getBoolean(KEY_IS_MODERATOR, false)
isOneToOneConversation = extras.getBoolean(KEY_ROOM_ONE_TO_ONE, false)
if (extras.containsKey(KEY_FROM_NOTIFICATION_START_CALL)) {
isIncomingCallFromNotification = extras.getBoolean(KEY_FROM_NOTIFICATION_START_CALL)
}
if (extras.containsKey(KEY_IS_BREAKOUT_ROOM)) {
isBreakoutRoom = extras.getBoolean(KEY_IS_BREAKOUT_ROOM)
}
baseUrl = extras.getString(KEY_MODIFIED_BASE_URL, "")
}
private fun checkRecordingConsentAndInitiateCall() {
@ -618,17 +632,7 @@ class CallActivity : CallBaseActivity() {
@SuppressLint("ClickableViewAccessibility")
private fun initClickListeners(isModerator: Boolean, isOneToOneConversation: Boolean) {
binding!!.pictureInPictureButton.setOnClickListener { enterPipMode() }
binding!!.audioOutputButton.setOnClickListener {
audioOutputDialog = AudioOutputDialog(this)
audioOutputDialog!!.show()
}
binding!!.moreCallActions.setOnClickListener {
moreCallActionsDialog = MoreCallActionsDialog(this)
moreCallActionsDialog!!.show()
}
initCallActionClickListeners(isModerator, isOneToOneConversation)
if (canPublishAudioStream) {
binding!!.microphoneButton.setOnClickListener { onMicrophoneClick() }
@ -648,11 +652,7 @@ class CallActivity : CallBaseActivity() {
}
} else {
binding!!.microphoneButton.setOnClickListener {
Snackbar.make(
binding!!.root,
R.string.nc_not_allowed_to_activate_audio,
Snackbar.LENGTH_SHORT
).show()
Snackbar.make(binding!!.root, R.string.nc_not_allowed_to_activate_audio, Snackbar.LENGTH_SHORT).show()
}
}
@ -660,58 +660,14 @@ class CallActivity : CallBaseActivity() {
binding!!.cameraButton.setOnClickListener { onCameraClick() }
} else {
binding!!.cameraButton.setOnClickListener {
Snackbar.make(
binding!!.root,
R.string.nc_not_allowed_to_activate_video,
Snackbar.LENGTH_SHORT
).show()
Snackbar.make(binding!!.root, R.string.nc_not_allowed_to_activate_video, Snackbar.LENGTH_SHORT).show()
}
}
if (isOneToOneConversation) {
binding!!.hangupButton.setOnLongClickListener {
showLeaveCallPopupMenu()
true
}
binding!!.hangupButton.setOnClickListener {
hangup(true, true)
}
} else {
if (isModerator) {
binding!!.hangupButton.setOnLongClickListener {
showEndCallForAllPopupMenu()
true
}
}
binding!!.hangupButton.setOnClickListener {
hangup(true, false)
}
}
if (!isOneToOneConversation) {
binding!!.endCallPopupMenu.setOnClickListener {
hangup(true, true)
binding!!.endCallPopupMenu.visibility = View.GONE
}
} else {
binding!!.endCallPopupMenu.setOnClickListener {
hangup(true, false)
binding!!.endCallPopupMenu.visibility = View.GONE
}
}
binding!!.switchSelfVideoButton.setOnClickListener { switchCamera() }
binding!!.gridview.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, _: Int, _: Long ->
animateCallControls(
true,
0
)
}
binding!!.callStates.callStateRelativeLayout.setOnClickListener {
if (currentCallStatus === CallStatus.CALLING_TIMEOUT) {
setCallState(CallStatus.RECONNECTING)
hangupNetworkCalls(false, false)
hangupNetworkCalls(shutDownView = false, endCallForAll = false)
}
}
binding!!.callRecordingIndicator.setOnClickListener {
@ -732,7 +688,54 @@ class CallActivity : CallBaseActivity() {
).show()
}
}
}
private fun initCallActionClickListeners(isModerator: Boolean, isOneToOneConversation: Boolean) {
binding!!.audioOutputButton.setOnClickListener {
audioOutputDialog = AudioOutputDialog(this)
audioOutputDialog!!.show()
}
binding!!.moreCallActions.setOnClickListener {
moreCallActionsDialog = MoreCallActionsDialog(this)
moreCallActionsDialog!!.show()
}
if (isOneToOneConversation) {
binding!!.hangupButton.setOnLongClickListener {
showLeaveCallPopupMenu()
true
}
binding!!.hangupButton.setOnClickListener {
hangup(shutDownView = true, endCallForAll = true)
}
binding!!.endCallPopupMenu.setOnClickListener {
hangup(shutDownView = true, endCallForAll = true)
binding!!.endCallPopupMenu.visibility = View.GONE
}
} else {
if (isModerator) {
binding!!.hangupButton.setOnLongClickListener {
showEndCallForAllPopupMenu()
true
}
}
binding!!.hangupButton.setOnClickListener {
hangup(shutDownView = true, endCallForAll = false)
}
binding!!.endCallPopupMenu.setOnClickListener {
hangup(shutDownView = true, endCallForAll = false)
binding!!.endCallPopupMenu.visibility = View.GONE
}
}
binding!!.switchSelfVideoButton.setOnClickListener { switchCamera() }
binding!!.gridview.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, _: Int, _: Long ->
animateCallControls(true, 0)
}
binding!!.lowerHandButton.setOnClickListener { l: View? -> raiseHandViewModel!!.lowerHand() }
binding!!.pictureInPictureButton.setOnClickListener { enterPipMode() }
}
private fun showEndCallForAllPopupMenu() {
@ -2013,6 +2016,30 @@ class CallActivity : CallBaseActivity() {
dispose(null)
if (shutDownView) {
terminateAudioVideo()
}
val peerConnectionIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (wrapper in peerConnectionWrapperList) {
peerConnectionIdsToEnd.add(wrapper.sessionId)
}
for (sessionId in peerConnectionIdsToEnd) {
endPeerConnection(sessionId, "video")
endPeerConnection(sessionId, "screen")
}
val callParticipantIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (callParticipant in callParticipants.values) {
callParticipantIdsToEnd.add(callParticipant!!.callParticipantModel.sessionId)
}
for (sessionId in callParticipantIdsToEnd) {
removeCallParticipant(sessionId)
}
ApplicationWideCurrentRoomHolder.getInstance().isInCall = false
ApplicationWideCurrentRoomHolder.getInstance().isDialing = false
hangupNetworkCalls(shutDownView, endCallForAll)
}
private fun terminateAudioVideo() {
if (videoCapturer != null) {
try {
videoCapturer!!.stopCapture()
@ -2046,31 +2073,6 @@ class CallActivity : CallBaseActivity() {
}
}
val peerConnectionIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (wrapper in peerConnectionWrapperList) {
peerConnectionIdsToEnd.add(wrapper.sessionId)
}
for (sessionId in peerConnectionIdsToEnd) {
endPeerConnection(sessionId, "video")
endPeerConnection(sessionId, "screen")
}
val callParticipantIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (callParticipant in callParticipants.values) {
callParticipantIdsToEnd.add(callParticipant!!.callParticipantModel.sessionId)
}
for (sessionId in callParticipantIdsToEnd) {
removeCallParticipant(sessionId)
}
ApplicationWideCurrentRoomHolder.getInstance().isInCall = false
ApplicationWideCurrentRoomHolder.getInstance().isDialing = false
hangupNetworkCalls(shutDownView, endCallForAll)
}
private fun hangupNetworkCalls(shutDownView: Boolean, endCallForAll: Boolean) {
Log.d(TAG, "hangupNetworkCalls. shutDownView=$shutDownView")
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
@ -2170,22 +2172,16 @@ class CallActivity : CallBaseActivity() {
}
if (!isSelfInCall &&
currentCallStatus !== CallStatus.LEAVING &&
ApplicationWideCurrentRoomHolder.getInstance().isInCall
currentCallStatus !== CallStatus.LEAVING && ApplicationWideCurrentRoomHolder.getInstance().isInCall
) {
Log.d(TAG, "Most probably a moderator ended the call for all.")
hangup(true, false)
hangup(shutDownView = true, endCallForAll = false)
return
}
if (!isSelfInCall) {
Log.d(TAG, "Self not in call, disconnecting from all other sessions")
for ((_, _, _, _, _, _, _, _, _, _, sessionId) in participantsInCall) {
Log.d(TAG, " session that will be removed is: $sessionId")
endPeerConnection(sessionId, "video")
endPeerConnection(sessionId, "screen")
removeCallParticipant(sessionId)
}
removeSessions(participantsInCall)
return
}
if (currentCallStatus === CallStatus.LEAVING) {
@ -2199,6 +2195,28 @@ class CallActivity : CallBaseActivity() {
true
)
}
handleJoinedCallParticipantsChanged(selfParticipant, joined, currentSessionId)
if (othersInCall && currentCallStatus !== CallStatus.IN_CONVERSATION) {
setCallState(CallStatus.IN_CONVERSATION)
}
removeSessions(left)
}
private fun removeSessions(sessions: Collection<Participant>) {
for ((_, _, _, _, _, _, _, _, _, _, session) in sessions) {
Log.d(TAG, " session that will be removed is: $session")
endPeerConnection(session, "video")
endPeerConnection(session, "screen")
removeCallParticipant(session)
}
}
private fun handleJoinedCallParticipantsChanged(
selfParticipant: Participant?,
joined: Collection<Participant>,
currentSessionId: String?
) {
var selfJoined = false
val selfParticipantHasAudioOrVideo = participantInCallFlagsHaveAudioOrVideo(selfParticipant)
for (participant in joined) {
@ -2240,11 +2258,13 @@ class CallActivity : CallBaseActivity() {
// remote session ID. However, if the other participant does not have audio nor video that participant
// will not send an offer, so no connection is actually established when the remote participant has a
// higher session ID but is not publishing media.
if (hasMCU &&
participantHasAudioOrVideo ||
!hasMCU &&
selfParticipantHasAudioOrVideo &&
(!participantHasAudioOrVideo || sessionId < currentSessionId!!)
if (hasMCUAndAudioVideo(participantHasAudioOrVideo) ||
hasNoMCUAndAudioVideo(
participantHasAudioOrVideo,
selfParticipantHasAudioOrVideo,
sessionId,
currentSessionId!!
)
) {
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false)
}
@ -2254,17 +2274,17 @@ class CallActivity : CallBaseActivity() {
} else {
joined.isNotEmpty()
}
}
if (othersInCall && currentCallStatus !== CallStatus.IN_CONVERSATION) {
setCallState(CallStatus.IN_CONVERSATION)
}
for ((_, _, _, _, _, _, _, _, _, _, sessionId) in left) {
Log.d(TAG, " oldSession that will be removed is: $sessionId")
endPeerConnection(sessionId, "video")
endPeerConnection(sessionId, "screen")
removeCallParticipant(sessionId)
}
}
private fun hasMCUAndAudioVideo(participantHasAudioOrVideo: Boolean): Boolean = hasMCU && participantHasAudioOrVideo
private fun hasNoMCUAndAudioVideo(
participantHasAudioOrVideo: Boolean,
selfParticipantHasAudioOrVideo: Boolean,
sessionId: String,
currentSessionId: String
): Boolean =
!hasMCU && selfParticipantHasAudioOrVideo && (!participantHasAudioOrVideo || sessionId < currentSessionId)
private fun participantInCallFlagsHaveAudioOrVideo(participant: Participant?): Boolean =
if (participant == null) {
@ -2289,8 +2309,7 @@ class CallActivity : CallBaseActivity() {
type: String,
publisher: Boolean
): PeerConnectionWrapper? {
var peerConnectionWrapper: PeerConnectionWrapper?
peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(sessionId, type)
var peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(sessionId, type)
return if (peerConnectionWrapper != null) {
peerConnectionWrapper
@ -2302,68 +2321,10 @@ class CallActivity : CallBaseActivity() {
context.resources.getString(R.string.nc_common_error_sorry),
Snackbar.LENGTH_LONG
).show()
hangup(true, false)
hangup(shutDownView = true, endCallForAll = false)
return null
}
peerConnectionWrapper = if (hasMCU && publisher) {
PeerConnectionWrapper(
peerConnectionFactory,
iceServers,
sdpConstraintsForMCU,
sessionId,
callSession,
localStream,
true,
true,
type,
signalingMessageReceiver,
signalingMessageSender
)
} else if (hasMCU) {
PeerConnectionWrapper(
peerConnectionFactory,
iceServers,
sdpConstraints,
sessionId,
callSession,
null,
false,
true,
type,
signalingMessageReceiver,
signalingMessageSender
)
} else {
if ("screen" != type) {
PeerConnectionWrapper(
peerConnectionFactory,
iceServers,
sdpConstraints,
sessionId,
callSession,
localStream,
false,
false,
type,
signalingMessageReceiver,
signalingMessageSender
)
} else {
PeerConnectionWrapper(
peerConnectionFactory,
iceServers,
sdpConstraints,
sessionId,
callSession,
null,
false,
false,
type,
signalingMessageReceiver,
signalingMessageSender
)
}
}
peerConnectionWrapper = createPeerConnectionWrapperForSessionIdAndType(publisher, sessionId, type)
peerConnectionWrapperList.add(peerConnectionWrapper)
if (!publisher) {
var callParticipant = callParticipants[sessionId]
@ -2384,6 +2345,47 @@ class CallActivity : CallBaseActivity() {
}
}
private fun createPeerConnectionWrapperForSessionIdAndType(
publisher: Boolean,
sessionId: String?,
type: String
): PeerConnectionWrapper {
val tempIsMCUPublisher: Boolean
val tempHasMCU: Boolean
val tempLocalStream: MediaStream?
if (hasMCU && publisher) {
tempIsMCUPublisher = true
tempHasMCU = true
tempLocalStream = localStream
} else if (hasMCU) {
tempIsMCUPublisher = false
tempHasMCU = true
tempLocalStream = null
} else {
tempIsMCUPublisher = false
tempHasMCU = false
tempLocalStream = if ("screen" != type) {
localStream
} else {
null
}
}
return PeerConnectionWrapper(
peerConnectionFactory,
iceServers,
sdpConstraintsForMCU,
sessionId,
callSession,
tempLocalStream,
tempIsMCUPublisher,
tempHasMCU,
type,
signalingMessageReceiver,
signalingMessageSender
)
}
private fun addCallParticipant(sessionId: String?): CallParticipant {
val callParticipant = CallParticipant(sessionId, signalingMessageReceiver)
callParticipants[sessionId] = callParticipant
@ -2530,7 +2532,7 @@ class CallActivity : CallBaseActivity() {
ProximitySensorEvent.ProximitySensorEventType.SENSOR_FAR &&
videoOn
if (permissionUtil!!.isCameraPermissionGranted() &&
(currentCallStatus === CallStatus.CONNECTING || isConnectionEstablished) &&
isConnectingOrEstablished() &&
videoOn &&
enableVideo != localVideoTrack!!.enabled()
) {
@ -2539,6 +2541,9 @@ class CallActivity : CallBaseActivity() {
}
}
private fun isConnectingOrEstablished(): Boolean =
currentCallStatus === CallStatus.CONNECTING || isConnectionEstablished
private fun startSendingNick() {
val dataChannelMessage = DataChannelMessage()
dataChannelMessage.type = "nickChanged"
@ -2602,109 +2607,52 @@ class CallActivity : CallBaseActivity() {
handler!!.removeCallbacksAndMessages(null)
}
when (callState) {
CallStatus.CONNECTING -> handler!!.post {
playCallingSound()
if (isIncomingCallFromNotification) {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_incoming)
} else {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_ringing)
CallStatus.CONNECTING -> handler!!.post { handleCallStateConnected() }
CallStatus.CALLING_TIMEOUT -> handler!!.post { handleCallStateCallingTimeout() }
CallStatus.PUBLISHER_FAILED -> handler!!.post { handleCallStatePublisherFailed() }
CallStatus.RECONNECTING -> handler!!.post { handleCallStateReconnecting() }
CallStatus.JOINED -> {
handler!!.postDelayed({ setCallState(CallStatus.CALLING_TIMEOUT) }, CALLING_TIMEOUT)
handler!!.post { handleCallStateJoined() }
}
binding!!.callConversationNameTextView.text = conversationName
CallStatus.IN_CONVERSATION -> handler!!.post { handleCallStateInConversation() }
CallStatus.OFFLINE -> handler!!.post { handleCallStateOffline() }
CallStatus.LEAVING -> handler!!.post { handleCallStateLeaving() }
}
}
}
private fun handleCallStateLeaving() {
if (!isDestroyed) {
stopCallingSound()
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateTextView.setText(R.string.nc_leaving_call)
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
CallStatus.CALLING_TIMEOUT -> handler!!.post {
hangup(false, false)
binding!!.callStates.callStateTextView.setText(R.string.nc_call_timeout)
binding!!.callModeTextView.text = descriptionForCallType
private fun handleCallStateOffline() {
stopCallingSound()
binding!!.callStates.callStateTextView.setText(R.string.nc_offline)
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.GONE) {
binding!!.callStates.callStateProgressBar.visibility = View.GONE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
binding!!.callStates.errorImageView.setImageResource(R.drawable.ic_av_timer_timer_24dp)
if (binding!!.callStates.callStateProgressBar.visibility != View.GONE) {
binding!!.callStates.callStateProgressBar.visibility = View.GONE
}
binding!!.callStates.errorImageView.setImageResource(R.drawable.ic_signal_wifi_off_white_24dp)
if (binding!!.callStates.errorImageView.visibility != View.VISIBLE) {
binding!!.callStates.errorImageView.visibility = View.VISIBLE
}
}
CallStatus.PUBLISHER_FAILED -> handler!!.post {
// No calling sound when the publisher failed
binding!!.callStates.callStateTextView.setText(R.string.nc_call_reconnecting)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
CallStatus.RECONNECTING -> handler!!.post {
playCallingSound()
binding!!.callStates.callStateTextView.setText(R.string.nc_call_reconnecting)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
CallStatus.JOINED -> {
handler!!.postDelayed({ setCallState(CallStatus.CALLING_TIMEOUT) }, CALLING_TIMEOUT)
handler!!.post {
binding!!.callModeTextView.text = descriptionForCallType
if (isIncomingCallFromNotification) {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_incoming)
} else {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_ringing)
}
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
}
CallStatus.IN_CONVERSATION -> handler!!.post {
private fun handleCallStateInConversation() {
stopCallingSound()
binding!!.callModeTextView.text = descriptionForCallType
if (!isVoiceOnlyCall) {
@ -2727,38 +2675,104 @@ class CallActivity : CallBaseActivity() {
}
}
CallStatus.OFFLINE -> handler!!.post {
stopCallingSound()
binding!!.callStates.callStateTextView.setText(R.string.nc_offline)
private fun handleCallStateJoined() {
binding!!.callModeTextView.text = descriptionForCallType
if (isIncomingCallFromNotification) {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_incoming)
} else {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_ringing)
}
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
private fun handleCallStateReconnecting() {
playCallingSound()
binding!!.callStates.callStateTextView.setText(R.string.nc_call_reconnecting)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
private fun handleCallStatePublisherFailed() {
// No calling sound when the publisher failed
binding!!.callStates.callStateTextView.setText(R.string.nc_call_reconnecting)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
private fun handleCallStateCallingTimeout() {
hangup(shutDownView = false, endCallForAll = false)
binding!!.callStates.callStateTextView.setText(R.string.nc_call_timeout)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.GONE) {
binding!!.callStates.callStateProgressBar.visibility = View.GONE
}
binding!!.callStates.errorImageView.setImageResource(R.drawable.ic_signal_wifi_off_white_24dp)
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
binding!!.callStates.errorImageView.setImageResource(R.drawable.ic_av_timer_timer_24dp)
if (binding!!.callStates.errorImageView.visibility != View.VISIBLE) {
binding!!.callStates.errorImageView.visibility = View.VISIBLE
}
}
CallStatus.LEAVING -> handler!!.post {
if (!isDestroyed) {
stopCallingSound()
private fun handleCallStateConnected() {
playCallingSound()
if (isIncomingCallFromNotification) {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_incoming)
} else {
binding!!.callStates.callStateTextView.setText(R.string.nc_call_ringing)
}
binding!!.callConversationNameTextView.text = conversationName
binding!!.callModeTextView.text = descriptionForCallType
binding!!.callStates.callStateTextView.setText(R.string.nc_leaving_call)
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
binding!!.callStates.callStateRelativeLayout.visibility = View.VISIBLE
}
if (binding!!.gridview.visibility != View.INVISIBLE) {
binding!!.gridview.visibility = View.INVISIBLE
}
if (binding!!.callStates.callStateProgressBar.visibility != View.VISIBLE) {
binding!!.callStates.callStateProgressBar.visibility = View.VISIBLE
}
if (binding!!.callStates.errorImageView.visibility != View.GONE) {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
}
}
}
private val descriptionForCallType: String
get() {

View file

@ -132,6 +132,10 @@ class ContactItem(
holder?.binding?.nameText?.text = sharedApplication!!.getString(R.string.nc_guest)
}
setAvatar(holder)
}
private fun setAvatar(holder: ContactItemViewHolder?) {
if (model.calculatedActorType == Participant.ActorType.GROUPS ||
model.calculatedActorType == Participant.ActorType.CIRCLES
) {

View file

@ -120,7 +120,11 @@ class MentionAutocompleteItem(
} else {
holder.binding.nameText.text = displayName
}
var avatarId = objectId
setAvatar(holder, objectId)
drawStatus(holder)
}
private fun setAvatar(holder: ParticipantItemViewHolder, objectId: String?) {
when (source) {
SOURCE_CALLS -> {
run {}
@ -136,10 +140,7 @@ class MentionAutocompleteItem(
SOURCE_GROUPS -> {
holder.binding.avatarView.loadUserAvatar(
viewThemeUtils.talk.themePlaceholderAvatar(
holder.binding.avatarView,
R.drawable.ic_avatar_group
)
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.avatarView, R.drawable.ic_avatar_group)
)
}
@ -149,27 +150,30 @@ class MentionAutocompleteItem(
currentUser,
currentUser.baseUrl!!,
roomToken,
avatarId!!,
objectId!!,
darkTheme,
true,
false
requestBigSize = true,
ignoreCache = false
)
}
SOURCE_GUESTS, SOURCE_EMAILS -> {
avatarId = displayName
if (displayName.equals(context.resources.getString(R.string.nc_guest))) {
holder.binding.avatarView.loadDefaultAvatar(viewThemeUtils)
} else {
holder.binding.avatarView.loadGuestAvatar(currentUser, avatarId!!, false)
holder.binding.avatarView.loadGuestAvatar(currentUser, displayName!!, false)
}
}
else -> {
holder.binding.avatarView.loadUserAvatar(currentUser, avatarId!!, true, false)
holder.binding.avatarView.loadUserAvatar(
currentUser,
objectId!!,
requestBigSize = true,
ignoreCache = false
)
}
}
drawStatus(holder)
}
private fun drawStatus(holder: ParticipantItemViewHolder) {

View file

@ -224,14 +224,11 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {

View file

@ -14,7 +14,6 @@ import android.view.View
import androidx.core.content.ContextCompat
import autodagger.AutoInjector
import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
@ -202,14 +201,11 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) :
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {

View file

@ -22,7 +22,6 @@ import android.webkit.WebViewClient
import autodagger.AutoInjector
import coil.load
import com.google.android.material.snackbar.Snackbar
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
@ -187,14 +186,11 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
binding.messageQuote.quotedMessageAuthor
.setTextColor(context.resources.getColor(R.color.textColorMaxContrast, null))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {

View file

@ -13,7 +13,6 @@ import android.view.View
import androidx.core.content.ContextCompat
import autodagger.AutoInjector
import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
@ -209,14 +208,11 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) :
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {
Log.d(TAG, "Error when processing parent message in view holder", e)

View file

@ -13,10 +13,8 @@ import android.content.Context
import android.util.Log
import android.util.TypedValue
import android.view.View
import androidx.core.content.ContextCompat
import autodagger.AutoInjector
import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
@ -212,19 +210,12 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
viewThemeUtils
)
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundColor(
ContextCompat.getColor(
binding.messageQuote.quoteColoredView.context,
R.color.high_emphasis_text
)
)
}
binding.messageQuote.quotedChatMessageView.setOnClickListener {
val chatActivity = commonMessageInterface as ChatActivity

View file

@ -119,15 +119,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
}
if (message.resetVoiceMessage) {
binding.playPauseBtn.visibility = View.VISIBLE
binding.playPauseBtn.icon = ContextCompat.getDrawable(
context!!,
R.drawable.ic_baseline_play_arrow_voice_message_24
)
binding.seekbar.progress = SEEKBAR_START
message.resetVoiceMessage = false
message.voiceMessagePlayedSeconds = 0
binding.voiceMessageDuration.visibility = View.INVISIBLE
resetVoiceMessage(message)
}
binding.seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
@ -163,6 +155,18 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
isBound = true
}
private fun resetVoiceMessage(chatMessage: ChatMessage) {
binding.playPauseBtn.visibility = View.VISIBLE
binding.playPauseBtn.icon = ContextCompat.getDrawable(
context!!,
R.drawable.ic_baseline_play_arrow_voice_message_24
)
binding.seekbar.progress = SEEKBAR_START
chatMessage.resetVoiceMessage = false
chatMessage.voiceMessagePlayedSeconds = 0
binding.voiceMessageDuration.visibility = View.INVISIBLE
}
private fun longClickOnReaction(chatMessage: ChatMessage) {
commonMessageInterface.onLongClickReactions(chatMessage)
}
@ -322,14 +326,11 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context!!, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {

View file

@ -215,14 +215,11 @@ class OutcomingDeckCardViewHolder(
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
viewThemeUtils.talk.themeParentMessage(
parentChatMessage,
message,
binding.messageQuote.quoteColoredView
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {

View file

@ -127,6 +127,7 @@ object Migrations {
db.execSQL("ALTER TABLE ArbitraryStorage_dualPK RENAME TO ArbitraryStorage")
}
@Suppress("Detekt.LongMethod")
fun migrateToOfflineSupport(db: SupportSQLiteDatabase) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS Conversations (" +

View file

@ -238,6 +238,14 @@ class DiagnoseActivity : BaseActivity() {
addValue(BuildConfig.FLAVOR)
if (isGooglePlayServicesAvailable) {
setupAppValuesForGooglePlayServices()
}
addKey(context.resources.getString(R.string.nc_diagnose_app_users_amount))
addValue(userManager.users.blockingGet().size.toString())
}
private fun setupAppValuesForGooglePlayServices() {
addKey(context.resources.getString(R.string.nc_diagnose_battery_optimization_title))
if (PowerManagerUtils().isIgnoringBatteryOptimizations()) {
@ -297,10 +305,6 @@ class DiagnoseActivity : BaseActivity() {
}
}
addKey(context.resources.getString(R.string.nc_diagnose_app_users_amount))
addValue(userManager.users.blockingGet().size.toString())
}
private fun setupAccountValues() {
addHeadline(context.resources.getString(R.string.nc_diagnose_account_category_title))

View file

@ -39,16 +39,13 @@ class SaveFileToStorageWorker(val context: Context, workerParameters: WorkerPara
@Suppress("Detekt.TooGenericExceptionCaught")
override fun doWork(): Result {
try {
val sourceFilePath = inputData.getString(KEY_SOURCE_FILE_PATH)
val cacheFile = File(sourceFilePath!!)
val cacheFile = File(inputData.getString(KEY_SOURCE_FILE_PATH)!!)
val contentResolver = context.contentResolver
val mimeType = URLConnection.guessContentTypeFromName(cacheFile.name)
val appName = applicationContext.resources!!.getString(R.string.nc_app_product_name)
val values = ContentValues().apply {
if (mimeType.startsWith(IMAGE_PREFIX) || mimeType.startsWith(VIDEO_PREFIX)) {
val appName = applicationContext.resources!!.getString(R.string.nc_app_product_name)
put(FileColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/" + appName)
}
put(FileColumns.DISPLAY_NAME, cacheFile.name)
@ -58,11 +55,7 @@ class SaveFileToStorageWorker(val context: Context, workerParameters: WorkerPara
}
}
val collectionUri = getUriByType(mimeType)
val uri = contentResolver.insert(collectionUri, values)
uri?.let { fileUri ->
contentResolver.insert(getUriByType(mimeType), values)?.let { fileUri ->
try {
val outputStream: OutputStream? = contentResolver.openOutputStream(fileUri)
outputStream.use { output ->

View file

@ -241,7 +241,7 @@ class LocationPickerActivity :
return true
}
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod")
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod", "Detekt.LongMethod")
private fun initMap() {
binding.map.setTileSource(TileSourceFactory.MAPNIK)
binding.map.onResume()

View file

@ -77,6 +77,7 @@ import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.USER_REM
*
*/
class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.SystemMessageType>() {
@Suppress("Detekt.LongMethod")
override fun getFromString(string: String): ChatMessage.SystemMessageType {
return when (string) {
"conversation_created" -> CONVERSATION_CREATED
@ -144,7 +145,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
}
}
@Suppress("Detekt.ComplexMethod")
@Suppress("Detekt.ComplexMethod", "Detekt.LongMethod")
override fun convertToString(`object`: ChatMessage.SystemMessageType?): String {
return when (`object`) {
null -> ""

View file

@ -943,10 +943,6 @@ class SettingsActivity :
binding.settingsShowNotificationWarning.visibility = View.GONE
}
binding.settingsScreenSecuritySwitch.isChecked = appPreferences.isScreenSecured
binding.settingsIncognitoKeyboardSwitch.isChecked = appPreferences.isKeyboardIncognito
if (CapabilitiesUtil.isReadStatusAvailable(currentUser!!.capabilities!!.spreedCapability!!)) {
binding.settingsReadPrivacySwitch.isChecked = !CapabilitiesUtil.isReadStatusPrivate(currentUser!!)
} else {
@ -954,15 +950,7 @@ class SettingsActivity :
}
setupTypingStatusSetting()
binding.settingsPhoneBookIntegrationSwitch.isChecked = appPreferences.isPhoneBookIntegrationEnabled
binding.settingsProxyUseCredentialsSwitch.isChecked = appPreferences.proxyCredentials
binding.settingsProxyUseCredentials.setOnClickListener {
val isChecked = binding.settingsProxyUseCredentialsSwitch.isChecked
binding.settingsProxyUseCredentialsSwitch.isChecked = !isChecked
appPreferences.setProxyNeedsCredentials(!isChecked)
}
setupProxyUseSetting()
binding.settingsScreenLockSwitch.isChecked = appPreferences.isScreenLocked
binding.settingsScreenLock.setOnClickListener {
@ -977,12 +965,31 @@ class SettingsActivity :
appPreferences.setReadPrivacy(!isChecked)
}
binding.settingsIncognitoKeyboardSwitch.isChecked = appPreferences.isKeyboardIncognito
binding.settingsIncognitoKeyboard.setOnClickListener {
val isChecked = binding.settingsIncognitoKeyboardSwitch.isChecked
binding.settingsIncognitoKeyboardSwitch.isChecked = !isChecked
appPreferences.setIncognitoKeyboard(!isChecked)
}
setupPhoneBookIntegrationSetting()
binding.settingsScreenSecuritySwitch.isChecked = appPreferences.isScreenSecured
binding.settingsScreenSecurity.setOnClickListener {
val isChecked = binding.settingsScreenSecuritySwitch.isChecked
binding.settingsScreenSecuritySwitch.isChecked = !isChecked
appPreferences.setScreenSecurity(!isChecked)
}
binding.settingsTypingStatus.setOnClickListener {
val isChecked = binding.settingsTypingStatusSwitch.isChecked
binding.settingsTypingStatusSwitch.isChecked = !isChecked
appPreferences.setTypingStatus(!isChecked)
}
}
private fun setupPhoneBookIntegrationSetting() {
binding.settingsPhoneBookIntegrationSwitch.isChecked = appPreferences.isPhoneBookIntegrationEnabled
binding.settingsPhoneBookIntegration.setOnClickListener {
val isChecked = binding.settingsPhoneBookIntegrationSwitch.isChecked
binding.settingsPhoneBookIntegrationSwitch.isChecked = !isChecked
@ -995,17 +1002,14 @@ class SettingsActivity :
deleteAll()
}
}
binding.settingsScreenSecurity.setOnClickListener {
val isChecked = binding.settingsScreenSecuritySwitch.isChecked
binding.settingsScreenSecuritySwitch.isChecked = !isChecked
appPreferences.setScreenSecurity(!isChecked)
}
binding.settingsTypingStatus.setOnClickListener {
val isChecked = binding.settingsTypingStatusSwitch.isChecked
binding.settingsTypingStatusSwitch.isChecked = !isChecked
appPreferences.setTypingStatus(!isChecked)
private fun setupProxyUseSetting() {
binding.settingsProxyUseCredentialsSwitch.isChecked = appPreferences.proxyCredentials
binding.settingsProxyUseCredentials.setOnClickListener {
val isChecked = binding.settingsProxyUseCredentialsSwitch.isChecked
binding.settingsProxyUseCredentialsSwitch.isChecked = !isChecked
appPreferences.setProxyNeedsCredentials(!isChecked)
}
}

View file

@ -147,6 +147,10 @@ class MessageActionsDialog(
}
}
initMenuItems()
}
private fun initMenuItems() {
this.lifecycleScope.launch {
initMenuItemTranslate(
!message.isDeleted &&

View file

@ -24,6 +24,7 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.SearchView
@ -42,6 +43,7 @@ import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase
import com.nextcloud.android.common.ui.theme.utils.AndroidXViewThemeUtils
import com.nextcloud.android.common.ui.util.buildColorStateList
import com.nextcloud.talk.R
import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
import com.nextcloud.talk.ui.MicInputCloud
import com.nextcloud.talk.ui.StatusDrawable
@ -368,6 +370,21 @@ class TalkSpecificViewThemeUtils @Inject constructor(
}
}
fun themeParentMessage(
parentChatMessage: ChatMessage,
message: ChatMessage,
quoteColoredView: View,
@ColorRes quoteColorNonSelf: Int = R.color.textColorMaxContrast
) {
withScheme(quoteColoredView) { scheme ->
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
quoteColoredView.setBackgroundColor(dynamicColor.primary().getArgb(scheme))
} else {
quoteColoredView.setBackgroundResource(quoteColorNonSelf)
}
}
}
fun getTextColor(isOutgoingMessage: Boolean, isSelfReaction: Boolean, binding: ReactionsInsideMessageBinding): Int {
return withScheme(binding.root) { scheme ->
return@withScheme if (!isOutgoingMessage || isSelfReaction) {

View file

@ -102,11 +102,7 @@ class DatabaseStorageModule(conversationUser: User, conversationToken: String) {
withContext(Dispatchers.IO) {
ncApiCoroutines!!.setMessageExpiration(
getCredentials(conversationUser.username, conversationUser.token)!!,
getUrlForMessageExpiration(
apiVersion,
conversationUser.baseUrl,
conversationToken
),
getUrlForMessageExpiration(apiVersion, conversationUser.baseUrl, conversationToken),
valueInt
)
messageExpiration = valueInt
@ -132,10 +128,7 @@ class DatabaseStorageModule(conversationUser: User, conversationToken: String) {
val apiVersion = getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
withContext(Dispatchers.IO) {
ncApiCoroutines!!.setNotificationLevel(
getCredentials(
conversationUser.username,
conversationUser.token
)!!,
getCredentials(conversationUser.username, conversationUser.token)!!,
getUrlForRoomNotificationLevel(
apiVersion,
conversationUser.baseUrl,

View file

@ -69,32 +69,38 @@ class ConversationConversionTest(
// check if default values are set for the fields when API_V1 is used
if (apiVersion == 1) {
// default values for API_V2 fields
assertEquals(false, conversationEntity.canDeleteConversation)
assertEquals(true, conversationEntity.canLeaveConversation)
// default values for API_V3 fields
assertEquals("", conversationEntity.description)
assertEquals("", conversationEntity.actorType)
assertEquals("", conversationEntity.actorId)
assertEquals(0, conversationEntity.callFlag)
assertEquals(0, conversationEntity.lastCommonReadMessage)
// default values for API_V4 fields
assertEquals("", conversationEntity.avatarVersion)
assertEquals(0, conversationEntity.callStartTime)
assertEquals(0, conversationEntity.callRecording)
assertEquals(false, conversationEntity.unreadMentionDirect)
assertEquals("", conversationEntity.status)
assertEquals("", conversationEntity.statusIcon)
assertEquals("", conversationEntity.statusMessage)
assertEquals(null, conversationEntity.statusClearAt)
assertEquals("", conversationEntity.avatarVersion)
assertEquals(0, conversationEntity.callStartTime)
assertEquals(0, conversationEntity.callRecording)
checkConversationEntityV1(conversationEntity)
}
if (apiVersion >= 1) {
checkConversationEntityLargerThanV1(conversationEntity)
}
if (apiVersion >= 2) {
assertEquals(false, conversationEntity.canDeleteConversation)
assertEquals(true, conversationEntity.canLeaveConversation)
}
if (apiVersion >= 3) {
assertEquals("test", conversationEntity.description)
// assertEquals("", conversationEntity.attendeeId) // Not implemented
// assertEquals("", conversationEntity.attendeePin) // Not implemented
assertEquals("users", conversationEntity.actorType)
assertEquals("marcel2", conversationEntity.actorId)
// assertEquals("", conversationEntity.listable) // Not implemented
assertEquals(0, conversationEntity.callFlag)
// assertEquals("", conversationEntity.sipEnabled) // Not implemented
// assertEquals("", conversationEntity.canEnableSIP) // Not implemented
assertEquals(92320, conversationEntity.lastCommonReadMessage)
}
if (apiVersion >= 4) {
checkConversationEntityV4(conversationEntity)
}
}
private fun checkConversationEntityLargerThanV1(conversationEntity: ConversationEntity) {
assertEquals("juwd77g6", conversationEntity.token)
assertEquals(ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL, conversationEntity.type)
assertEquals("marcel", conversationEntity.name)
@ -123,26 +129,7 @@ class ConversationConversionTest(
assertEquals(ConversationEnums.ObjectType.DEFAULT, conversationEntity.objectType)
}
if (apiVersion >= 2) {
assertEquals(false, conversationEntity.canDeleteConversation)
assertEquals(true, conversationEntity.canLeaveConversation)
}
if (apiVersion >= 3) {
assertEquals("test", conversationEntity.description)
// assertEquals("", conversationEntity.attendeeId) // Not implemented
// assertEquals("", conversationEntity.attendeePin) // Not implemented
assertEquals("users", conversationEntity.actorType)
assertEquals("marcel2", conversationEntity.actorId)
// assertEquals("", conversationEntity.listable) // Not implemented
assertEquals(0, conversationEntity.callFlag)
// assertEquals("", conversationEntity.sipEnabled) // Not implemented
// assertEquals("", conversationEntity.canEnableSIP) // Not implemented
assertEquals(92320, conversationEntity.lastCommonReadMessage)
}
if (apiVersion >= 4) {
private fun checkConversationEntityV4(conversationEntity: ConversationEntity) {
assertEquals("143a9df3", conversationEntity.avatarVersion)
assertEquals(0, conversationEntity.callStartTime)
assertEquals(0, conversationEntity.callRecording)
@ -161,5 +148,30 @@ class ConversationConversionTest(
// assertEquals("", conversationEntity.mentionPermissions) // Not implemented
// assertEquals("", conversationEntity.isArchived) // Not implemented
}
private fun checkConversationEntityV1(conversationEntity: ConversationEntity) {
// default values for API_V2 fields
assertEquals(false, conversationEntity.canDeleteConversation)
assertEquals(true, conversationEntity.canLeaveConversation)
// default values for API_V3 fields
assertEquals("", conversationEntity.description)
assertEquals("", conversationEntity.actorType)
assertEquals("", conversationEntity.actorId)
assertEquals(0, conversationEntity.callFlag)
assertEquals(0, conversationEntity.lastCommonReadMessage)
// default values for API_V4 fields
assertEquals("", conversationEntity.avatarVersion)
assertEquals(0, conversationEntity.callStartTime)
assertEquals(0, conversationEntity.callRecording)
assertEquals(false, conversationEntity.unreadMentionDirect)
assertEquals("", conversationEntity.status)
assertEquals("", conversationEntity.statusIcon)
assertEquals("", conversationEntity.statusMessage)
assertEquals(null, conversationEntity.statusClearAt)
assertEquals("", conversationEntity.avatarVersion)
assertEquals(0, conversationEntity.callStartTime)
assertEquals(0, conversationEntity.callRecording)
}
}

View file

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: GPL-3.0-or-later
build:
maxIssues: 122
maxIssues: 99
weights:
# complexity: 2
# LongParameterList: 1
@ -48,7 +48,7 @@ complexity:
active: true
ComplexCondition:
active: true
threshold: 4
threshold: 5
ComplexInterface:
active: false
threshold: 10