From 22bed19d904385740c5230261411e468255c463c Mon Sep 17 00:00:00 2001
From: Konrad Pozniak <connyduck@users.noreply.github.com>
Date: Sun, 7 Mar 2021 19:06:05 +0100
Subject: [PATCH] migrating to ViewBinding part 3: EmojiPreference (#2094)

---
 .../components/preference/EmojiPreference.kt  | 145 ++++++++----------
 .../tusky/util/EmojiCompatFont.kt             |   8 +-
 app/src/main/res/layout/item_emoji_pref.xml   |  33 ++--
 3 files changed, 83 insertions(+), 103 deletions(-)

diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/EmojiPreference.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/EmojiPreference.kt
index c0e538a9..2d32723f 100644
--- a/app/src/main/java/com/keylesspalace/tusky/components/preference/EmojiPreference.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/EmojiPreference.kt
@@ -8,14 +8,23 @@ import android.os.Build
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
-import android.widget.*
+import android.widget.RadioButton
+import android.widget.Toast
 import androidx.appcompat.app.AlertDialog
 import androidx.preference.Preference
 import androidx.preference.PreferenceManager
 import com.keylesspalace.tusky.R
 import com.keylesspalace.tusky.SplashActivity
+import com.keylesspalace.tusky.databinding.DialogEmojicompatBinding
+import com.keylesspalace.tusky.databinding.ItemEmojiPrefBinding
 import com.keylesspalace.tusky.util.EmojiCompatFont
+import com.keylesspalace.tusky.util.EmojiCompatFont.Companion.BLOBMOJI
 import com.keylesspalace.tusky.util.EmojiCompatFont.Companion.FONTS
+import com.keylesspalace.tusky.util.EmojiCompatFont.Companion.NOTOEMOJI
+import com.keylesspalace.tusky.util.EmojiCompatFont.Companion.SYSTEM_DEFAULT
+import com.keylesspalace.tusky.util.EmojiCompatFont.Companion.TWEMOJI
+import com.keylesspalace.tusky.util.hide
+import com.keylesspalace.tusky.util.show
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import okhttp3.OkHttpClient
@@ -50,94 +59,85 @@ class EmojiPreference(
     }
 
     override fun onClick() {
-        val view = LayoutInflater.from(context).inflate(R.layout.dialog_emojicompat, null)
-        viewIds.forEachIndexed { index, viewId ->
-            setupItem(view.findViewById(viewId), FONTS[index])
-        }
+        val binding = DialogEmojicompatBinding.inflate(LayoutInflater.from(context))
+
+        setupItem(BLOBMOJI, binding.itemBlobmoji)
+        setupItem(TWEMOJI, binding.itemTwemoji)
+        setupItem(NOTOEMOJI, binding.itemNotoemoji)
+        setupItem(SYSTEM_DEFAULT, binding.itemNomoji)
+
         AlertDialog.Builder(context)
-                .setView(view)
+                .setView(binding.root)
                 .setPositiveButton(android.R.string.ok) { _, _ -> onDialogOk() }
                 .setNegativeButton(android.R.string.cancel, null)
                 .show()
     }
 
-    private fun setupItem(container: View, font: EmojiCompatFont) {
-        val title: TextView = container.findViewById(R.id.emojicompat_name)
-        val caption: TextView = container.findViewById(R.id.emojicompat_caption)
-        val thumb: ImageView = container.findViewById(R.id.emojicompat_thumb)
-        val download: ImageButton = container.findViewById(R.id.emojicompat_download)
-        val cancel: ImageButton = container.findViewById(R.id.emojicompat_download_cancel)
-        val radio: RadioButton = container.findViewById(R.id.emojicompat_radio)
-
+    private fun setupItem(font: EmojiCompatFont, binding: ItemEmojiPrefBinding) {
         // Initialize all the views
-        title.text = font.getDisplay(container.context)
-        caption.setText(font.caption)
-        thumb.setImageResource(font.img)
+        binding.emojiName.text = font.getDisplay(context)
+        binding.emojiCaption.setText(font.caption)
+        binding.emojiThumbnail.setImageResource(font.img)
 
         // There needs to be a list of all the radio buttons in order to uncheck them when one is selected
-        radioButtons.add(radio)
-        updateItem(font, container)
+        radioButtons.add(binding.emojiRadioButton)
+        updateItem(font, binding)
 
         // Set actions
-        download.setOnClickListener { startDownload(font, container) }
-        cancel.setOnClickListener { cancelDownload(font, container) }
-        radio.setOnClickListener { radioButton: View -> select(font, radioButton as RadioButton) }
-        container.setOnClickListener { containerView: View ->
-            select(font, containerView.findViewById(R.id.emojicompat_radio))
+        binding.emojiDownload.setOnClickListener { startDownload(font, binding) }
+        binding.emojiDownloadCancel.setOnClickListener { cancelDownload(font, binding) }
+        binding.emojiRadioButton.setOnClickListener { radioButton: View -> select(font, radioButton as RadioButton) }
+        binding.root.setOnClickListener {
+            select(font, binding.emojiRadioButton)
         }
     }
 
-    private fun startDownload(font: EmojiCompatFont, container: View) {
-        val download: ImageButton = container.findViewById(R.id.emojicompat_download)
-        val caption: TextView = container.findViewById(R.id.emojicompat_caption)
-        val progressBar: ProgressBar = container.findViewById(R.id.emojicompat_progress)
-        val cancel: ImageButton = container.findViewById(R.id.emojicompat_download_cancel)
-
+    private fun startDownload(font: EmojiCompatFont, binding: ItemEmojiPrefBinding) {
         // Switch to downloading style
-        download.visibility = View.GONE
-        caption.visibility = View.INVISIBLE
-        progressBar.visibility = View.VISIBLE
-        progressBar.progress = 0
-        cancel.visibility = View.VISIBLE
+        binding.emojiDownload.hide()
+        binding.emojiCaption.visibility = View.INVISIBLE
+        binding.emojiProgress.show()
+        binding.emojiProgress.progress = 0
+        binding.emojiDownloadCancel.show()
         font.downloadFontFile(context, okHttpClient)
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(
                         { progress ->
                             // The progress is returned as a float between 0 and 1, or -1 if it could not determined
                             if (progress >= 0) {
-                                progressBar.isIndeterminate = false
-                                val max = progressBar.max.toFloat()
+                                binding.emojiProgress.isIndeterminate = false
+                                val max = binding.emojiProgress.max.toFloat()
                                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                                    progressBar.setProgress((max * progress).toInt(), true)
+                                    binding.emojiProgress.setProgress((max * progress).toInt(), true)
                                 } else {
-                                    progressBar.progress = (max * progress).toInt()
+                                    binding.emojiProgress.progress = (max * progress).toInt()
                                 }
                             } else {
-                                progressBar.isIndeterminate = true
+                                binding.emojiProgress.isIndeterminate = true
                             }
                         },
                         {
                             Toast.makeText(context, R.string.download_failed, Toast.LENGTH_SHORT).show()
-                            updateItem(font, container)
+                            updateItem(font, binding)
                         },
                         {
-                            finishDownload(font, container)
+                            finishDownload(font, binding)
                         }
                 ).also { downloadDisposables[font.id] = it }
 
 
     }
 
-    private fun cancelDownload(font: EmojiCompatFont, container: View) {
-        font.deleteDownloadedFile(container.context)
+    private fun cancelDownload(font: EmojiCompatFont, binding: ItemEmojiPrefBinding) {
+        font.deleteDownloadedFile(context)
         downloadDisposables[font.id]?.dispose()
         downloadDisposables[font.id] = null
-        updateItem(font, container)
+        updateItem(font, binding)
     }
 
-    private fun finishDownload(font: EmojiCompatFont, container: View) {
-        select(font, container.findViewById(R.id.emojicompat_radio))
-        updateItem(font, container)
+    private fun finishDownload(font: EmojiCompatFont, binding: ItemEmojiPrefBinding) {
+        select(font, binding.emojiRadioButton)
+        updateItem(font, binding)
         // Set the flag to restart the app (because an update has been downloaded)
         if (selected === original && currentNeedsUpdate) {
             updated = true
@@ -153,54 +153,43 @@ class EmojiPreference(
      */
     private fun select(font: EmojiCompatFont, radio: RadioButton) {
         selected = font
-        // Uncheck all the other buttons
-        for (other in radioButtons) {
-            if (other !== radio) {
-                other.isChecked = false
-            }
+        radioButtons.forEach { radioButton ->
+            radioButton.isChecked = radioButton == radio
         }
-        radio.isChecked = true
     }
 
     /**
      * Called when a "consistent" state is reached, i.e. it's not downloading the font
      *
      * @param font      The font to be displayed
-     * @param container The ConstraintLayout containing the item
+     * @param binding The ItemEmojiPrefBinding to show the item in
      */
-    private fun updateItem(font: EmojiCompatFont, container: View) {
-        // Assignments
-        val download: ImageButton = container.findViewById(R.id.emojicompat_download)
-        val caption: TextView = container.findViewById(R.id.emojicompat_caption)
-        val progress: ProgressBar = container.findViewById(R.id.emojicompat_progress)
-        val cancel: ImageButton = container.findViewById(R.id.emojicompat_download_cancel)
-        val radio: RadioButton = container.findViewById(R.id.emojicompat_radio)
-
+    private fun updateItem(font: EmojiCompatFont, binding: ItemEmojiPrefBinding) {
         // There's no download going on
-        progress.visibility = View.GONE
-        cancel.visibility = View.GONE
-        caption.visibility = View.VISIBLE
+        binding.emojiProgress.hide()
+        binding.emojiDownloadCancel.hide()
+        binding.emojiCaption.show()
         if (font.isDownloaded(context)) {
             // Make it selectable
-            download.visibility = View.GONE
-            radio.visibility = View.VISIBLE
-            container.isClickable = true
+            binding.emojiDownload.hide()
+            binding.emojiRadioButton.show()
+            binding.root.isClickable = true
         } else {
             // Make it downloadable
-            download.visibility = View.VISIBLE
-            radio.visibility = View.GONE
-            container.isClickable = false
+            binding.emojiDownload.show()
+            binding.emojiRadioButton.hide()
+            binding.root.isClickable = false
         }
 
         // Select it if necessary
         if (font === selected) {
-            radio.isChecked = true
+            binding.emojiRadioButton.isChecked = true
             // Update available
             if (!font.isDownloaded(context)) {
                 currentNeedsUpdate = true
             }
         } else {
-            radio.isChecked = false
+            binding.emojiRadioButton.isChecked = false
         }
     }
 
@@ -246,13 +235,5 @@ class EmojiPreference(
 
     companion object {
         private const val TAG = "EmojiPreference"
-
-        // Please note that this array must sorted in the same way as the fonts.
-        private val viewIds = intArrayOf(
-                R.id.item_nomoji,
-                R.id.item_blobmoji,
-                R.id.item_twemoji,
-                R.id.item_notoemoji
-        )
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/EmojiCompatFont.kt b/app/src/main/java/com/keylesspalace/tusky/util/EmojiCompatFont.kt
index 4697a1e9..d0a0e443 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/EmojiCompatFont.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/util/EmojiCompatFont.kt
@@ -256,27 +256,27 @@ class EmojiCompatFont(
         private const val CHUNK_SIZE = 4096L
 
         // The system font gets some special behavior...
-        private val SYSTEM_DEFAULT = EmojiCompatFont("system-default",
+        val SYSTEM_DEFAULT = EmojiCompatFont("system-default",
                 "System Default",
                 R.string.caption_systememoji,
                 R.drawable.ic_emoji_34dp,
                 "",
                 "0")
-        private val BLOBMOJI = EmojiCompatFont("Blobmoji",
+        val BLOBMOJI = EmojiCompatFont("Blobmoji",
                 "Blobmoji",
                 R.string.caption_blobmoji,
                 R.drawable.ic_blobmoji,
                 "https://tusky.app/hosted/emoji/BlobmojiCompat.ttf",
                 "12.0.0"
         )
-        private val TWEMOJI = EmojiCompatFont("Twemoji",
+        val TWEMOJI = EmojiCompatFont("Twemoji",
                 "Twemoji",
                 R.string.caption_twemoji,
                 R.drawable.ic_twemoji,
                 "https://tusky.app/hosted/emoji/TwemojiCompat.ttf",
                 "12.0.0"
         )
-        private val NOTOEMOJI = EmojiCompatFont("NotoEmoji",
+        val NOTOEMOJI = EmojiCompatFont("NotoEmoji",
                 "Noto Emoji",
                 R.string.caption_notoemoji,
                 R.drawable.ic_notoemoji,
diff --git a/app/src/main/res/layout/item_emoji_pref.xml b/app/src/main/res/layout/item_emoji_pref.xml
index d8755a3d..a10a5ffe 100644
--- a/app/src/main/res/layout/item_emoji_pref.xml
+++ b/app/src/main/res/layout/item_emoji_pref.xml
@@ -2,7 +2,6 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/emojicompat_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="?attr/selectableItemBackground"
@@ -11,7 +10,7 @@
 
     <!--This is a thumbnail picture-->
     <ImageView
-        android:id="@+id/emojicompat_thumb"
+        android:id="@+id/emojiThumbnail"
         android:layout_width="42dp"
         android:layout_height="42dp"
         android:layout_marginStart="16dp"
@@ -25,22 +24,22 @@
 
     <!--This is the font's name-->
     <TextView
-        android:id="@+id/emojicompat_name"
+        android:id="@+id/emojiName"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginStart="12dp"
         android:layout_marginEnd="72dp"
         android:textColor="?android:textColorPrimary"
         android:textSize="?attr/status_text_medium"
-        app:layout_constraintBottom_toTopOf="@+id/emojicompat_caption"
+        app:layout_constraintBottom_toTopOf="@+id/emojiCaption"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/emojicompat_thumb"
+        app:layout_constraintStart_toEndOf="@+id/emojiThumbnail"
         app:layout_constraintTop_toTopOf="parent"
         tools:text="@string/system_default" />
 
     <!--A short caption…-->
     <TextView
-        android:id="@+id/emojicompat_caption"
+        android:id="@+id/emojiCaption"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginEnd="72dp"
@@ -49,14 +48,14 @@
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintHorizontal_bias="0"
-        app:layout_constraintStart_toStartOf="@id/emojicompat_name"
-        app:layout_constraintTop_toBottomOf="@id/emojicompat_name"
+        app:layout_constraintStart_toStartOf="@id/emojiName"
+        app:layout_constraintTop_toBottomOf="@id/emojiName"
         app:layout_constraintVertical_chainStyle="packed"
         tools:text="@string/caption_blobmoji" />
 
     <!--This progress bar is shown while the font is downloading.-->
     <ProgressBar
-        android:id="@+id/emojicompat_progress"
+        android:id="@+id/emojiProgress"
         style="?android:attr/progressBarStyleHorizontal"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -65,12 +64,12 @@
         android:indeterminate="false"
         android:visibility="gone"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="@id/emojicompat_name"
-        app:layout_constraintTop_toBottomOf="@id/emojicompat_name" />
+        app:layout_constraintStart_toStartOf="@id/emojiName"
+        app:layout_constraintTop_toBottomOf="@id/emojiName" />
 
     <!--Click on it and the font will be downloaded!-->
     <ImageButton
-        android:id="@+id/emojicompat_download"
+        android:id="@+id/emojiDownload"
         android:layout_width="42dp"
         android:layout_height="42dp"
         android:background="?attr/selectableItemBackgroundBorderless"
@@ -80,13 +79,13 @@
         android:visibility="gone"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/emojicompat_caption"
+        app:layout_constraintStart_toEndOf="@id/emojiCaption"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_file_download_black_24dp" />
 
     <!--You should be able to cancel the download-->
     <ImageButton
-        android:id="@+id/emojicompat_download_cancel"
+        android:id="@+id/emojiDownloadCancel"
         android:layout_width="42dp"
         android:layout_height="42dp"
         android:background="?attr/selectableItemBackgroundBorderless"
@@ -96,20 +95,20 @@
         android:visibility="gone"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/emojicompat_name"
+        app:layout_constraintStart_toEndOf="@id/emojiName"
         app:layout_constraintTop_toTopOf="parent"
         app:srcCompat="@drawable/ic_cancel_24dp" />
 
     <!--You'll probably want to select an emoji font, don't you?-->
     <androidx.appcompat.widget.AppCompatRadioButton
-        android:id="@+id/emojicompat_radio"
+        android:id="@+id/emojiRadioButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:visibility="visible"
         app:buttonTint="@color/compound_button_color"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/emojicompat_name"
+        app:layout_constraintStart_toEndOf="@id/emojiName"
         app:layout_constraintTop_toTopOf="parent" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file