Lots of work on contacts

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2020-01-16 03:18:07 +01:00
parent ea758940de
commit acc55d36af
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
20 changed files with 173 additions and 139 deletions

View File

@ -21,13 +21,14 @@
package com.nextcloud.talk.adapters.items package com.nextcloud.talk.adapters.items
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.view.View import android.view.View
import coil.api.load import coil.api.load
import coil.transform.CircleCropTransformation
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.newarch.local.models.UserNgEntity import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.newarch.utils.Images
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@ -40,7 +41,8 @@ class MentionAutocompleteItem(
val objectId: String?, val objectId: String?,
val displayName: String?, val displayName: String?,
var source: String?, var source: String?,
private val currentUser: UserNgEntity private val currentUser: UserNgEntity,
val context: Context
) : AbstractFlexibleItem<UserItem.UserItemViewHolder>(), IFilterable<String> { ) : AbstractFlexibleItem<UserItem.UserItemViewHolder>(), IFilterable<String> {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@ -94,9 +96,7 @@ class MentionAutocompleteItem(
} }
if (source == "calls") { if (source == "calls") {
holder.avatarImageView!!.load(R.drawable.ic_people_group_white_24px) { holder.avatarImageView?.load(Images().getImageWithBackground(context, R.drawable.ic_people_group_white_24px))
transformations(CircleCropTransformation())
}
} else { } else {
var avatarId = objectId var avatarId = objectId
var avatarUrl = ApiUtils.getUrlForAvatarWithName( var avatarUrl = ApiUtils.getUrlForAvatarWithName(
@ -114,7 +114,6 @@ class MentionAutocompleteItem(
holder.avatarImageView!!.load(avatarUrl) { holder.avatarImageView!!.load(avatarUrl) {
addHeader("Authorization", currentUser.getCredentials()) addHeader("Authorization", currentUser.getCredentials())
transformations(CircleCropTransformation())
} }
} }
} }

View File

@ -21,18 +21,22 @@
package com.nextcloud.talk.adapters.items package com.nextcloud.talk.adapters.items
import android.content.Context import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import androidx.emoji.widget.EmojiTextView import androidx.emoji.widget.EmojiTextView
import androidx.recyclerview.widget.RecyclerView.ViewHolder import androidx.recyclerview.widget.RecyclerView.ViewHolder
import coil.api.load import coil.api.load
import coil.transform.CircleCropTransformation import com.google.android.material.imageview.ShapeableImageView
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter
import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.newarch.local.models.UserNgEntity import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.utils.Images
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@ -147,24 +151,20 @@ class UserItem(
holder.avatarImageView!!.load(ApiUtils.getUrlForAvatarWithNameForGuests( holder.avatarImageView!!.load(ApiUtils.getUrlForAvatarWithNameForGuests(
entity.baseUrl, entity.baseUrl,
displayName, R.dimen.avatar_size displayName, R.dimen.avatar_size
)) { ))
transformations(CircleCropTransformation())
}
} else { } else {
holder.avatarImageView!!.load(ApiUtils.getUrlForAvatarWithNameForGuests( holder.avatarImageView!!.load(ApiUtils.getUrlForAvatarWithNameForGuests(
entity.baseUrl, entity.baseUrl,
model.userId, R.dimen.avatar_size model.userId, R.dimen.avatar_size
)) { ))
transformations(CircleCropTransformation())
}
} }
} else if ("groups" == model.source) { } else if ("groups" == model.source) {
holder.avatarImageView!!.load(R.drawable.ic_people_group_white_24px) { holder.avatarImageView?.load(Images().getImageWithBackground(activityContext, R.drawable.ic_people_group_white_24px))
transformations(CircleCropTransformation()) } else if ("emails" == model.source) {
} holder.avatarImageView?.load(Images().getImageWithBackground(activityContext, R.drawable.ic_baseline_email_24))
} }
val resources = activityContext.resources val resources = activityContext.resources
@ -264,7 +264,7 @@ class UserItem(
) : FlexibleViewHolder(view, adapter) { ) : FlexibleViewHolder(view, adapter) {
var contactDisplayName: EmojiTextView? = null var contactDisplayName: EmojiTextView? = null
var avatarImageView: ImageView? = null var avatarImageView: ShapeableImageView? = null
var contactMentionId: EmojiTextView? = null var contactMentionId: EmojiTextView? = null
var voiceOrSimpleCallImageView: ImageView? = null var voiceOrSimpleCallImageView: ImageView? = null
var videoCallImageView: ImageView? = null var videoCallImageView: ImageView? = null

View File

@ -440,12 +440,12 @@ class CallNotificationController(private val originalBundle: Bundle) : BaseContr
} }
Conversation.ConversationType.GROUP_CONVERSATION -> { Conversation.ConversationType.GROUP_CONVERSATION -> {
avatarImageView?.load(R.drawable.ic_people_group_white_24px) { avatarImageView?.load(R.drawable.ic_people_group_white_24px_with_circle) {
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
} }
} }
Conversation.ConversationType.PUBLIC_CONVERSATION -> { Conversation.ConversationType.PUBLIC_CONVERSATION -> {
avatarImageView?.load(R.drawable.ic_link_white_24px) { avatarImageView?.load(R.drawable.ic_link_white_24px_with_circle) {
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
} }

View File

@ -623,22 +623,26 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
} }
private fun setupMentionAutocomplete() { private fun setupMentionAutocomplete() {
val elevation = 6f activity?.let {
val backgroundDrawable = ColorDrawable(resources!!.getColor(R.color.bg_default)) resources?.let { resources ->
val presenter = MentionAutocompletePresenter(applicationContext!!, roomToken) val elevation = 6f
val callback = MentionAutocompleteCallback( val backgroundDrawable = ColorDrawable(resources.getColor(R.color.bg_default))
activity, val presenter = MentionAutocompletePresenter(it, roomToken)
conversationUser, messageInput val callback = MentionAutocompleteCallback(
) activity,
conversationUser, messageInput
)
if (mentionAutocomplete == null && messageInput != null) { if (mentionAutocomplete == null && messageInput != null) {
mentionAutocomplete = Autocomplete.on<Mention>(messageInput) mentionAutocomplete = Autocomplete.on<Mention>(messageInput)
.with(elevation) .with(elevation)
.with(backgroundDrawable) .with(backgroundDrawable)
.with(MagicCharPolicy('@')) .with(MagicCharPolicy('@'))
.with(presenter) .with(presenter)
.with(callback) .with(callback)
.build() .build()
}
}
} }
} }

View File

@ -100,8 +100,7 @@ import kotlin.String
class ContactsController : BaseController, class ContactsController : BaseController,
SearchView.OnQueryTextListener, SearchView.OnQueryTextListener,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemClickListener,
FastScroller.OnScrollStateChangeListener, FastScroller.OnScrollStateChangeListener{
FlexibleAdapter.EndlessScrollListener {
val usersRepository: UsersRepository by inject() val usersRepository: UsersRepository by inject()
val ncApi: NcApi by inject() val ncApi: NcApi by inject()
@ -144,8 +143,6 @@ class ContactsController : BaseController,
private var contactItems: MutableList<AbstractFlexibleItem<*>>? = null private var contactItems: MutableList<AbstractFlexibleItem<*>>? = null
private var bottomSheet: BottomSheet? = null private var bottomSheet: BottomSheet? = null
private var bottomSheetView: View? = null private var bottomSheetView: View? = null
private var currentPage: Int = 0
private var currentSearchPage: Int = 0
private var layoutManager: SmoothScrollLinearLayoutManager? = null private var layoutManager: SmoothScrollLinearLayoutManager? = null
@ -158,8 +155,6 @@ class ContactsController : BaseController,
private var userHeaderItems = HashMap<String, GenericTextHeaderItem>() private var userHeaderItems = HashMap<String, GenericTextHeaderItem>()
private var alreadyFetching = false private var alreadyFetching = false
private var canFetchFurther = true
private var canFetchSearchFurther = true
private var doneMenuItem: MenuItem? = null private var doneMenuItem: MenuItem? = null
@ -247,8 +242,6 @@ class ContactsController : BaseController,
adapter!!.setNotifyChangeOfUnfilteredItems(true) adapter!!.setNotifyChangeOfUnfilteredItems(true)
.mode = SelectableAdapter.Mode.MULTI .mode = SelectableAdapter.Mode.MULTI
adapter!!.setEndlessScrollListener(this, ProgressItem())
adapter!!.addListener(this) adapter!!.addListener(this)
} }
@ -456,52 +449,31 @@ class ContactsController : BaseController,
private fun fetchData(startFromScratch: Boolean) { private fun fetchData(startFromScratch: Boolean) {
alreadyFetching = true alreadyFetching = true
val shareeHashSet = HashSet<Sharee>()
val autocompleteUsersHashSet = HashSet<AutocompleteUser>() val autocompleteUsersHashSet = HashSet<AutocompleteUser>()
userHeaderItems = HashMap() userHeaderItems = HashMap()
val query = adapter!!.getFilter(String::class.java) val query = adapter!!.getFilter(String::class.java)
val retrofitBucket: RetrofitBucket val retrofitBucket: RetrofitBucket = ApiUtils.getRetrofitBucketForContactsSearchFor14(currentUser!!.baseUrl, query)
var serverIs14OrUp = false
if (currentUser!!.hasSpreedFeatureCapability("last-room-activity")) {
// a hack to see if we're on 14 or not
retrofitBucket =
ApiUtils.getRetrofitBucketForContactsSearchFor14(currentUser!!.baseUrl, query)
serverIs14OrUp = true
} else {
retrofitBucket = ApiUtils.getRetrofitBucketForContactsSearch(currentUser!!.baseUrl, query)
}
var page = 1
if (!startFromScratch) {
if (TextUtils.isEmpty(query)) {
page = currentPage + 1
} else {
page = currentSearchPage + 1
}
}
val modifiedQueryMap = HashMap<String, Any>(retrofitBucket.queryMap) val modifiedQueryMap = HashMap<String, Any>(retrofitBucket.queryMap)
modifiedQueryMap["page"] = page modifiedQueryMap["limit"] = 100
modifiedQueryMap["perPage"] = 100
var shareTypesList: MutableList<String>? = null var shareTypesList: MutableList<String> = mutableListOf()
// user
shareTypesList.add("0")
// group
shareTypesList.add("1")
// remote
shareTypesList.add("7");
if (serverIs14OrUp) { if (!isNewConversationView) {
shareTypesList = ArrayList() modifiedQueryMap["itemId"] = "difz"
// users shareTypesList.add("4")
shareTypesList.add("0")
// groups
shareTypesList.add("1")
// mails
//shareTypesList.add("4");
modifiedQueryMap["shareTypes[]"] = shareTypesList
} }
val finalServerIs14OrUp = serverIs14OrUp modifiedQueryMap["shareTypes[]"] = shareTypesList
ncApi.getContactsWithSearchParam( ncApi.getContactsWithSearchParam(
credentials, credentials,
retrofitBucket.url, shareTypesList, modifiedQueryMap retrofitBucket.url, shareTypesList, modifiedQueryMap
@ -563,16 +535,6 @@ class ContactsController : BaseController,
Log.e(TAG, "Parsing response body failed while getting contacts") Log.e(TAG, "Parsing response body failed while getting contacts")
} }
if (TextUtils.isEmpty(modifiedQueryMap["search"] as CharSequence?)) {
canFetchFurther =
!shareeHashSet.isEmpty() || finalServerIs14OrUp && autocompleteUsersHashSet.size == 100
currentPage = modifiedQueryMap["page"] as Int
} else {
canFetchSearchFurther =
!shareeHashSet.isEmpty() || finalServerIs14OrUp && autocompleteUsersHashSet.size == 100
currentSearchPage = modifiedQueryMap["page"] as Int
}
userHeaderItems = HashMap() userHeaderItems = HashMap()
contactItems!!.addAll(newUserItemList) contactItems!!.addAll(newUserItemList)
@ -1007,23 +969,6 @@ class ContactsController : BaseController,
} }
} }
override fun noMoreLoad(newItemsSize: Int) {}
override fun onLoadMore(
lastPosition: Int,
currentPage: Int
) {
if (!alreadyFetching && (searchView != null && searchView!!.isIconified && canFetchFurther || !TextUtils.isEmpty(
adapter!!.getFilter(String::class.java)
) && canFetchSearchFurther)
) {
fetchData(false)
} else {
adapter!!.onLoadMoreComplete(null)
}
}
companion object { companion object {
val TAG = "ContactsController" val TAG = "ContactsController"

View File

@ -293,7 +293,7 @@ fun createImageLoader(
return ImageLoader(androidApplication) { return ImageLoader(androidApplication) {
availableMemoryPercentage(0.5) availableMemoryPercentage(0.5)
bitmapPoolPercentage(0.5) bitmapPoolPercentage(0.5)
crossfade(true) crossfade(false)
okHttpClient(okHttpClient) okHttpClient(okHttpClient)
componentRegistry { componentRegistry {
if (SDK_INT >= P) { if (SDK_INT >= P) {

View File

@ -21,8 +21,12 @@
package com.nextcloud.talk.newarch.utils package com.nextcloud.talk.newarch.utils
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.ScaleDrawable
import android.view.Gravity
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader import coil.ImageLoader
import coil.request.LoadRequest import coil.request.LoadRequest
@ -34,7 +38,6 @@ import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
class Images { class Images {
fun getRequestForUrl( fun getRequestForUrl(
imageLoader: ImageLoader, imageLoader: ImageLoader,
@ -65,15 +68,28 @@ class Images {
} }
} }
fun getImageWithBackground(context: Context, drawableId: Int): Bitmap {
val layers = arrayOfNulls<Drawable>(2)
layers[0] = context.getDrawable(R.color.bg_message_list_incoming_bubble)
var scale = 0.25f
if (drawableId == R.drawable.ic_baseline_email_24 || drawableId == R.drawable.ic_link_white_24px) {
scale = 0.5f
}
layers[1] = ScaleDrawable(context.getDrawable(drawableId), Gravity.CENTER, scale, scale)
layers[0]?.level = 0
layers[1]?.level = 1
return LayerDrawable(layers).toBitmap()
}
// returns null if it's one-to-one that you need to fetch yourself // returns null if it's one-to-one that you need to fetch yourself
fun getImageForConversation(context: Context, conversation: Conversation): Drawable? { fun getImageForConversation(context: Context, conversation: Conversation): Drawable? {
conversation.objectType?.let { objectType -> conversation.objectType?.let { objectType ->
when (objectType) { when (objectType) {
"share:password" -> { "share:password" -> {
return DisplayUtils.getRoundedDrawable(context.getDrawable(R.drawable.ic_file_password_request)) return DisplayUtils.getRoundedDrawableFromBitmap(getImageWithBackground(context, R.drawable.ic_file_password_request))
} }
"file" -> { "file" -> {
return DisplayUtils.getRoundedDrawable(context.getDrawable(R.drawable.ic_file_icon)) return DisplayUtils.getRoundedDrawableFromBitmap(getImageWithBackground(context, R.drawable.ic_file_icon))
} }
else -> { else -> {
} // do nothing } // do nothing
@ -85,10 +101,10 @@ class Images {
return null return null
} }
Conversation.ConversationType.GROUP_CONVERSATION -> { Conversation.ConversationType.GROUP_CONVERSATION -> {
return DisplayUtils.getRoundedDrawable(context.getDrawable(R.drawable.ic_people_group_white_24px)) return DisplayUtils.getRoundedDrawableFromBitmap(getImageWithBackground(context, R.drawable.ic_people_group_white_24px))
} }
Conversation.ConversationType.PUBLIC_CONVERSATION -> { Conversation.ConversationType.PUBLIC_CONVERSATION -> {
return DisplayUtils.getRoundedDrawable(context.getDrawable(R.drawable.ic_link_white_24px)) return DisplayUtils.getRoundedDrawableFromBitmap(getImageWithBackground(context, R.drawable.ic_link_white_24px))
} }
else -> { else -> {
// we handle else as Conversation.ConversationType.SYSTEM_CONVERSATION for now // we handle else as Conversation.ConversationType.SYSTEM_CONVERSATION for now

View File

@ -96,7 +96,7 @@ class MentionAutocompletePresenter : RecyclerViewPresenter<Mention?>, FlexibleAd
internalAbstractFlexibleItemList.add( internalAbstractFlexibleItemList.add(
MentionAutocompleteItem(mention.id, MentionAutocompleteItem(mention.id,
mention.label, mention.source, mention.label, mention.source,
currentUser!!)) currentUser!!, internalContext))
} }
if (adapter!!.itemCount != 0) { if (adapter!!.itemCount != 0) {
adapter!!.clear() adapter!!.clear()

View File

@ -97,6 +97,12 @@ object DisplayUtils {
textView.movementMethod = LinkMovementMethod.getInstance() textView.movementMethod = LinkMovementMethod.getInstance()
} }
fun getRoundedDrawableFromBitmap(bitmap: Bitmap): Drawable {
return runBlocking {
return@runBlocking BitmapDrawable(CircleCropTransformation().transform(BitmapPool(0), bitmap, OriginalSize))
}
}
fun getRoundedDrawable(drawable: Drawable?): Drawable { fun getRoundedDrawable(drawable: Drawable?): Drawable {
val bitmap = getBitmap(drawable!!) val bitmap = getBitmap(drawable!!)
val drawable = runBlocking { val drawable = runBlocking {
@ -225,7 +231,7 @@ object DisplayUtils {
target(target) target(target)
} }
} else { } else {
Coil.load(context, R.drawable.ic_people_group_white_24px) { Coil.load(context, R.drawable.ic_people_group_white_24px_with_circle) {
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
target(target) target(target)
} }

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z"/>
</vector>

View File

@ -21,9 +21,6 @@
<vector android:autoMirrored="true" android:height="24dp" <vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24" android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero"
android:pathData="M0,0l24,0l0,24l-24,0z" android:strokeAlpha="0"
android:strokeColor="#000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero" <path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M6.4825,5C6.2123,5 6,5.2123 6,5.4825L6,18.0275C6,18.2977 6.2123,18.51 6.4825,18.51L17.0975,18.51C17.3677,18.51 17.58,18.2977 17.58,18.0275L17.58,7.895L14.685,5L6.4825,5ZM7.93,6.93L13.72,6.93L13.72,7.895L7.93,7.895L7.93,6.93ZM7.93,9.825L12.755,9.825L12.755,10.79L7.93,10.79L7.93,9.825ZM7.93,12.72L15.65,12.72L15.65,13.685L7.93,13.685L7.93,12.72ZM7.93,15.615L11.79,15.615L11.79,16.58L7.93,16.58L7.93,15.615Z" android:pathData="M6.4825,5C6.2123,5 6,5.2123 6,5.4825L6,18.0275C6,18.2977 6.2123,18.51 6.4825,18.51L17.0975,18.51C17.3677,18.51 17.58,18.2977 17.58,18.0275L17.58,7.895L14.685,5L6.4825,5ZM7.93,6.93L13.72,6.93L13.72,7.895L7.93,7.895L7.93,6.93ZM7.93,9.825L12.755,9.825L12.755,10.79L7.93,10.79L7.93,9.825ZM7.93,12.72L15.65,12.72L15.65,13.685L7.93,13.685L7.93,12.72ZM7.93,15.615L11.79,15.615L11.79,16.58L7.93,16.58L7.93,15.615Z"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000" android:strokeWidth="1"/>

View File

@ -21,9 +21,6 @@
<vector android:autoMirrored="true" android:height="24dp" <vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24" android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero"
android:pathData="M0,0l24,0l0,24l-24,0z" android:strokeAlpha="0"
android:strokeColor="#000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero" <path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M15.8787,9.9394L15.1731,9.9394L15.1731,8.5281C15.1731,6.5806 13.5925,5 11.645,5C9.6975,5 8.1169,6.5806 8.1169,8.5281L8.1169,9.9394L7.4113,9.9394C6.6351,9.9394 6,10.5744 6,11.3506L6,18.4069C6,19.1831 6.6351,19.8181 7.4113,19.8181L15.8787,19.8181C16.6549,19.8181 17.29,19.1831 17.29,18.4069L17.29,11.3506C17.29,10.5744 16.6549,9.9394 15.8787,9.9394ZM9.5281,8.5281C9.5281,7.3568 10.4737,6.4113 11.645,6.4113C12.8163,6.4113 13.7619,7.3568 13.7619,8.5281L13.7619,9.9394L9.5281,9.9394L9.5281,8.5281ZM15.8787,18.4069L7.4113,18.4069L7.4113,11.3506L15.8787,11.3506L15.8787,18.4069ZM11.645,16.29C12.4212,16.29 13.0562,15.6549 13.0562,14.8787C13.0562,14.1026 12.4212,13.4675 11.645,13.4675C10.8688,13.4675 10.2338,14.1026 10.2338,14.8787C10.2338,15.6549 10.8688,16.29 11.645,16.29Z" android:pathData="M15.8787,9.9394L15.1731,9.9394L15.1731,8.5281C15.1731,6.5806 13.5925,5 11.645,5C9.6975,5 8.1169,6.5806 8.1169,8.5281L8.1169,9.9394L7.4113,9.9394C6.6351,9.9394 6,10.5744 6,11.3506L6,18.4069C6,19.1831 6.6351,19.8181 7.4113,19.8181L15.8787,19.8181C16.6549,19.8181 17.29,19.1831 17.29,18.4069L17.29,11.3506C17.29,10.5744 16.6549,9.9394 15.8787,9.9394ZM9.5281,8.5281C9.5281,7.3568 10.4737,6.4113 11.645,6.4113C12.8163,6.4113 13.7619,7.3568 13.7619,8.5281L13.7619,9.9394L9.5281,9.9394L9.5281,8.5281ZM15.8787,18.4069L7.4113,18.4069L7.4113,11.3506L15.8787,11.3506L15.8787,18.4069ZM11.645,16.29C12.4212,16.29 13.0562,15.6549 13.0562,14.8787C13.0562,14.1026 12.4212,13.4675 11.645,13.4675C10.8688,13.4675 10.2338,14.1026 10.2338,14.8787C10.2338,15.6549 10.8688,16.29 11.645,16.29Z"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:strokeColor="#00000000" android:strokeWidth="1"/>

View File

@ -2,7 +2,7 @@
~ Nextcloud Talk application ~ Nextcloud Talk application
~ ~
~ @author Mario Danic ~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com> ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~ ~
~ This program is free software: you can redistribute it and/or modify ~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by ~ it under the terms of the GNU General Public License as published by
@ -18,15 +18,11 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<vector xmlns:tools="http://schemas.android.com/tools" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true" android:height="24dp" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportWidth="24"
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero" android:viewportHeight="24">
android:pathData="M0,0l24,0l0,24l-24,0z" <path android:fillColor="#FFFFFF"
android:strokeColor="#00000000" android:strokeWidth="1"/> android:pathData="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" />
<path android:fillColor="#FFFFFF" android:fillType="nonZero" </vector>
android:pathData="M13,5.921L9.818,9.105C9.111,9.812 8.781,10.723 8.83,11.562C8.88,12.401 9.263,13.146 9.818,13.701L11.23,12.285C10.663,11.717 10.686,11.065 11.232,10.519L14.414,7.337C14.939,6.812 15.664,6.814 16.186,7.335C16.668,7.891 16.713,8.574 16.182,9.105L15.362,9.925C15.917,10.71 16.007,11.291 15.955,12.16L17.596,10.519C18.833,9.282 18.833,7.154 17.596,5.917C16.36,4.681 14.254,4.706 13,5.921L13,5.921ZM13.707,9.806L12.293,11.224L12.297,11.224C12.847,11.774 12.804,12.482 12.293,12.994L9.111,16.175C8.415,16.767 7.813,16.646 7.342,16.175C6.715,15.549 6.842,14.907 7.342,14.407L8.192,13.56C7.636,12.777 7.543,12.195 7.594,11.328L5.928,12.994C4.689,14.233 4.692,16.354 5.928,17.589C7.163,18.825 9.29,18.825 10.526,17.589L13.707,14.407C14.416,13.699 14.747,12.789 14.698,11.949C14.65,11.109 14.266,10.362 13.709,9.808L13.707,9.806Z"
android:strokeColor="#00000000" android:strokeWidth="1"
tools:ignore="VectorPath" />
</vector>

View File

@ -0,0 +1,32 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector xmlns:tools="http://schemas.android.com/tools"
android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero"
android:pathData="M0,0l24,0l0,24l-24,0z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M13,5.921L9.818,9.105C9.111,9.812 8.781,10.723 8.83,11.562C8.88,12.401 9.263,13.146 9.818,13.701L11.23,12.285C10.663,11.717 10.686,11.065 11.232,10.519L14.414,7.337C14.939,6.812 15.664,6.814 16.186,7.335C16.668,7.891 16.713,8.574 16.182,9.105L15.362,9.925C15.917,10.71 16.007,11.291 15.955,12.16L17.596,10.519C18.833,9.282 18.833,7.154 17.596,5.917C16.36,4.681 14.254,4.706 13,5.921L13,5.921ZM13.707,9.806L12.293,11.224L12.297,11.224C12.847,11.774 12.804,12.482 12.293,12.994L9.111,16.175C8.415,16.767 7.813,16.646 7.342,16.175C6.715,15.549 6.842,14.907 7.342,14.407L8.192,13.56C7.636,12.777 7.543,12.195 7.594,11.328L5.928,12.994C4.689,14.233 4.692,16.354 5.928,17.589C7.163,18.825 9.29,18.825 10.526,17.589L13.707,14.407C14.416,13.699 14.747,12.789 14.698,11.949C14.65,11.109 14.266,10.362 13.709,9.808L13.707,9.806Z"
android:strokeColor="#00000000" android:strokeWidth="1"
tools:ignore="VectorPath" />
</vector>

View File

@ -2,7 +2,7 @@
~ Nextcloud Talk application ~ Nextcloud Talk application
~ ~
~ @author Mario Danic ~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com> ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~ ~
~ This program is free software: you can redistribute it and/or modify ~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by ~ it under the terms of the GNU General Public License as published by
@ -22,10 +22,7 @@
android:autoMirrored="true" android:height="24dp" android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero" <path android:fillColor="@color/white" android:fillType="nonZero"
android:pathData="M0,0l24,0l0,24l-24,0z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M12.729,5C11.044,5 9.833,6.38 9.833,7.702C9.833,9.054 9.93,10.019 10.605,11.08C10.822,11.36 11.074,11.418 11.281,11.659C11.411,12.142 11.513,12.625 11.378,13.107C10.957,13.255 10.557,13.428 10.152,13.59C9.66,13.326 9.09,13.107 8.598,12.914C8.53,12.644 8.579,12.444 8.646,12.19C8.762,12.07 8.868,12.016 8.994,11.901C9.351,11.466 9.37,10.733 9.37,10.212C9.37,9.44 8.675,8.861 7.922,8.861C7.082,8.861 6.474,9.555 6.474,10.212L6.455,10.212C6.455,10.887 6.503,11.37 6.841,11.901C6.938,12.045 7.075,12.07 7.179,12.19C7.244,12.431 7.296,12.673 7.227,12.914C6.61,13.129 6.027,13.397 5.49,13.686C5.085,13.976 5.265,13.862 5.007,14.796C4.888,15.279 6.262,15.501 7.247,15.578C7.198,15.843 7.131,16.196 6.938,16.871C6.629,18.078 11.139,18.512 12.729,18.512C15.074,18.512 18.822,18.072 18.501,16.871C17.999,14.999 18.3,15.221 17.555,14.651C16.503,14.02 15.188,13.525 14.08,13.107C13.935,12.57 14.041,12.171 14.177,11.659C14.403,11.418 14.659,11.312 14.872,11.08C15.537,10.227 15.624,8.741 15.624,7.702C15.624,6.172 14.244,5 12.729,5L12.729,5Z" android:pathData="M12.729,5C11.044,5 9.833,6.38 9.833,7.702C9.833,9.054 9.93,10.019 10.605,11.08C10.822,11.36 11.074,11.418 11.281,11.659C11.411,12.142 11.513,12.625 11.378,13.107C10.957,13.255 10.557,13.428 10.152,13.59C9.66,13.326 9.09,13.107 8.598,12.914C8.53,12.644 8.579,12.444 8.646,12.19C8.762,12.07 8.868,12.016 8.994,11.901C9.351,11.466 9.37,10.733 9.37,10.212C9.37,9.44 8.675,8.861 7.922,8.861C7.082,8.861 6.474,9.555 6.474,10.212L6.455,10.212C6.455,10.887 6.503,11.37 6.841,11.901C6.938,12.045 7.075,12.07 7.179,12.19C7.244,12.431 7.296,12.673 7.227,12.914C6.61,13.129 6.027,13.397 5.49,13.686C5.085,13.976 5.265,13.862 5.007,14.796C4.888,15.279 6.262,15.501 7.247,15.578C7.198,15.843 7.131,16.196 6.938,16.871C6.629,18.078 11.139,18.512 12.729,18.512C15.074,18.512 18.822,18.072 18.501,16.871C17.999,14.999 18.3,15.221 17.555,14.651C16.503,14.02 15.188,13.525 14.08,13.107C13.935,12.57 14.041,12.171 14.177,11.659C14.403,11.418 14.659,11.312 14.872,11.08C15.537,10.227 15.624,8.741 15.624,7.702C15.624,6.172 14.244,5 12.729,5L12.729,5Z"
android:strokeColor="#00000000" android:strokeWidth="1" android:strokeColor="#00000000" android:strokeWidth="1"
tools:ignore="VectorPath" /> tools:ignore="VectorPath" />

View File

@ -0,0 +1,32 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector xmlns:tools="http://schemas.android.com/tools"
android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/bg_message_list_incoming_bubble" android:fillType="nonZero"
android:pathData="M0,0l24,0l0,24l-24,0z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
<path android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M12.729,5C11.044,5 9.833,6.38 9.833,7.702C9.833,9.054 9.93,10.019 10.605,11.08C10.822,11.36 11.074,11.418 11.281,11.659C11.411,12.142 11.513,12.625 11.378,13.107C10.957,13.255 10.557,13.428 10.152,13.59C9.66,13.326 9.09,13.107 8.598,12.914C8.53,12.644 8.579,12.444 8.646,12.19C8.762,12.07 8.868,12.016 8.994,11.901C9.351,11.466 9.37,10.733 9.37,10.212C9.37,9.44 8.675,8.861 7.922,8.861C7.082,8.861 6.474,9.555 6.474,10.212L6.455,10.212C6.455,10.887 6.503,11.37 6.841,11.901C6.938,12.045 7.075,12.07 7.179,12.19C7.244,12.431 7.296,12.673 7.227,12.914C6.61,13.129 6.027,13.397 5.49,13.686C5.085,13.976 5.265,13.862 5.007,14.796C4.888,15.279 6.262,15.501 7.247,15.578C7.198,15.843 7.131,16.196 6.938,16.871C6.629,18.078 11.139,18.512 12.729,18.512C15.074,18.512 18.822,18.072 18.501,16.871C17.999,14.999 18.3,15.221 17.555,14.651C16.503,14.02 15.188,13.525 14.08,13.107C13.935,12.57 14.041,12.171 14.177,11.659C14.403,11.418 14.659,11.312 14.872,11.08C15.537,10.227 15.624,8.741 15.624,7.702C15.624,6.172 14.244,5 12.729,5L12.729,5Z"
android:strokeColor="#00000000" android:strokeWidth="1"
tools:ignore="VectorPath" />
</vector>

View File

@ -48,8 +48,9 @@
android:ellipsize="end" android:ellipsize="end"
tools:text="Contact item text" /> tools:text="Contact item text" />
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/avatarImageView" android:id="@+id/avatarImageView"
app:shapeAppearanceOverlay="@style/circleImageView"
android:layout_width="@dimen/small_item_height" android:layout_width="@dimen/small_item_height"
android:layout_height="@dimen/small_item_height" android:layout_height="@dimen/small_item_height"
android:layout_centerVertical="true" android:layout_centerVertical="true"

View File

@ -32,10 +32,11 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginStart="@dimen/activity_horizontal_margin"> android:layout_marginStart="@dimen/activity_horizontal_margin">
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/avatarImageView" android:id="@+id/avatarImageView"
android:layout_width="@dimen/avatar_size" android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size" android:layout_height="@dimen/avatar_size"
app:shapeAppearanceOverlay="@style/circleImageView"
tools:background="@tools:sample/avatars[1]" tools:background="@tools:sample/avatars[1]"
/> />

View File

@ -24,6 +24,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/item_height" android:layout_height="@dimen/item_height"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
@ -33,8 +34,9 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginStart="@dimen/activity_horizontal_margin"> android:layout_marginStart="@dimen/activity_horizontal_margin">
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/avatarImageView" android:id="@+id/avatarImageView"
app:shapeAppearanceOverlay="@style/circleImageView"
android:layout_width="@dimen/avatar_size" android:layout_width="@dimen/avatar_size"
android:layout_height="@dimen/avatar_size"/> android:layout_height="@dimen/avatar_size"/>

View File

@ -68,4 +68,8 @@
<item name="android:textColor">@color/nc_incoming_text_default</item> <item name="android:textColor">@color/nc_incoming_text_default</item>
</style> </style>
<style name="circleImageView" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
</resources> </resources>