diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2332e1e..c0f04bd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -12,10 +13,13 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + tools:ignore="GoogleAppIndexingWarning"> + + + android:value="fr.plnech.dunbar.FriendListActivity" /> @@ -25,32 +25,18 @@ class BuddyDetailActivity : AppCompatActivity() { .setAction("Action", null).show() } - // Show the Up button in the action bar. supportActionBar?.setDisplayHomeAsUpEnabled(true) - // savedInstanceState is non-null when there is fragment state - // saved from previous configurations of this activity - // (e.g. when rotating the screen from portrait to landscape). - // In this case, the fragment will automatically be re-added - // to its container so we don't need to manually add it. - // For more information, see the Fragments API guide at: - // - // http://developer.android.com/guide/components/fragments.html - // if (savedInstanceState == null) { - // Create the detail fragment and add it to the activity - // using a fragment transaction. - val fragment = BuddyDetailFragment().apply { - arguments = Bundle().apply { - putString( - BuddyDetailFragment.ARG_ITEM_ID, - intent.getStringExtra(BuddyDetailFragment.ARG_ITEM_ID) - ) - } - } - supportFragmentManager.beginTransaction() - .add(R.id.buddy_detail_container, fragment) + .add(R.id.friend_detail_container, FriendDetailFragment().apply { + arguments = Bundle().apply { + putString( + FriendDetailFragment.ARG_ITEM_ID, + intent.getStringExtra(FriendDetailFragment.ARG_ITEM_ID) + ) + } + }) .commit() } } @@ -58,13 +44,7 @@ class BuddyDetailActivity : AppCompatActivity() { override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { android.R.id.home -> { - // This ID represents the Home or Up button. In the case of this - // activity, the Up button is shown. For - // more details, see the Navigation pattern on Android Design: - // - // http://developer.android.com/design/patterns/navigation.html#up-vs-back - - navigateUpTo(Intent(this, BuddyListActivity::class.java)) + navigateUpTo(Intent(this, FriendListActivity::class.java)) true } else -> super.onOptionsItemSelected(item) diff --git a/app/src/main/java/fr/plnech/dunbar/FriendDetailFragment.kt b/app/src/main/java/fr/plnech/dunbar/FriendDetailFragment.kt index be535f3..7c3f482 100644 --- a/app/src/main/java/fr/plnech/dunbar/FriendDetailFragment.kt +++ b/app/src/main/java/fr/plnech/dunbar/FriendDetailFragment.kt @@ -7,16 +7,16 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import fr.plnech.dunbar.dummy.DummyContent import fr.plnech.dunbar.model.Friend -import kotlinx.android.synthetic.main.activity_buddy_detail.* -import kotlinx.android.synthetic.main.buddy_detail.view.* +import kotlinx.android.synthetic.main.activity_friend_detail.* +import kotlinx.android.synthetic.main.friend_detail.view.* /** - * A fragment representing a single Buddy detail screen. + * A fragment representing a single Friend detail screen. * This fragment is either contained in a [FriendListActivity] * in two-pane mode (on tablets) or a [FriendDetailActivity] * on handsets. */ -class BuddyDetailFragment : Fragment() { +class FriendDetailFragment : Fragment() { /** * The dummy content this fragment is presenting. @@ -41,11 +41,11 @@ class BuddyDetailFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - val rootView = inflater.inflate(R.layout.buddy_detail, container, false) + val rootView = inflater.inflate(R.layout.friend_detail, container, false) // Show the dummy content as text in a TextView. item?.let { - rootView.buddy_detail.text = it.mapString() + rootView.friend_detail.text = it.mapString() activity?.title = it.name } diff --git a/app/src/main/java/fr/plnech/dunbar/FriendListActivity.kt b/app/src/main/java/fr/plnech/dunbar/FriendListActivity.kt index 975d13f..adaa4fb 100644 --- a/app/src/main/java/fr/plnech/dunbar/FriendListActivity.kt +++ b/app/src/main/java/fr/plnech/dunbar/FriendListActivity.kt @@ -13,11 +13,11 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar import fr.plnech.dunbar.dummy.DummyContent import fr.plnech.dunbar.model.Friend -import kotlinx.android.synthetic.main.activity_buddy_list.* -import kotlinx.android.synthetic.main.buddy_list.* -import kotlinx.android.synthetic.main.buddy_list_content.view.* +import kotlinx.android.synthetic.main.activity_friends_list.* +import kotlinx.android.synthetic.main.friend_list.* +import kotlinx.android.synthetic.main.friend_list_content.view.* -class BuddyListActivity : AppCompatActivity() { +class FriendListActivity : AppCompatActivity() { /** * Whether or not the activity is in two-pane mode, i.e. running on a tablet @@ -27,7 +27,7 @@ class BuddyListActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_buddy_list) + setContentView(R.layout.activity_friends_list) setSupportActionBar(toolbar) toolbar.title = title @@ -39,7 +39,7 @@ class BuddyListActivity : AppCompatActivity() { // Show the Up button in the action bar. supportActionBar?.setDisplayHomeAsUpEnabled(true) - if (buddy_detail_container != null) { + if (friend_detail_container != null) { // The detail container view will be present only in the // large-screen layouts (res/values-w900dp). // If this view is present, then the @@ -47,7 +47,7 @@ class BuddyListActivity : AppCompatActivity() { twoPane = true } - setupRecyclerView(buddy_list) + setupRecyclerView(friend_list) } override fun onOptionsItemSelected(item: MenuItem) = @@ -64,7 +64,7 @@ class BuddyListActivity : AppCompatActivity() { } class SimpleItemRecyclerViewAdapter( - private val parentActivity: BuddyListActivity, + private val parentActivity: FriendListActivity, private val values: List, private val twoPane: Boolean ) : @@ -76,18 +76,18 @@ class BuddyListActivity : AppCompatActivity() { onClickListener = View.OnClickListener { v -> val item = v.tag as Friend if (twoPane) { - val fragment = BuddyDetailFragment().apply { + val fragment = FriendDetailFragment().apply { arguments = Bundle().apply { - putString(BuddyDetailFragment.ARG_ITEM_ID, "friend_${item.id}") + putString(FriendDetailFragment.ARG_ITEM_ID, "friend_${item.id}") } } parentActivity.supportFragmentManager .beginTransaction() - .replace(R.id.buddy_detail_container, fragment) + .replace(R.id.friend_detail_container, fragment) .commit() } else { - val intent = Intent(v.context, BuddyDetailActivity::class.java).apply { - putExtra(BuddyDetailFragment.ARG_ITEM_ID, "friend_${item.id}") + val intent = Intent(v.context, FriendDetailActivity::class.java).apply { + putExtra(FriendDetailFragment.ARG_ITEM_ID, "friend_${item.id}") } v.context.startActivity(intent) } @@ -96,7 +96,7 @@ class BuddyListActivity : AppCompatActivity() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) - .inflate(R.layout.buddy_list_content, parent, false) + .inflate(R.layout.friend_list_content, parent, false) return ViewHolder(view) } diff --git a/app/src/main/java/fr/plnech/dunbar/data/Messages.kt b/app/src/main/java/fr/plnech/dunbar/data/Messages.kt index 446761a..929afc6 100644 --- a/app/src/main/java/fr/plnech/dunbar/data/Messages.kt +++ b/app/src/main/java/fr/plnech/dunbar/data/Messages.kt @@ -1,5 +1,6 @@ package fr.plnech.dunbar.data +import android.annotation.SuppressLint import android.content.Context import android.net.Uri import android.provider.Telephony @@ -16,6 +17,7 @@ class Messages(context: Context) { sent = fetchMessages(Telephony.Sms.Sent.CONTENT_URI) } + @SuppressLint("Recycle") // Cursor is recycled when nonnull private fun fetchMessages(uri: Uri): MutableList> { val messages = mutableListOf>() @@ -41,7 +43,6 @@ class Messages(context: Context) { } else { println("Null cursor.") } - } return messages } diff --git a/app/src/main/java/fr/plnech/dunbar/model/Friend.kt b/app/src/main/java/fr/plnech/dunbar/model/Friend.kt index 21d9389..d7501e7 100644 --- a/app/src/main/java/fr/plnech/dunbar/model/Friend.kt +++ b/app/src/main/java/fr/plnech/dunbar/model/Friend.kt @@ -18,7 +18,7 @@ data class Friend(val map: Map = mutableMapOf(), val photo: Bit get() = name?.split(Regex("\\s"))?.firstOrNull() val id: Int - get() = map[Contacts._ID]!!.toInt() + get() = (map[Contacts._ID] ?: error("No id for friend $name")).toInt() val phone: String? get() = if (map[Contacts.HAS_PHONE_NUMBER] == "1") map["data1"] else null diff --git a/app/src/main/java/fr/plnech/dunbar/notif/FriendReminder.kt b/app/src/main/java/fr/plnech/dunbar/notif/FriendReminder.kt index 7432922..7d42775 100644 --- a/app/src/main/java/fr/plnech/dunbar/notif/FriendReminder.kt +++ b/app/src/main/java/fr/plnech/dunbar/notif/FriendReminder.kt @@ -7,11 +7,11 @@ import androidx.core.app.NotificationCompat import fr.plnech.dunbar.model.Friend -val CHANNEL_ID = "dunbar" +const val CHANNEL_ID = "dunbar" -class FriendReminder(val ctx: Context) { +class FriendReminder(private val ctx: Context) { - var channelCreated = false + private var channelCreated = false private fun createNotificationChannel() { // Create the NotificationChannel, but only on API 26+ because diff --git a/app/src/main/java/fr/plnech/dunbar/ui/ContactsActivity.kt b/app/src/main/java/fr/plnech/dunbar/ui/ContactsActivity.kt index 4717ba7..a3aadba 100644 --- a/app/src/main/java/fr/plnech/dunbar/ui/ContactsActivity.kt +++ b/app/src/main/java/fr/plnech/dunbar/ui/ContactsActivity.kt @@ -8,14 +8,14 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NotificationManagerCompat import androidx.recyclerview.widget.LinearLayoutManager -import fr.plnech.dunbar.BuddyListActivity +import fr.plnech.dunbar.FriendListActivity 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.activity_contacts.* import kotlinx.android.synthetic.main.content_friends.* import java.util.* @@ -27,7 +27,7 @@ class FriendsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_friends) + setContentView(R.layout.activity_contacts) setSupportActionBar(toolbar) // messages = Messages(applicationContext) @@ -42,7 +42,7 @@ class FriendsActivity : AppCompatActivity() { } private fun notifyFriend() { - val idNotif = 0 + val idNotification = 0 val notRecentlyTalked = friends.filter { it.lastDate != null && (Date().time - it.lastDate!!.time) > 1 * 60 * 60 * 1000 } @@ -58,7 +58,7 @@ class FriendsActivity : AppCompatActivity() { this@FriendsActivity ) notification?.let { - notify(idNotif, notification) + notify(idNotification, notification) } } } @@ -76,8 +76,8 @@ class FriendsActivity : AppCompatActivity() { // as you specify a parent activity in AndroidManifest.xml. return when (item.itemId) { R.id.action_settings -> true - R.id.action_buddies -> { - startActivity(Intent(this, BuddyListActivity::class.java)) + R.id.action_friends -> { + startActivity(Intent(this, FriendListActivity::class.java)) true } else -> super.onOptionsItemSelected(item) @@ -106,7 +106,7 @@ class FriendsActivity : AppCompatActivity() { friendsList.layoutManager = LinearLayoutManager(this) friendsList.setHasFixedSize(true) friendsList.adapter = adapter - welcomeTitle.text = "$nbFriends ${"friend".plural(nbFriends)} on Dunbar" + welcomeTitle.text = getString(R.string.text_welcome).format(nbFriends, "friend".plural(nbFriends)) } } diff --git a/app/src/main/java/fr/plnech/dunbar/ui/FriendsAdapter.kt b/app/src/main/java/fr/plnech/dunbar/ui/FriendsAdapter.kt index b78dd63..c57213b 100644 --- a/app/src/main/java/fr/plnech/dunbar/ui/FriendsAdapter.kt +++ b/app/src/main/java/fr/plnech/dunbar/ui/FriendsAdapter.kt @@ -17,11 +17,7 @@ class FriendsAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FriendsViewHolder = FriendsViewHolder( - LayoutInflater.from(parent.context).inflate( - viewType, - parent, - false - ) + LayoutInflater.from(parent.context).inflate(viewType, parent, false) ) override fun getItemCount(): Int = friends.size @@ -43,35 +39,12 @@ class FriendsViewHolder(private val view: View) : RecyclerView.ViewHolder(view) fun bind(friend: Friend) { name.text = friend.name data.text = buildDataString(friend) - bindPhone(friend) + bindPhone(friend) bindPic(friend) bindClick(friend) } - private fun buildDataString(friend: Friend): String { - return buildString { - if (friend.lastDate != null) { - append(friend.timesContacted) - append(" interactions, last ") - append(DateUtils.getRelativeTimeSpanString(friend.lastTimeStamp)) - } else { - append("Never interacted") - } - } - } - - private fun bindClick(friend: Friend) { - view.setOnClickListener { - Toast.makeText(view.context, friend.mapString(), Toast.LENGTH_LONG).show() - println(friend.mapString()) - } - } - - private fun bindPic(friend: Friend) { - pic.setImageBitmap(friend.photo) - } - private fun bindPhone(friend: Friend) { friend.phone?.let { phone.text = it @@ -90,4 +63,27 @@ class FriendsViewHolder(private val view: View) : RecyclerView.ViewHolder(view) } } + private fun bindPic(friend: Friend) { + pic.setImageBitmap(friend.photo) + } + + private fun bindClick(friend: Friend) { + view.setOnClickListener { + Toast.makeText(view.context, friend.mapString(), Toast.LENGTH_LONG).show() + println(friend.mapString()) + } + } + + private fun buildDataString(friend: Friend): String { + return buildString { + if (friend.lastDate != null) { + append(friend.timesContacted) + append(" interactions, last ") + append(DateUtils.getRelativeTimeSpanString(friend.lastTimeStamp)) + } else { + append("Never interacted") + } + } + } + } diff --git a/app/src/main/res/layout-w900dp/buddy_list.xml b/app/src/main/res/layout-w900dp/friend_list.xml similarity index 80% rename from app/src/main/res/layout-w900dp/buddy_list.xml rename to app/src/main/res/layout-w900dp/friend_list.xml index 1a453ac..f5abd42 100644 --- a/app/src/main/res/layout-w900dp/buddy_list.xml +++ b/app/src/main/res/layout-w900dp/friend_list.xml @@ -10,28 +10,28 @@ android:divider="?android:attr/dividerHorizontal" android:orientation="horizontal" android:showDividers="middle" - tools:context=".BuddyListActivity"> + tools:context=".FriendListActivity"> + tools:context="fr.plnech.dunbar.FriendListActivity" + tools:listitem="@layout/friend_list_content" /> diff --git a/app/src/main/res/layout/activity_friend_detail.xml b/app/src/main/res/layout/activity_friend_detail.xml index b1db4c5..58e009d 100644 --- a/app/src/main/res/layout/activity_friend_detail.xml +++ b/app/src/main/res/layout/activity_friend_detail.xml @@ -36,7 +36,7 @@ @@ -47,7 +47,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical|start" android:layout_margin="@dimen/fab_margin" - app:layout_anchor="@+id/buddy_detail_container" + app:layout_anchor="@+id/friend_detail_container" app:layout_anchorGravity="top|end" app:srcCompat="@android:drawable/stat_notify_chat" /> diff --git a/app/src/main/res/layout/friend_detail.xml b/app/src/main/res/layout/friend_detail.xml index d4374f4..80052c8 100644 --- a/app/src/main/res/layout/friend_detail.xml +++ b/app/src/main/res/layout/friend_detail.xml @@ -1,7 +1,7 @@ Dunbar Updates about friends you don\'t want to forget Settings - Buddies - Buddies - Buddy Detail + Friends + Friends + Friend Detail + "%1$d %2$s on Dunbar"