refactor: Extract methods to right place

parent 58e90f84
......@@ -5,8 +5,6 @@
- Select best friend to remind of
- Keep track of reminded?
- Stats
- Quick increment
# 0.5
- Auto increment from call/sms log?
\ No newline at end of file
- Quick increment
- Store interactions, not only call/sms log
package fr.plnech.dunbar
import android.content.Intent
import android.net.Uri
import android.content.ContentUris
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.provider.ContactsContract
import fr.plnech.dunbar.model.Friend
import java.io.IOException
fun String.plural(count: Int = 1): String {
return when {
......@@ -11,17 +15,57 @@ fun String.plural(count: Int = 1): String {
}
}
fun Friend.smsIntent(): Intent? {
return phone?.let {
val uri = Uri.parse("smsto:${it}")
Intent(Intent.ACTION_SENDTO, uri).apply {
putExtra("sms_body", "Hey ${this@smsIntent.firstName}, how are you?")
fun Context.fetchFriends(): List<Friend> {
val friends = mutableListOf<Friend>()
//TODO: More efficient query using non-null parameters
contentResolver.query(
ContactsContract.CommonDataKinds.Contactables.CONTENT_URI,
null,
null,
null,
null
)?.let {
while (it.moveToNext()) {
mutableMapOf<String, String?>().also { map ->
val indexId = it.getColumnIndex(ContactsContract.Contacts._ID)
val id = it.getLong(indexId)
val photo: Bitmap? = getFriendPhoto(id)
it.columnNames.forEach { name ->
val index = it.getColumnIndex(name)
map[name] = it.getString(index)
}
friends.add(Friend(map, photo))
}
}
it.close()
}
return friends.sortedByDescending { it.timesContacted }
}
fun Friend.callIntent(): Intent? {
return phone?.let {
Intent(Intent.ACTION_DIAL, Uri.parse("tel:${it}"))
private fun Context.getFriendPhoto(id: Long): Bitmap? {
var photo: Bitmap? = null
try {
val inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
contentResolver,
ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
java.lang.Long.valueOf(id)
)
)
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream)
}
inputStream?.close()
} catch (e: IOException) {
e.printStackTrace()
}
println("Photo for $id: $photo")
return photo
}
\ No newline at end of file
package fr.plnech.dunbar.data
import android.content.ContentUris
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.provider.ContactsContract
import fr.plnech.dunbar.model.Friend
import java.io.IOException
package fr.plnech.dunbar.model
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.provider.ContactsContract.Contacts
import java.util.*
......@@ -19,7 +21,7 @@ data class Friend(val map: MutableMap<String, String?>, val photo: Bitmap?) {
get() = map[Contacts._ID]!!.toInt()
val phone: String?
get() = if(map[Contacts.HAS_PHONE_NUMBER] == "1") map["data1"] else null
get() = if (map[Contacts.HAS_PHONE_NUMBER] == "1") map["data1"] else null
val lastTimeStamp = map[Contacts.LAST_TIME_CONTACTED]!!.toLong()
......@@ -34,4 +36,22 @@ data class Friend(val map: MutableMap<String, String?>, val photo: Bitmap?) {
val visibleOutsideSearch: String?
get() = map[Contacts.IN_DEFAULT_DIRECTORY]
}
\ No newline at end of file
fun smsIntent(): Intent? {
return phone?.let {
val uri = Uri.parse("smsto:${it}")
Intent(Intent.ACTION_SENDTO, uri).apply {
putExtra("sms_body", "Hey ${firstName}, how are you?")
}
}
}
fun callIntent(): Intent? {
return phone?.let {
Intent(Intent.ACTION_DIAL, Uri.parse("tel:${it}"))
}
}
}
......@@ -5,7 +5,6 @@ import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import fr.plnech.dunbar.model.Friend
import fr.plnech.dunbar.smsIntent
val CHANNEL_ID = "dunbar"
......
package fr.plnech.dunbar.ui
import android.content.ContentUris
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.provider.ContactsContract
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
......@@ -13,18 +9,19 @@ import androidx.core.app.NotificationManagerCompat
import androidx.recyclerview.widget.LinearLayoutManager
import fr.plnech.dunbar.R
import fr.plnech.dunbar.data.Messages
import fr.plnech.dunbar.fetchFriends
import fr.plnech.dunbar.model.Friend
import fr.plnech.dunbar.notif.FriendReminder
import fr.plnech.dunbar.plural
import kotlinx.android.synthetic.main.activity_friends.*
import kotlinx.android.synthetic.main.content_friends.*
import java.io.IOException
import java.util.*
class FriendsActivity : AppCompatActivity() {
private lateinit var messages: Messages
private val friends = mutableListOf<Friend>()
private var friends = listOf<Friend>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -35,6 +32,7 @@ class FriendsActivity : AppCompatActivity() {
fab.setOnClickListener { view ->
reloadFriends()
notifyFriend()
}
reloadFriends()
......@@ -43,11 +41,23 @@ class FriendsActivity : AppCompatActivity() {
private fun notifyFriend() {
val idNotif = 0
with(NotificationManagerCompat.from(this)) {
val notification =
FriendReminder(applicationContext).createNotification(friends[0], this@FriendsActivity)
notification?.let {
notify(idNotif, notification)
val notRecentlyTalked = friends.filter {
it.lastDate != null && (Date().time - it.lastDate!!.time) > 1 * 60 * 60 * 1000
}
println("${notRecentlyTalked.size} good old friends I could talk to.")
val friend = notRecentlyTalked.minBy { it.timesContacted }
friend?.let {
with(NotificationManagerCompat.from(this)) {
val notification =
FriendReminder(applicationContext).createNotification(
friend,
this@FriendsActivity
)
notification?.let {
notify(idNotif, notification)
}
}
}
}
......@@ -69,7 +79,7 @@ class FriendsActivity : AppCompatActivity() {
}
private fun reloadFriends() {
fetchFriends()
friends = fetchFriends()
displayFriends()
// fetchMessages()
}
......@@ -82,76 +92,15 @@ class FriendsActivity : AppCompatActivity() {
).show()
}
private fun fetchFriends() {
val newFriends = mutableListOf<Friend>()
contentResolver.query(
ContactsContract.CommonDataKinds.Contactables.CONTENT_URI,
null,
null,
null,
null
)?.let {
while (it.moveToNext()) {
mutableMapOf<String, String?>().also { map ->
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)
}
newFriends.add(Friend(map, photo))
}
}
it.close()
friends.clear()
friends.addAll(newFriends)
}
friends.sortBy { it.timesContacted }
}
private fun displayFriends() {
val adapter = FriendsAdapter(friends)
val nbFriends = adapter.itemCount
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()
// }
val nbFriends = adapter.itemCount
welcomeTitle.text = "$nbFriends ${"friend".plural(nbFriends)} on Dunbar"
}
private fun getPhoto(id: Long): Bitmap? {
var photo: Bitmap? = null
try {
val inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
contentResolver,
ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
java.lang.Long.valueOf(id)
)
)
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream)
}
inputStream?.close()
} catch (e: IOException) {
e.printStackTrace()
}
println("Photo for $id: $photo")
return photo
}
}
......@@ -7,9 +7,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import fr.plnech.dunbar.R
import fr.plnech.dunbar.callIntent
import fr.plnech.dunbar.model.Friend
import fr.plnech.dunbar.smsIntent
import kotlinx.android.synthetic.main.contact.view.*
......
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