Added missing local default account avatar

This commit is contained in:
Sylvain Berfini 2020-08-18 13:51:13 +02:00
parent 0cb96fa59e
commit ff13b2fd1f
8 changed files with 132 additions and 67 deletions

View file

@ -311,37 +311,7 @@ class DetailChatRoomFragment : MasterFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
var fileToUploadPath: String? = null val fileToUploadPath = ImageUtils.getImageFilePathFromPickerIntent(data, chatSendingViewModel.temporaryFileUploadPath)
val temporaryFileUploadPath = chatSendingViewModel.temporaryFileUploadPath
if (temporaryFileUploadPath != null) {
if (data != null) {
val dataUri = data.data
if (dataUri != null) {
fileToUploadPath = dataUri.toString()
Log.i("[Chat Room] Using data URI $fileToUploadPath")
} else if (temporaryFileUploadPath.exists()) {
fileToUploadPath = temporaryFileUploadPath.absolutePath
Log.i("[Chat Room] Data URI is null, using $fileToUploadPath")
}
} else if (temporaryFileUploadPath.exists()) {
fileToUploadPath = temporaryFileUploadPath.absolutePath
Log.i("[Chat Room] Data is null, using $fileToUploadPath")
}
}
if (fileToUploadPath != null) {
if (fileToUploadPath.startsWith("content://") ||
fileToUploadPath.startsWith("file://")
) {
val uriToParse = Uri.parse(fileToUploadPath)
fileToUploadPath = FileUtils.getFilePath(requireContext(), uriToParse)
Log.i("[Chat] Path was using a content or file scheme, real path is: $fileToUploadPath")
if (fileToUploadPath == null) {
Log.e("[Chat] Failed to get access to file $uriToParse")
}
}
}
if (fileToUploadPath != null) { if (fileToUploadPath != null) {
chatSendingViewModel.addAttachment(fileToUploadPath) chatSendingViewModel.addAttachment(fileToUploadPath)
} }

View file

@ -44,6 +44,7 @@ import org.linphone.contact.NativeContact
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.databinding.ContactEditorFragmentBinding import org.linphone.databinding.ContactEditorFragmentBinding
import org.linphone.utils.FileUtils import org.linphone.utils.FileUtils
import org.linphone.utils.ImageUtils
import org.linphone.utils.PermissionHelper import org.linphone.utils.PermissionHelper
class ContactEditorFragment : Fragment() { class ContactEditorFragment : Fragment() {
@ -133,40 +134,9 @@ class ContactEditorFragment : Fragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
var fileToUploadPath: String? = null val contactImageFilePath = ImageUtils.getImageFilePathFromPickerIntent(data, temporaryPicturePath)
if (contactImageFilePath != null) {
val temporaryFileUploadPath = temporaryPicturePath viewModel.setPictureFromPath(contactImageFilePath)
if (temporaryFileUploadPath != null) {
if (data != null) {
val dataUri = data.data
if (dataUri != null) {
fileToUploadPath = dataUri.toString()
Log.i("[Chat Room] Using data URI $fileToUploadPath")
} else if (temporaryFileUploadPath.exists()) {
fileToUploadPath = temporaryFileUploadPath.absolutePath
Log.i("[Chat Room] Data URI is null, using $fileToUploadPath")
}
} else if (temporaryFileUploadPath.exists()) {
fileToUploadPath = temporaryFileUploadPath.absolutePath
Log.i("[Chat Room] Data is null, using $fileToUploadPath")
}
}
if (fileToUploadPath != null) {
if (fileToUploadPath.startsWith("content://") ||
fileToUploadPath.startsWith("file://")
) {
val uriToParse = Uri.parse(fileToUploadPath)
fileToUploadPath = FileUtils.getFilePath(requireContext(), uriToParse)
Log.i("[Chat] Path was using a content or file scheme, real path is: $fileToUploadPath")
if (fileToUploadPath == null) {
Log.e("[Chat] Failed to get access to file $uriToParse")
}
}
}
if (fileToUploadPath != null) {
viewModel.setPictureFromPath(fileToUploadPath)
} }
} }
} }
@ -175,7 +145,7 @@ class ContactEditorFragment : Fragment() {
private fun pickFile() { private fun pickFile() {
val cameraIntents = ArrayList<Intent>() val cameraIntents = ArrayList<Intent>()
// Handles image & video picking // Handles image picking
val galleryIntent = Intent(Intent.ACTION_PICK) val galleryIntent = Intent(Intent.ACTION_PICK)
galleryIntent.type = "image/*" galleryIntent.type = "image/*"

View file

@ -19,15 +19,22 @@
*/ */
package org.linphone.activities.main.sidemenu.fragments package org.linphone.activities.main.sidemenu.fragments
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable
import android.provider.MediaStore
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import java.io.File
import kotlinx.coroutines.launch
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.activities.assistant.AssistantActivity import org.linphone.activities.assistant.AssistantActivity
@ -38,11 +45,15 @@ import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.databinding.SideMenuFragmentBinding import org.linphone.databinding.SideMenuFragmentBinding
import org.linphone.utils.Event import org.linphone.utils.Event
import org.linphone.utils.FileUtils
import org.linphone.utils.ImageUtils
import org.linphone.utils.PermissionHelper
class SideMenuFragment : Fragment() { class SideMenuFragment : Fragment() {
private lateinit var binding: SideMenuFragmentBinding private lateinit var binding: SideMenuFragmentBinding
private lateinit var viewModel: SideMenuViewModel private lateinit var viewModel: SideMenuViewModel
private lateinit var sharedViewModel: SharedMainViewModel private lateinit var sharedViewModel: SharedMainViewModel
private var temporaryPicturePath: File? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -81,6 +92,10 @@ class SideMenuFragment : Fragment() {
} }
} }
binding.setSelfPictureClickListener {
pickFile()
}
binding.setAssistantClickListener { binding.setAssistantClickListener {
sharedViewModel.toggleDrawerEvent.value = Event(true) sharedViewModel.toggleDrawerEvent.value = Event(true)
startActivity(Intent(context, AssistantActivity::class.java)) startActivity(Intent(context, AssistantActivity::class.java))
@ -106,4 +121,39 @@ class SideMenuFragment : Fragment() {
coreContext.stop() coreContext.stop()
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch {
val contactImageFilePath = ImageUtils.getImageFilePathFromPickerIntent(data, temporaryPicturePath)
if (contactImageFilePath != null) {
viewModel.setPictureFromPath(contactImageFilePath)
}
}
}
}
private fun pickFile() {
val cameraIntents = ArrayList<Intent>()
// Handles image picking
val galleryIntent = Intent(Intent.ACTION_PICK)
galleryIntent.type = "image/*"
if (PermissionHelper.get().hasCameraPermission()) {
// Allows to capture directly from the camera
val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val tempFileName = System.currentTimeMillis().toString() + ".jpeg"
temporaryPicturePath = FileUtils.getFileStoragePath(tempFileName)
val uri = Uri.fromFile(temporaryPicturePath)
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
cameraIntents.add(captureIntent)
}
val chooserIntent =
Intent.createChooser(galleryIntent, getString(R.string.chat_message_pick_file_dialog))
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(arrayOf<Parcelable>()))
startActivityForResult(chooserIntent, 0)
}
} }

View file

@ -37,6 +37,7 @@ class SideMenuViewModel : ViewModel() {
val defaultAccount = MutableLiveData<AccountSettingsViewModel>() val defaultAccount = MutableLiveData<AccountSettingsViewModel>()
val defaultAccountFound = MutableLiveData<Boolean>() val defaultAccountFound = MutableLiveData<Boolean>()
val defaultAccountAvatar = MutableLiveData<String>()
val accounts = MutableLiveData<ArrayList<AccountSettingsViewModel>>() val accounts = MutableLiveData<ArrayList<AccountSettingsViewModel>>()
@ -64,6 +65,7 @@ class SideMenuViewModel : ViewModel() {
init { init {
defaultAccountFound.value = false defaultAccountFound.value = false
defaultAccountAvatar.value = corePreferences.defaultAccountAvatarPath
coreContext.core.addListener(listener) coreContext.core.addListener(listener)
updateAccountsList() updateAccountsList()
} }
@ -94,4 +96,9 @@ class SideMenuViewModel : ViewModel() {
} }
accounts.value = list accounts.value = list
} }
fun setPictureFromPath(picturePath: String) {
corePreferences.defaultAccountAvatarPath = picturePath
defaultAccountAvatar.value = corePreferences.defaultAccountAvatarPath
}
} }

View file

@ -276,6 +276,12 @@ class CorePreferences constructor(private val context: Context) {
/* Side Menu */ /* Side Menu */
var defaultAccountAvatarPath: String?
get() = config.getString("app", "default_avatar_path", null)
set(value) {
config.setString("app", "default_avatar_path", value)
}
val showAccountsInSideMenu: Boolean val showAccountsInSideMenu: Boolean
get() = config.getBool("app", "side_menu_accounts", true) get() = config.getBool("app", "side_menu_accounts", true)

View file

@ -263,6 +263,16 @@ fun <T> setEntries(
setEntries(viewGroup, entries, layoutId, null, parent) setEntries(viewGroup, entries, layoutId, null, parent)
} }
@BindingAdapter("glideAvatarFallback")
fun loadAvatarWithGlideFallback(imageView: ImageView, path: String?) {
if (path != null && path.isNotEmpty() && FileUtils.isExtensionImage(path)) {
Glide.with(imageView).load(path).apply(RequestOptions.circleCropTransform()).into(imageView)
} else {
Log.w("[Data Binding] [Glide] Can't load $path")
imageView.setImageResource(R.drawable.avatar)
}
}
@BindingAdapter("glidePath") @BindingAdapter("glidePath")
fun loadImageWithGlide(imageView: ImageView, path: String) { fun loadImageWithGlide(imageView: ImageView, path: String) {
if (path.isNotEmpty() && FileUtils.isExtensionImage(path)) { if (path.isNotEmpty() && FileUtils.isExtensionImage(path)) {

View file

@ -20,10 +20,14 @@
package org.linphone.utils package org.linphone.utils
import android.content.Context import android.content.Context
import android.content.Intent
import android.graphics.* import android.graphics.*
import android.media.ThumbnailUtils import android.media.ThumbnailUtils
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import java.io.File
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.tools.Log
class ImageUtils { class ImageUtils {
companion object { companion object {
@ -67,6 +71,40 @@ class ImageUtils {
return ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND) return ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND)
} }
suspend fun getImageFilePathFromPickerIntent(data: Intent?, temporaryImageFilePath: File?): String? {
var imageFilePath: String? = null
if (temporaryImageFilePath != null) {
if (data != null) {
val dataUri = data.data
if (dataUri != null) {
imageFilePath = dataUri.toString()
Log.i("[Image Utils] Using data URI $imageFilePath")
} else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath
Log.i("[Image Utils] Data URI is null, using $imageFilePath")
}
} else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath
Log.i("[Image Utils] Data is null, using $imageFilePath")
}
}
if (imageFilePath != null) {
if (imageFilePath.startsWith("content://") ||
imageFilePath.startsWith("file://")
) {
val uriToParse = Uri.parse(imageFilePath)
imageFilePath = FileUtils.getFilePath(coreContext.context, uriToParse)
Log.i("[Image Utils] Path was using a content or file scheme, real path is: $imageFilePath")
if (imageFilePath == null) {
Log.e("[Image Utils] Failed to get access to file $uriToParse")
}
}
}
return imageFilePath
}
private fun getRoundBitmap(bitmap: Bitmap): Bitmap? { private fun getRoundBitmap(bitmap: Bitmap): Bitmap? {
val output = val output =
Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888) Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)

View file

@ -4,6 +4,9 @@
<data> <data>
<import type="android.view.View"/> <import type="android.view.View"/>
<variable
name="selfPictureClickListener"
type="android.view.View.OnClickListener"/>
<variable <variable
name="assistantClickListener" name="assistantClickListener"
type="android.view.View.OnClickListener"/> type="android.view.View.OnClickListener"/>
@ -39,10 +42,21 @@
android:layout_height="70dp" android:layout_height="70dp"
android:background="?attr/lightToolbarBackgroundColor"> android:background="?attr/lightToolbarBackgroundColor">
<ImageView
android:visibility="@{viewModel.defaultAccountFound ? View.VISIBLE : View.GONE}"
android:onClick="@{selfPictureClickListener}"
android:id="@+id/avatar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:padding="10dp"
android:src="@drawable/avatar"
glideAvatarFallback="@{viewModel.defaultAccountAvatar}" />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="10dp" android:layout_toRightOf="@id/avatar"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical"> android:orientation="vertical">