Cleaned up code, fixed contact avatar blinking when toggling selection in list while creating chat room/conference

This commit is contained in:
Sylvain Berfini 2022-06-01 11:09:03 +02:00
parent 4e0d38ca35
commit 5dfc18a78d
17 changed files with 74 additions and 74 deletions

View file

@ -313,7 +313,7 @@ class ChatMessagesListAdapter(
popupView.addToContactsHidden = true
totalSize -= itemSize
}
if (chatMessage.chatRoom.isReadOnly()) {
if (chatMessage.chatRoom.isReadOnly) {
popupView.replyHidden = true
totalSize -= itemSize
}

View file

@ -402,12 +402,16 @@ class ChatMessageContentData(
var earpieceCard: String? = null
for (device in coreContext.core.audioDevices) {
if (device.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
if (device.type == AudioDevice.Type.Speaker) {
speakerCard = device.id
} else if (device.type == AudioDevice.Type.Earpiece) {
earpieceCard = device.id
} else if (device.type == AudioDevice.Type.Headphones || device.type == AudioDevice.Type.Headset) {
headphonesCard = device.id
when (device.type) {
AudioDevice.Type.Speaker -> {
speakerCard = device.id
}
AudioDevice.Type.Earpiece -> {
earpieceCard = device.id
}
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
}
}
}

View file

@ -27,8 +27,4 @@ class ImdnParticipantData(val imdnState: ParticipantImdnState) : GenericContactD
val sipUri: String = imdnState.participant.address.asStringUriOnly()
val time: String = TimestampUtils.toString(imdnState.stateChangeTime)
override fun destroy() {
super.destroy()
}
}

View file

@ -73,7 +73,7 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
adapter = GroupInfoParticipantsAdapter(
viewLifecycleOwner,
chatRoom?.hasCapability(ChatRoomCapabilities.Encrypted.toInt()) ?: viewModel.isEncrypted.value == true
chatRoom?.hasCapability(ChatRoomCapabilities.Encrypted.toInt()) ?: (viewModel.isEncrypted.value == true)
)
binding.participants.adapter = adapter

View file

@ -114,7 +114,7 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
override fun onStateChanged(chatRoom: ChatRoom, state: ChatRoom.State) {
if (state == ChatRoom.State.Created || state == ChatRoom.State.Terminated) {
isReadOnly.value = chatRoom.isReadOnly()
isReadOnly.value = chatRoom.isReadOnly
}
}
}
@ -457,12 +457,16 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
var earpieceCard: String? = null
for (device in coreContext.core.audioDevices) {
if (device.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
if (device.type == AudioDevice.Type.Speaker) {
speakerCard = device.id
} else if (device.type == AudioDevice.Type.Earpiece) {
earpieceCard = device.id
} else if (device.type == AudioDevice.Type.Headphones || device.type == AudioDevice.Type.Headset) {
headphonesCard = device.id
when (device.type) {
AudioDevice.Type.Speaker -> {
speakerCard = device.id
}
AudioDevice.Type.Earpiece -> {
earpieceCard = device.id
}
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
}
}
}

View file

@ -63,10 +63,6 @@ class ChatRoomCreationViewModel : ContactsSelectionViewModel() {
waitForChatRoomCreation.value = false
}
override fun onCleared() {
super.onCleared()
}
fun updateEncryption(encrypted: Boolean) {
isEncrypted.value = encrypted
}

View file

@ -97,8 +97,8 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : MessageNotifierViewModel() {
init {
subject.value = chatRoom?.subject
isMeAdmin.value = chatRoom == null || (chatRoom.me?.isAdmin == true && !chatRoom.isReadOnly())
canLeaveGroup.value = chatRoom != null && !chatRoom.isReadOnly()
isMeAdmin.value = chatRoom == null || (chatRoom.me?.isAdmin == true && !chatRoom.isReadOnly)
canLeaveGroup.value = chatRoom != null && !chatRoom.isReadOnly
isEncrypted.value = chatRoom?.hasCapability(ChatRoomCapabilities.Encrypted.toInt())
if (chatRoom != null) updateParticipants()

View file

@ -171,12 +171,16 @@ class RecordingData(val path: String, private val recordingListener: RecordingLi
var earpieceCard: String? = null
for (device in coreContext.core.audioDevices) {
if (device.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
if (device.type == AudioDevice.Type.Speaker) {
speakerCard = device.id
} else if (device.type == AudioDevice.Type.Earpiece) {
earpieceCard = device.id
} else if (device.type == AudioDevice.Type.Headphones || device.type == AudioDevice.Type.Headset) {
headphonesCard = device.id
when (device.type) {
AudioDevice.Type.Speaker -> {
speakerCard = device.id
}
AudioDevice.Type.Earpiece -> {
earpieceCard = device.id
}
AudioDevice.Type.Headphones, AudioDevice.Type.Headset -> {
headphonesCard = device.id
}
}
}
}

View file

@ -59,7 +59,7 @@ open class StatusViewModel : ViewModel() {
if (body.type == "application" && body.subtype == "simple-message-summary" && body.size > 0) {
val data = body.utf8Text?.lowercase(Locale.getDefault())
val voiceMail = data?.split("voice-message: ")
if (voiceMail?.size ?: 0 >= 2) {
if ((voiceMail?.size ?: 0) >= 2) {
val toParse = voiceMail!![1].split("/", limit = 0)
try {
val unreadCount: Int = toParse[0].toInt()

View file

@ -26,6 +26,7 @@ import androidx.navigation.navGraphViewModels
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.activities.GenericFragment
import org.linphone.activities.navigateToAddParticipants
import org.linphone.activities.voip.viewmodels.ConferenceViewModel
import org.linphone.core.tools.Log
import org.linphone.databinding.VoipConferenceParticipantsFragmentBinding
@ -76,7 +77,7 @@ class ConferenceParticipantsFragment : GenericFragment<VoipConferenceParticipant
}
binding.setEditClickListener {
// TODO: go to conferences view outside of call activity in edition mode
navigateToAddParticipants()
}
}

View file

@ -40,8 +40,8 @@ class GridBoxLayout : GridLayout {
)
var centerContent: Boolean = false
var previousChildCount = 0
var previousCellSize = 0
private var previousChildCount = 0
private var previousCellSize = 0
@SuppressLint("DrawAllocation")
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

View file

@ -169,7 +169,7 @@ class HorizontalScrollDotsView : View {
setMeasuredDimension(width, height)
}
fun setDotCount(count: Int) {
private fun setDotCount(count: Int) {
this.count = count
requestLayout()
invalidate()

View file

@ -19,7 +19,6 @@
*/
package org.linphone.contact
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
@ -41,25 +40,26 @@ class ContactsSelectionAdapter(
) : ListAdapter<SearchResult, RecyclerView.ViewHolder>(SearchResultDiffCallback()) {
val selectedContact = MutableLiveData<Event<SearchResult>>()
private var selectedAddresses = ArrayList<Address>()
private val selection = MutableLiveData<List<Address>>()
private var requireGroupChatCapability: Boolean = false
private var requireLimeCapability: Boolean = false
private val requireGroupChatCapability = MutableLiveData<Boolean>()
private var requireLimeCapability = MutableLiveData<Boolean>()
@SuppressLint("NotifyDataSetChanged")
fun updateSelectedAddresses(selection: ArrayList<Address>) {
selectedAddresses = selection
notifyDataSetChanged()
init {
requireGroupChatCapability.value = false
requireLimeCapability.value = false
}
fun updateSelectedAddresses(selectedAddresses: List<Address>) {
selection.value = selectedAddresses
}
@SuppressLint("NotifyDataSetChanged")
fun setLimeCapabilityRequired(enabled: Boolean) {
requireLimeCapability = enabled
notifyDataSetChanged()
requireLimeCapability.value = enabled
}
fun setGroupChatCapabilityRequired(enabled: Boolean) {
requireGroupChatCapability = enabled
requireGroupChatCapability.value = enabled
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
@ -84,13 +84,20 @@ class ContactsSelectionAdapter(
lifecycleOwner = viewLifecycleOwner
updateSecurity(searchResult, searchResultViewModel, requireLimeCapability)
val selected = selectedAddresses.find { address ->
val searchAddress = searchResult.address
if (searchAddress != null) address.weakEqual(searchAddress) else false
requireLimeCapability.observe(viewLifecycleOwner) {
updateSecurity(searchResult, searchResultViewModel)
}
requireGroupChatCapability.observe(viewLifecycleOwner) {
updateSecurity(searchResult, searchResultViewModel)
}
selection.observe(viewLifecycleOwner) { selectedAddresses ->
val selected = selectedAddresses.find { address ->
val searchAddress = searchResult.address
if (searchAddress != null) address.weakEqual(searchAddress) else false
}
searchResultViewModel.isSelected.value = selected != null
}
searchResultViewModel.isSelected.value = selected != null
setClickListener {
selectedContact.value = Event(searchResult)
@ -102,13 +109,14 @@ class ContactsSelectionAdapter(
private fun updateSecurity(
searchResult: SearchResult,
viewModel: ContactSelectionData,
securityEnabled: Boolean
viewModel: ContactSelectionData
) {
val securityEnabled = requireLimeCapability.value ?: false
val groupCapabilityRequired = requireGroupChatCapability.value ?: false
val searchAddress = searchResult.address
val isMyself = securityEnabled && searchAddress != null && coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(searchAddress) ?: false
val limeCheck = !securityEnabled || (securityEnabled && searchResult.hasCapability(FriendCapability.LimeX3Dh))
val groupCheck = !requireGroupChatCapability || (requireGroupChatCapability && searchResult.hasCapability(FriendCapability.GroupChat))
val groupCheck = !groupCapabilityRequired || (groupCapabilityRequired && searchResult.hasCapability(FriendCapability.GroupChat))
val disabled = if (searchResult.friend != null) !limeCheck || !groupCheck || isMyself else false // Generated entry from search filter
viewModel.isDisabled.value = disabled

View file

@ -97,7 +97,7 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else ""
searchResultsPending = true
fastFetchJob?.cancel()
coreContext.contactsManager.magicSearch.getContactsAsync(filter.value.orEmpty(), domain, MagicSearchSource.All.toInt())
coreContext.contactsManager.magicSearch.getContactsListAsync(filter.value.orEmpty(), domain, MagicSearchSource.All.toInt(), MagicSearchAggregation.None)
val spinnerDelay = corePreferences.delayBeforeShowingContactsSearchSpinner.toLong()
fastFetchJob = viewModelScope.launch {

View file

@ -22,7 +22,6 @@ package org.linphone.utils
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.text.Editable
import android.text.TextWatcher
import android.util.Patterns
@ -65,11 +64,6 @@ fun ImageView.setSourceImageResource(resource: Int) {
this.setImageResource(resource)
}
@BindingAdapter("android:src")
fun ImageView.setSourceImageBitmap(bitmap: Bitmap?) {
if (bitmap != null) this.setImageBitmap(bitmap)
}
@BindingAdapter("android:contentDescription")
fun ImageView.setContentDescription(resource: Int) {
if (resource == 0) {
@ -116,13 +110,6 @@ fun setRightMargin(view: View, margin: Float) {
view.layoutParams = layoutParams
}
@BindingAdapter("android:layout_weight")
fun setLayoutWeight(view: View, weight: Float) {
val layoutParams = view.layoutParams as LinearLayout.LayoutParams
layoutParams.weight = weight
view.layoutParams = layoutParams
}
@BindingAdapter("android:layout_alignLeft")
fun setLayoutLeftAlign(view: View, oldTargetId: Int, newTargetId: Int) {
val layoutParams = view.layoutParams as RelativeLayout.LayoutParams
@ -494,7 +481,7 @@ fun addUsernameEditTextValidation(editText: EditText, enabled: Boolean) {
s?.matches(Regex(usernameRegexp)) == false ->
editText.error =
editText.context.getString(R.string.assistant_error_username_invalid_characters)
s?.length ?: 0 > usernameMaxLength -> {
(s?.length ?: 0) > usernameMaxLength -> {
editText.error =
editText.context.getString(R.string.assistant_error_username_too_long)
}

View file

@ -27,7 +27,7 @@ import android.widget.TextView
import java.util.regex.Pattern
class PatternClickableSpan {
var patterns: ArrayList<SpannablePatternItem> = ArrayList()
private var patterns: ArrayList<SpannablePatternItem> = ArrayList()
inner class SpannablePatternItem(
var pattern: Pattern,

View file

@ -15,7 +15,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.10'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.1.0"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.0'
}
}