refactor: Extract methods to right place

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