feat(friends): Interactions, taps, reload

parent 2e335df3
......@@ -2,18 +2,23 @@ package fr.plnech.dunbar
import android.graphics.Bitmap
import android.provider.ContactsContract.Contacts
import java.util.*
data class Friend(val map: MutableMap<String, String?>, val photo: Bitmap?) {
override fun toString(): String = "$name"
fun mapString(): String = map.entries.filter { !it.value.isNullOrEmpty() }.toString()
val name: String?
get() = map[Contacts.DISPLAY_NAME]
val id: Int
get() = map[Contacts._ID]!!.toInt()
val lastTime: String?
get() = map[Contacts.LAST_TIME_CONTACTED]
val lastTimeStamp = map[Contacts.LAST_TIME_CONTACTED]!!.toLong()
val lastDate: Date?
get() = if (lastTimeStamp > 0) Date(lastTimeStamp) else null
val timesContacted: Int
get() = map[Contacts.TIMES_CONTACTED]?.toInt() ?: 0
......
package fr.plnech.dunbar
import android.text.format.DateUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.contact.view.*
class FriendsAdapter(
private var friends: List<Friend> = mutableListOf()
) : RecyclerView.Adapter<FriendsViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FriendsViewHolder =
FriendsViewHolder(LayoutInflater.from(parent.context).inflate(viewType, parent, false))
override fun getItemCount(): Int = friends.size
override fun getItemViewType(position: Int): Int = R.layout.contact
override fun onBindViewHolder(holder: FriendsViewHolder, position: Int): Unit =
holder.bind(friends[position])
}
class FriendsViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
private val name = view.contactName
private val data = view.contactData
private val pic = view.pic
fun bind(friend: Friend) {
name.text = friend.name
data.text = buildString {
if (friend.lastDate != null ) {
append(friend.timesContacted)
append(" interactions, last ")
append(DateUtils.getRelativeTimeSpanString(friend.lastTimeStamp))
} else {
append("Never interacted")
}
}
view.setOnClickListener {
Toast.makeText(view.context, friend.mapString(), Toast.LENGTH_LONG).show()
}
}
}
......@@ -8,10 +8,9 @@ import android.provider.ContactsContract
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import java.io.IOException
......@@ -27,11 +26,10 @@ class MainActivity : AppCompatActivity() {
setSupportActionBar(toolbar)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
reloadFriends()
}
fetchFriends()
reloadFriends()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
......@@ -50,8 +48,15 @@ class MainActivity : AppCompatActivity() {
}
}
fun fetchFriends() {
Toast.makeText(this@MainActivity, "Fetching friends...", Toast.LENGTH_SHORT).show()
private fun reloadFriends() {
fetchFriends()
displayFriends()
Toast.makeText(this, "Friends reloaded.", Toast.LENGTH_SHORT).show()
}
private fun fetchFriends() {
val newFriends = mutableListOf<Friend>()
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
......@@ -62,41 +67,43 @@ class MainActivity : AppCompatActivity() {
)?.let {
while (it.moveToNext()) {
mutableMapOf<String, String?>().also { map ->
val indexID = it.getColumnIndex(ContactsContract.Contacts._ID)
val id = it.getLong(indexID)
val indexId = it.getColumnIndex(ContactsContract.Contacts._ID)
val id = it.getLong(indexId)
val photo: Bitmap? = getPhoto(id)
it.columnNames.forEach { name ->
val index = it.getColumnIndex(name)
map[name] = it.getString(index)
}
friends.add(Friend(map, photo))
newFriends.add(Friend(map, photo))
}
}
it.close()
val adapter = ArrayAdapter<Friend>(
this, R.layout.contact, R.id.name,
friends
)
friends.clear()
friends.addAll(newFriends)
}
friendsList.adapter = adapter
friendsList.setOnItemClickListener { parent, view, position, id ->
val contact: String = adapter.getItem(position)?.toString() ?: "NONE"
friends.sortByDescending { it.timesContacted }
}
private fun displayFriends() {
val adapter = FriendsAdapter(friends)
friendsList.layoutManager = LinearLayoutManager(this)
friendsList.setHasFixedSize(true)
friendsList.adapter = adapter
// friendsList.setOnItemClickListener { parent, view, position, id ->
// val contact: String = adapter.getItem(position)?.toString() ?: "NONE"
//
// Snackbar.make(friendsList, contact, Snackbar.LENGTH_INDEFINITE).show()
Toast.makeText(this, contact, Toast.LENGTH_LONG).show()
}
// Toast.makeText(this, contact, Toast.LENGTH_LONG).show()
// }
val nbFriends = adapter.count
val nbFriends = adapter.itemCount
welcomeTitle.text = "$nbFriends ${"friend".plural(nbFriends)} on Dunbar"
Toast.makeText(this@MainActivity, "$nbFriends ", Toast.LENGTH_LONG).show()
it.close()
}
}
private fun getPhoto(id: Long): Bitmap? {
......
......@@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:elevation="5dp">
<androidx.constraintlayout.widget.ConstraintLayout
......@@ -24,12 +24,12 @@
android:elevation="2dp"
android:src="@drawable/user"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/name"
app:layout_constraintRight_toLeftOf="@id/contactName"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/name"
android:id="@+id/contactName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="false"
......@@ -38,15 +38,15 @@
android:gravity="end"
android:maxLines="2"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
app:layout_constraintBottom_toTopOf="@id/metadata"
app:layout_constraintBottom_toTopOf="@id/contactData"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="@id/pic"
app:layout_constraintRight_toLeftOf="@id/name"
app:layout_constraintRight_toLeftOf="@id/contactName"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<TextView
android:id="@+id/metadata"
android:id="@+id/contactData"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
......@@ -58,8 +58,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="@id/pic"
app:layout_constraintRight_toLeftOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/name"
app:layout_constraintRight_toLeftOf="@id/contactName"
app:layout_constraintTop_toBottomOf="@id/contactName"
tools:text="@tools:sample/full_names" />
</androidx.constraintlayout.widget.ConstraintLayout>
......
......@@ -10,17 +10,19 @@
<TextView
android:id="@+id/welcomeTitle"
android:layout_marginTop="50dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="N friends on Dunbar"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@id/friendsList"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:text="N friends on Dunbar" />
<ListView
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/friendsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment