Cleaned up code, fixed contact avatar blinking when toggling selection in list while creating chat room/conference
This commit is contained in:
parent
4e0d38ca35
commit
5dfc18a78d
17 changed files with 74 additions and 74 deletions
|
@ -313,7 +313,7 @@ class ChatMessagesListAdapter(
|
|||
popupView.addToContactsHidden = true
|
||||
totalSize -= itemSize
|
||||
}
|
||||
if (chatMessage.chatRoom.isReadOnly()) {
|
||||
if (chatMessage.chatRoom.isReadOnly) {
|
||||
popupView.replyHidden = true
|
||||
totalSize -= itemSize
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,10 +63,6 @@ class ChatRoomCreationViewModel : ContactsSelectionViewModel() {
|
|||
waitForChatRoomCreation.value = false
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
fun updateEncryption(encrypted: Boolean) {
|
||||
isEncrypted.value = encrypted
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -169,7 +169,7 @@ class HorizontalScrollDotsView : View {
|
|||
setMeasuredDimension(width, height)
|
||||
}
|
||||
|
||||
fun setDotCount(count: Int) {
|
||||
private fun setDotCount(count: Int) {
|
||||
this.count = count
|
||||
requestLayout()
|
||||
invalidate()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue