mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Reworked presence badge
This commit is contained in:
parent
5e1c681a8d
commit
e5bbe3a553
22 changed files with 220 additions and 51 deletions
|
|
@ -21,6 +21,8 @@ use_cpim=1
|
|||
zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512
|
||||
chat_messages_aggregation_delay=1000
|
||||
chat_messages_aggregation=1
|
||||
update_presence_model_timestamp_before_publish_expires_refresh=1
|
||||
rls_uri=sips:rls@sip.linphone.org
|
||||
|
||||
[sound]
|
||||
#remove this property for any application that is not Linphone public version itself
|
||||
|
|
|
|||
|
|
@ -21,16 +21,45 @@ package org.linphone.contacts
|
|||
|
||||
import androidx.loader.app.LoaderManager
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.CoreListenerStub
|
||||
import org.linphone.core.Friend
|
||||
import org.linphone.core.FriendList
|
||||
import org.linphone.core.FriendListListenerStub
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.MainActivity
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
class ContactsManager {
|
||||
companion object {
|
||||
const val TAG = "[Contacts Manager]"
|
||||
}
|
||||
val localFriends = arrayListOf<Friend>()
|
||||
|
||||
private val listeners = arrayListOf<ContactsListener>()
|
||||
|
||||
private val friendListListener: FriendListListenerStub = object : FriendListListenerStub() {
|
||||
override fun onPresenceReceived(list: FriendList, friends: Array<Friend>) {
|
||||
// Core thread
|
||||
Log.i("$TAG Presence received")
|
||||
for (listener in listeners) {
|
||||
listener.onContactsLoaded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val coreListener: CoreListenerStub = object : CoreListenerStub() {
|
||||
override fun onFriendListCreated(core: Core, friendList: FriendList) {
|
||||
// Core thread
|
||||
friendList.addListener(friendListListener)
|
||||
}
|
||||
|
||||
override fun onFriendListRemoved(core: Core, friendList: FriendList) {
|
||||
// Core thread
|
||||
friendList.removeListener(friendListListener)
|
||||
}
|
||||
}
|
||||
|
||||
fun loadContacts(activity: MainActivity) {
|
||||
// UI thread
|
||||
val manager = LoaderManager.getInstance(activity)
|
||||
|
|
@ -73,7 +102,7 @@ class ContactsManager {
|
|||
|
||||
fun updateLocalContacts() {
|
||||
// Core thread
|
||||
Log.i("[Contacts Manager] Updating local contact(s)")
|
||||
Log.i("$TAG Updating local contact(s)")
|
||||
localFriends.clear()
|
||||
|
||||
for (account in coreContext.core.accountList) {
|
||||
|
|
@ -84,7 +113,7 @@ class ContactsManager {
|
|||
friend.address = address
|
||||
|
||||
Log.i(
|
||||
"[Contacts Manager] Local contact created for account [${address.asString()}] and picture [${friend.photo}]"
|
||||
"$TAG Local contact created for account [${address.asString()}] and picture [${friend.photo}]"
|
||||
)
|
||||
localFriends.add(friend)
|
||||
}
|
||||
|
|
@ -92,11 +121,22 @@ class ContactsManager {
|
|||
|
||||
fun onCoreStarted() {
|
||||
// Core thread
|
||||
val core = coreContext.core
|
||||
core.addListener(coreListener)
|
||||
for (list in core.friendsLists) {
|
||||
list.addListener(friendListListener)
|
||||
}
|
||||
|
||||
updateLocalContacts()
|
||||
}
|
||||
|
||||
fun onCoreStopped() {
|
||||
// Core thread
|
||||
val core = coreContext.core
|
||||
core.removeListener(coreListener)
|
||||
for (list in core.friendsLists) {
|
||||
list.removeListener(friendListListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,12 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
|
|||
import org.linphone.contacts.ContactsManager
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.voip.VoipActivity
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
class CoreContext(val context: Context) : HandlerThread("Core Thread") {
|
||||
lateinit var core: Core
|
||||
|
||||
lateinit var emojiCompat: EmojiCompat
|
||||
val emojiCompat: EmojiCompat
|
||||
|
||||
val contactsManager = ContactsManager()
|
||||
|
||||
|
|
@ -96,6 +97,7 @@ class CoreContext(val context: Context) : HandlerThread("Core Thread") {
|
|||
)
|
||||
|
||||
computeUserAgent()
|
||||
|
||||
core.start()
|
||||
|
||||
contactsManager.onCoreStarted()
|
||||
|
|
@ -213,9 +215,8 @@ class CoreContext(val context: Context) : HandlerThread("Core Thread") {
|
|||
}
|
||||
|
||||
private fun computeUserAgent() {
|
||||
// TODO FIXME
|
||||
val deviceName: String = "Linphone6"
|
||||
val appName: String = "Linphone Android"
|
||||
val deviceName = LinphoneUtils.getDeviceName(context)
|
||||
val appName = context.getString(org.linphone.R.string.app_name)
|
||||
val androidVersion = BuildConfig.VERSION_NAME
|
||||
val userAgent = "$appName/$androidVersion ($deviceName) LinphoneSDK"
|
||||
val sdkVersion = context.getString(org.linphone.core.R.string.linphone_sdk_version)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ private class ContactDiffCallback : DiffUtil.ItemCallback<ContactAvatarModel>()
|
|||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: ContactAvatarModel, newItem: ContactAvatarModel): Boolean {
|
||||
return oldItem.showFirstLetter.value == newItem.showFirstLetter.value
|
||||
return oldItem.showFirstLetter.value == newItem.showFirstLetter.value &&
|
||||
oldItem.presenceStatus.value == newItem.presenceStatus.value
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,14 @@ import androidx.lifecycle.MutableLiveData
|
|||
import org.linphone.core.ConsolidatedPresence
|
||||
import org.linphone.core.Friend
|
||||
import org.linphone.core.FriendListenerStub
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
|
||||
class ContactAvatarModel(val friend: Friend) {
|
||||
companion object {
|
||||
const val TAG = "[Contact Avatar Model]"
|
||||
}
|
||||
|
||||
val id = friend.refKey
|
||||
|
||||
val avatar = MutableLiveData<Uri>()
|
||||
|
|
@ -47,19 +52,21 @@ class ContactAvatarModel(val friend: Friend) {
|
|||
|
||||
private val friendListener = object : FriendListenerStub() {
|
||||
override fun onPresenceReceived(fr: Friend) {
|
||||
Log.d(
|
||||
"$TAG Presence received for friend [${fr.name}]: [${friend.consolidatedPresence}]"
|
||||
)
|
||||
presenceStatus.postValue(fr.consolidatedPresence)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
// Core thread
|
||||
name.postValue(friend.name)
|
||||
presenceStatus.postValue(friend.consolidatedPresence)
|
||||
avatar.postValue(getAvatarUri())
|
||||
|
||||
friend.addListener(friendListener)
|
||||
|
||||
presenceStatus.postValue(ConsolidatedPresence.Offline)
|
||||
name.postValue(friend.name)
|
||||
presenceStatus.postValue(friend.consolidatedPresence)
|
||||
Log.d("$TAG Friend [${friend.name}] presence status is [${friend.consolidatedPresence}]")
|
||||
avatar.postValue(getAvatarUri())
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ import org.linphone.core.tools.Log
|
|||
import org.linphone.ui.main.contacts.model.ContactAvatarModel
|
||||
|
||||
class ContactsListViewModel : ViewModel() {
|
||||
companion object {
|
||||
const val TAG = "[Contacts List ViewModel]"
|
||||
}
|
||||
|
||||
val contactsList = MutableLiveData<ArrayList<ContactAvatarModel>>()
|
||||
|
||||
val favourites = MutableLiveData<ArrayList<ContactAvatarModel>>()
|
||||
|
|
@ -48,7 +52,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
private val magicSearchListener = object : MagicSearchListenerStub() {
|
||||
override fun onSearchResultsReceived(magicSearch: MagicSearch) {
|
||||
// Core thread
|
||||
Log.i("[Contacts] Magic search contacts available")
|
||||
Log.i("$TAG Magic search contacts available")
|
||||
processMagicSearchResults(magicSearch.lastSearch)
|
||||
}
|
||||
}
|
||||
|
|
@ -56,6 +60,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
private val contactsListener = object : ContactsListener {
|
||||
override fun onContactsLoaded() {
|
||||
// Core thread
|
||||
Log.i("$TAG Contacts have been (re)loaded, updating list")
|
||||
applyFilter(
|
||||
currentFilter,
|
||||
"",
|
||||
|
|
@ -92,7 +97,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
|
||||
fun processMagicSearchResults(results: Array<SearchResult>) {
|
||||
// Core thread
|
||||
Log.i("[Contacts List] Processing ${results.size} results")
|
||||
Log.i("$TAG Processing ${results.size} results")
|
||||
contactsList.value.orEmpty().forEach(ContactAvatarModel::destroy)
|
||||
|
||||
val list = arrayListOf<ContactAvatarModel>()
|
||||
|
|
@ -107,7 +112,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
currentLetter = friend.name?.get(0).toString()
|
||||
ContactAvatarModel(friend)
|
||||
} else {
|
||||
Log.w("[Contacts] SearchResult [$result] has no Friend!")
|
||||
Log.w("$TAG SearchResult [$result] has no Friend!")
|
||||
val fakeFriend =
|
||||
createFriendFromSearchResult(result)
|
||||
currentLetter = fakeFriend.name?.get(0).toString()
|
||||
|
|
@ -129,7 +134,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
favourites.postValue(favouritesList)
|
||||
contactsList.postValue(list)
|
||||
|
||||
Log.i("[Contacts] Processed ${results.size} results")
|
||||
Log.i("$TAG Processed ${results.size} results")
|
||||
}
|
||||
|
||||
fun applyFilter(filter: String) {
|
||||
|
|
@ -163,7 +168,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
previousFilter = filter
|
||||
|
||||
Log.i(
|
||||
"[Contacts] Asking Magic search for contacts matching filter [$filter], domain [$domain] and in sources [$sources]"
|
||||
"$TAG Asking Magic search for contacts matching filter [$filter], domain [$domain] and in sources [$sources]"
|
||||
)
|
||||
magicSearch.getContactsListAsync(
|
||||
filter,
|
||||
|
|
|
|||
|
|
@ -81,6 +81,10 @@ class AccountModel(private val account: Account) {
|
|||
}
|
||||
}
|
||||
|
||||
fun openMenu() {
|
||||
// UI thread
|
||||
}
|
||||
|
||||
fun refreshRegister() {
|
||||
// UI thread
|
||||
coreContext.postOnCoreThread { core ->
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ fun AppCompatTextView.setDrawableTint(color: Int) {
|
|||
|
||||
@BindingAdapter("coilContact")
|
||||
fun loadContactPictureWithCoil2(imageView: ImageView, contact: ContactData?) {
|
||||
// UI thread !
|
||||
// UI thread
|
||||
if (contact == null) {
|
||||
imageView.load(R.drawable.contact_avatar)
|
||||
} else {
|
||||
|
|
@ -142,18 +142,24 @@ fun loadContactPictureWithCoil2(imageView: ImageView, contact: ContactData?) {
|
|||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("presenceIcon")
|
||||
fun ImageView.setPresenceIcon(presence: ConsolidatedPresence?) {
|
||||
// UI thread
|
||||
val icon = when (presence) {
|
||||
ConsolidatedPresence.Online -> R.drawable.led_online
|
||||
ConsolidatedPresence.DoNotDisturb -> R.drawable.led_do_not_disturb
|
||||
ConsolidatedPresence.Busy -> R.drawable.led_away
|
||||
else -> R.drawable.led_not_registered
|
||||
}
|
||||
setImageResource(icon)
|
||||
}
|
||||
|
||||
@BindingAdapter("contactAvatar")
|
||||
fun AvatarView.loadContactPicture(contact: ContactAvatarModel?) {
|
||||
// UI thread !
|
||||
// UI thread
|
||||
if (contact == null) {
|
||||
loadImage(R.drawable.contact_avatar)
|
||||
} else {
|
||||
indicatorColor = when (contact.presenceStatus.value) {
|
||||
ConsolidatedPresence.Online -> R.color.green_online
|
||||
else -> R.color.blue_outgoing_message
|
||||
}
|
||||
indicatorEnabled = contact.presenceStatus.value != ConsolidatedPresence.Offline
|
||||
|
||||
val uri = contact.avatar.value
|
||||
loadImage(
|
||||
data = uri,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
*/
|
||||
package org.linphone.utils
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import androidx.annotation.IntegerRes
|
||||
import androidx.emoji2.text.EmojiCompat
|
||||
import java.util.Locale
|
||||
|
|
@ -137,5 +141,26 @@ class LinphoneUtils {
|
|||
fun getChatRoomId(chatRoom: ChatRoom): String {
|
||||
return getChatRoomId(chatRoom.localAddress, chatRoom.peerAddress)
|
||||
}
|
||||
|
||||
fun getDeviceName(context: Context): String {
|
||||
var name = Settings.Global.getString(
|
||||
context.contentResolver,
|
||||
Settings.Global.DEVICE_NAME
|
||||
)
|
||||
if (name == null) {
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter()
|
||||
name = adapter?.name
|
||||
}
|
||||
if (name == null) {
|
||||
name = Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
"bluetooth_name"
|
||||
)
|
||||
}
|
||||
if (name == null) {
|
||||
name = Build.MANUFACTURER + " " + Build.MODEL
|
||||
}
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
app/src/main/res/drawable/led_away.xml
Normal file
5
app/src/main/res/drawable/led_away.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/orange_away"/>
|
||||
<size android:width="15dp" android:height="15dp"/>
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/led_background.xml
Normal file
5
app/src/main/res/drawable/led_background.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/white"/>
|
||||
<size android:width="20dp" android:height="20dp"/>
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/led_do_not_disturb.xml
Normal file
5
app/src/main/res/drawable/led_do_not_disturb.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/red_danger"/>
|
||||
<size android:width="15dp" android:height="15dp"/>
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/led_not_registered.xml
Normal file
5
app/src/main/res/drawable/led_not_registered.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/gray_offline"/>
|
||||
<size android:width="15dp" android:height="15dp"/>
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/led_online.xml
Normal file
5
app/src/main/res/drawable/led_online.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||
<solid android:color="@color/green_online"/>
|
||||
<size android:width="15dp" android:height="15dp"/>
|
||||
</shape>
|
||||
|
|
@ -101,13 +101,16 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{() -> model.openMenu()}"
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/dot_menu"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
app:tint="@color/gray_1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/name"
|
||||
|
|
|
|||
|
|
@ -71,11 +71,6 @@
|
|||
android:adjustViewBounds="true"
|
||||
contactAvatar="@{viewModel.callLogModel.avatarModel}"
|
||||
app:avatarViewBorderWidth="0dp"
|
||||
app:avatarViewIndicatorBorderColor="@color/white"
|
||||
app:avatarViewIndicatorBorderSizeCriteria="8"
|
||||
app:avatarViewIndicatorEnabled="true"
|
||||
app:avatarViewIndicatorPosition="bottomRight"
|
||||
app:avatarViewIndicatorSizeCriteria="7"
|
||||
app:avatarViewInitialsBackgroundColor="@color/blue_outgoing_message"
|
||||
app:avatarViewInitialsTextColor="@color/gray_9"
|
||||
app:avatarViewInitialsTextSize="21sp"
|
||||
|
|
@ -86,6 +81,18 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/presence_badge"
|
||||
android:layout_width="@dimen/avatar_presence_badge_big_size"
|
||||
android:layout_height="@dimen/avatar_presence_badge_big_size"
|
||||
android:layout_marginEnd="@dimen/avatar_presence_badge_big_end_margin"
|
||||
android:background="@drawable/led_background"
|
||||
android:padding="@dimen/avatar_presence_badge_big_padding"
|
||||
app:presenceIcon="@{viewModel.callLogModel.avatarModel.presenceStatus}"
|
||||
android:visibility="@{viewModel.callLogModel.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
|
|
@ -118,7 +125,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{viewModel.callLogModel.avatarModel.presenceStatus == ConsolidatedPresence.Online ? `En ligne` : `Absent`, default=`En ligne`}"
|
||||
android:textColor="@{viewModel.callLogModel.avatarModel.presenceStatus == ConsolidatedPresence.Online ? @color/green_online : @color/green_online, default=@color/green_online}"
|
||||
android:textColor="@{viewModel.callLogModel.avatarModel.presenceStatus == ConsolidatedPresence.Online ? @color/green_online : @color/orange_away, default=@color/green_online}"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.graphics.Typeface" />
|
||||
<import type="org.linphone.core.ConsolidatedPresence" />
|
||||
<variable
|
||||
name="model"
|
||||
type="org.linphone.ui.main.calls.model.CallLogModel" />
|
||||
|
|
@ -48,6 +49,18 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/presence_badge"
|
||||
android:layout_width="@dimen/avatar_presence_badge_size"
|
||||
android:layout_height="@dimen/avatar_presence_badge_size"
|
||||
android:layout_marginEnd="@dimen/avatar_presence_badge_end_margin"
|
||||
android:background="@drawable/led_background"
|
||||
android:padding="@dimen/avatar_presence_badge_padding"
|
||||
app:presenceIcon="@{model.avatarModel.presenceStatus}"
|
||||
android:visibility="@{model.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="org.linphone.core.ConsolidatedPresence" />
|
||||
<variable
|
||||
name="model"
|
||||
type="org.linphone.ui.main.contacts.model.ContactAvatarModel" />
|
||||
|
|
@ -37,16 +38,22 @@
|
|||
app:avatarViewInitialsTextSize="16sp"
|
||||
app:avatarViewInitialsTextStyle="bold"
|
||||
app:avatarViewShape="circle"
|
||||
app:avatarViewBorderWidth="0dp"
|
||||
app:avatarViewIndicatorEnabled="true"
|
||||
app:avatarViewIndicatorBorderColor="@color/white"
|
||||
app:avatarViewIndicatorSizeCriteria="7"
|
||||
app:avatarViewIndicatorBorderSizeCriteria="8"
|
||||
app:avatarViewIndicatorPosition="bottomRight"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/presence_badge"
|
||||
android:layout_width="@dimen/avatar_presence_badge_size"
|
||||
android:layout_height="@dimen/avatar_presence_badge_size"
|
||||
android:layout_marginEnd="@dimen/avatar_presence_badge_end_margin"
|
||||
android:background="@drawable/led_background"
|
||||
android:padding="@dimen/avatar_presence_badge_padding"
|
||||
app:presenceIcon="@{model.presenceStatus}"
|
||||
android:visibility="@{model.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
|
|
|
|||
|
|
@ -89,11 +89,6 @@
|
|||
android:adjustViewBounds="true"
|
||||
contactAvatar="@{viewModel.contact}"
|
||||
app:avatarViewBorderWidth="0dp"
|
||||
app:avatarViewIndicatorBorderColor="@color/white"
|
||||
app:avatarViewIndicatorBorderSizeCriteria="8"
|
||||
app:avatarViewIndicatorEnabled="true"
|
||||
app:avatarViewIndicatorPosition="bottomRight"
|
||||
app:avatarViewIndicatorSizeCriteria="7"
|
||||
app:avatarViewInitialsBackgroundColor="@color/blue_outgoing_message"
|
||||
app:avatarViewInitialsTextColor="@color/gray_9"
|
||||
app:avatarViewInitialsTextSize="21sp"
|
||||
|
|
@ -104,6 +99,18 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/presence_badge"
|
||||
android:layout_width="@dimen/avatar_presence_badge_big_size"
|
||||
android:layout_height="@dimen/avatar_presence_badge_big_size"
|
||||
android:layout_marginEnd="@dimen/avatar_presence_badge_big_end_margin"
|
||||
android:background="@drawable/led_background"
|
||||
android:padding="@dimen/avatar_presence_badge_big_padding"
|
||||
app:presenceIcon="@{viewModel.contact.presenceStatus}"
|
||||
android:visibility="@{viewModel.contact.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
|
|
@ -124,7 +131,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{viewModel.contact.presenceStatus == ConsolidatedPresence.Online ? `En ligne` : `Absent`, default=`En ligne`}"
|
||||
android:textColor="@{viewModel.contact.presenceStatus == ConsolidatedPresence.Online ? @color/green_online : @color/green_online, default=@color/green_online}"
|
||||
android:textColor="@{viewModel.contact.presenceStatus == ConsolidatedPresence.Online ? @color/green_online : @color/orange_away, default=@color/green_online}"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="android.graphics.Typeface" />
|
||||
<import type="org.linphone.core.ConsolidatedPresence" />
|
||||
<variable
|
||||
name="model"
|
||||
type="org.linphone.ui.main.contacts.model.ContactAvatarModel" />
|
||||
|
|
@ -47,22 +48,29 @@
|
|||
android:layout_marginBottom="5dp"
|
||||
android:adjustViewBounds="true"
|
||||
contactAvatar="@{model}"
|
||||
app:avatarViewInitials="SB"
|
||||
app:avatarViewPlaceholder="@drawable/contact_avatar"
|
||||
app:avatarViewInitialsBackgroundColor="@color/blue_outgoing_message"
|
||||
app:avatarViewInitialsTextColor="@color/gray_9"
|
||||
app:avatarViewInitialsTextSize="16sp"
|
||||
app:avatarViewInitialsTextStyle="bold"
|
||||
app:avatarViewShape="circle"
|
||||
app:avatarViewBorderWidth="0dp"
|
||||
app:avatarViewIndicatorEnabled="true"
|
||||
app:avatarViewIndicatorBorderColor="@color/white"
|
||||
app:avatarViewIndicatorSizeCriteria="7"
|
||||
app:avatarViewIndicatorBorderSizeCriteria="8"
|
||||
app:avatarViewIndicatorPosition="bottomRight"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/header"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/presence_badge"
|
||||
android:layout_width="@dimen/avatar_presence_badge_size"
|
||||
android:layout_height="@dimen/avatar_presence_badge_size"
|
||||
android:layout_marginEnd="@dimen/avatar_presence_badge_end_margin"
|
||||
android:background="@drawable/led_background"
|
||||
android:padding="@dimen/avatar_presence_badge_padding"
|
||||
app:presenceIcon="@{model.presenceStatus}"
|
||||
android:visibility="@{model.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintEnd_toEndOf="@id/avatar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/name"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
<color name="blue_outgoing_message">#DFECF2</color>
|
||||
<color name="gray_incoming_message">#F4F4F7</color>
|
||||
<color name="trusted_blue">#4AA8FF</color>
|
||||
<color name="orange_away">#FFA645</color>
|
||||
<color name="gray_offline">#E1E1E1</color>
|
||||
<color name="warning_orange_background">#FFEACB</color>
|
||||
<color name="warning_orange_pressed_background">#FFB266</color>
|
||||
<color name="dialog_background">#22334D</color>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@
|
|||
<dimen name="avatar_favorite_list_cell_size">50dp</dimen>
|
||||
<dimen name="avatar_big_size">100dp</dimen>
|
||||
<dimen name="avatar_in_call_size">120dp</dimen>
|
||||
<dimen name="avatar_presence_badge_size">12dp</dimen>
|
||||
<dimen name="avatar_presence_badge_padding">2dp</dimen>
|
||||
<dimen name="avatar_presence_badge_end_margin">3dp</dimen>
|
||||
<dimen name="avatar_presence_badge_big_size">22dp</dimen>
|
||||
<dimen name="avatar_presence_badge_big_padding">3dp</dimen>
|
||||
<dimen name="avatar_presence_badge_big_end_margin">5dp</dimen>
|
||||
|
||||
<dimen name="top_search_bar_height">55dp</dimen>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue