From b5120d7ec4cd73359379bc7ea693aeeeeebfb7b1 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Mon, 2 Apr 2018 02:06:39 +0200
Subject: [PATCH] Improve reactivity, add nicklist button

---
 .../quasseldroid/ui/chat/ChatActivity.kt      | 56 +++++++++++++++++--
 .../chat/buffers/BufferViewConfigAdapter.kt   | 25 +++------
 .../chat/buffers/BufferViewConfigFragment.kt  | 11 +++-
 .../main/res/drawable/ic_account_multiple.xml |  9 +++
 app/src/main/res/menu/activity_main.xml       |  8 ++-
 app/src/main/res/values-de/strings.xml        |  3 +-
 app/src/main/res/values/strings.xml           |  1 +
 7 files changed, 88 insertions(+), 25 deletions(-)
 create mode 100644 app/src/main/res/drawable/ic_account_multiple.xml

diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
index d5be1e3fc..fb854582a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
@@ -21,12 +21,14 @@ import butterknife.BindView
 import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import com.sothree.slidinguppanel.SlidingUpPanelLayout
+import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.Message
 import de.kuschku.libquassel.protocol.Message_Type
 import de.kuschku.libquassel.protocol.message.HandshakeMessage
 import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
 import de.kuschku.libquassel.session.ConnectionState
 import de.kuschku.libquassel.util.flag.and
+import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.flag.or
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
@@ -46,6 +48,7 @@ import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
 import de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
 import de.kuschku.quasseldroid.viewmodel.data.AutoCompleteItem
+import de.kuschku.quasseldroid.viewmodel.data.BufferData
 import javax.inject.Inject
 
 class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
@@ -158,8 +161,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       historyPanel.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED
     }
     msgHistory.adapter = messageHistoryAdapter
-    viewModel.recentlySentMessages_liveData.observe(this,
-                                                    Observer(messageHistoryAdapter::submitList))
+    viewModel.recentlySentMessages_liveData
+      .observe(this, Observer(messageHistoryAdapter::submitList))
 
     setSupportActionBar(toolbar)
 
@@ -181,6 +184,21 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       drawerToggle.syncState()
     }
 
+    drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
+      override fun onDrawerStateChanged(newState: Int) = Unit
+      override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
+        actionMode?.finish()
+      }
+
+      override fun onDrawerClosed(drawerView: View) {
+        actionMode?.finish()
+      }
+
+      override fun onDrawerOpened(drawerView: View) {
+        actionMode?.finish()
+      }
+    })
+
     viewModel.errors.observe(this, Observer { error ->
       error?.let {
         when (it) {
@@ -262,7 +280,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       }
     })
 
-    viewModel.connectionProgress_liveData.observe(this, Observer { it ->
+    viewModel.connectionProgress_liveData.observe(this, Observer {
       val (state, progress, max) = it ?: Triple(ConnectionState.DISCONNECTED, 0, 0)
       when (state) {
         ConnectionState.CONNECTED,
@@ -284,18 +302,38 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       }
     })
 
+    viewModel.bufferData.distinctUntilChanged().toLiveData().observe(this, Observer {
+      bufferData = it
+      if (bufferData?.info?.type?.hasFlag(Buffer_Type.ChannelBuffer) == true) {
+        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END)
+      } else {
+        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END)
+      }
+
+      invalidateOptionsMenu()
+    })
+
     editorPanel.addPanelSlideListener(panelSlideListener)
     editorPanel.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED
   }
 
+  var bufferData: BufferData? = null
+  var actionMode: ActionMode? = null
+
   override fun onActionModeStarted(mode: ActionMode?) {
     when (mode?.tag) {
       "BUFFER",
       "MESSAGES" -> mode.menu?.retint(toolbar.context)
     }
+    actionMode = mode
     super.onActionModeStarted(mode)
   }
 
+  override fun onActionModeFinished(mode: ActionMode?) {
+    actionMode = null
+    super.onActionModeFinished(mode)
+  }
+
   override fun onStart() {
     if (Settings.autoComplete(this) != autoCompleteSettings) {
       recreate()
@@ -348,6 +386,9 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
   override fun onCreateOptionsMenu(menu: Menu?): Boolean {
     menuInflater.inflate(R.menu.activity_main, menu)
+    menu?.findItem(R.id.action_nicklist)?.isVisible = bufferData?.info?.type?.hasFlag(Buffer_Type.ChannelBuffer) ?: false
+    menu?.findItem(R.id.action_filter_messages)?.isVisible = bufferData != null
+    menu?.retint(toolbar.context)
     return super.onCreateOptionsMenu(menu)
   }
 
@@ -355,7 +396,14 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     android.R.id.home           -> {
       drawerToggle.onOptionsItemSelected(item)
     }
-
+    R.id.action_nicklist        -> {
+      if (drawerLayout.isDrawerVisible(Gravity.END)) {
+        drawerLayout.closeDrawer(Gravity.END)
+      } else {
+        drawerLayout.openDrawer(Gravity.END)
+      }
+      true
+    }
     R.id.action_filter_messages -> {
       runInBackground {
         viewModel.buffer { buffer ->
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt
index df415e13a..8c425e2d0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt
@@ -1,8 +1,5 @@
 package de.kuschku.quasseldroid.ui.chat.buffers
 
-import android.arch.lifecycle.LifecycleOwner
-import android.arch.lifecycle.LiveData
-import android.arch.lifecycle.Observer
 import android.support.v7.widget.RecyclerView
 import android.support.v7.widget.ThemedSpinnerAdapter
 import android.view.LayoutInflater
@@ -16,22 +13,14 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper
 import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter
 
-class BufferViewConfigAdapter(
-  lifecycleOwner: LifecycleOwner,
-  liveData: LiveData<List<BufferViewConfig>?>
-) : RecyclerSpinnerAdapter<BufferViewConfigAdapter.BufferViewConfigViewHolder>(),
-    ThemedSpinnerAdapter {
-  val data = mutableListOf<BufferViewConfig>()
+class BufferViewConfigAdapter :
+  RecyclerSpinnerAdapter<BufferViewConfigAdapter.BufferViewConfigViewHolder>(),
+  ThemedSpinnerAdapter {
+  var data = emptyList<BufferViewConfig>()
 
-  init {
-    liveData.observe(
-      lifecycleOwner, Observer { list: List<BufferViewConfig>? ->
-      data.clear()
-      if (list != null) {
-        data.addAll(list)
-      }
-      notifyDataSetChanged()
-    })
+  fun submitList(list: List<BufferViewConfig>) {
+    data = list
+    notifyDataSetChanged()
   }
 
   override fun isEmpty() = data.isEmpty()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
index a568631db..f1c23c4ff 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
@@ -12,6 +12,7 @@ import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.Buffer_Activity
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.Message_Type
+import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.flag.minus
@@ -20,6 +21,7 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.QuasselDatabase
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
+import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.map
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.helper.zip
@@ -169,7 +171,14 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
     val view = inflater.inflate(R.layout.fragment_chat_list, container, false)
     ButterKnife.bind(this, view)
 
-    val adapter = BufferViewConfigAdapter(this, viewModel.bufferViewConfigs.toLiveData())
+    val adapter = BufferViewConfigAdapter()
+    viewModel.bufferViewConfigs.switchMap {
+      combineLatest(it.map(BufferViewConfig::liveUpdates))
+    }.toLiveData().observe(this, Observer {
+      if (it != null) {
+        adapter.submitList(it)
+      }
+    })
 
     chatListSpinner.adapter = adapter
     chatListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
diff --git a/app/src/main/res/drawable/ic_account_multiple.xml b/app/src/main/res/drawable/ic_account_multiple.xml
new file mode 100644
index 000000000..b08b58c33
--- /dev/null
+++ b/app/src/main/res/drawable/ic_account_multiple.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+  android:width="24dp"
+  android:height="24dp"
+  android:viewportHeight="24"
+  android:viewportWidth="24">
+  <path
+    android:fillColor="#000"
+    android:pathData="M16,13C15.71,13 15.38,13 15.03,13.05C16.19,13.89 17,15 17,16.5V19H23V16.5C23,14.17 18.33,13 16,13M8,13C5.67,13 1,14.17 1,16.5V19H15V16.5C15,14.17 10.33,13 8,13M8,11A3,3 0 0,0 11,8A3,3 0 0,0 8,5A3,3 0 0,0 5,8A3,3 0 0,0 8,11M16,11A3,3 0 0,0 19,8A3,3 0 0,0 16,5A3,3 0 0,0 13,8A3,3 0 0,0 16,11Z" />
+</vector>
diff --git a/app/src/main/res/menu/activity_main.xml b/app/src/main/res/menu/activity_main.xml
index 31588b1be..04af1c3eb 100644
--- a/app/src/main/res/menu/activity_main.xml
+++ b/app/src/main/res/menu/activity_main.xml
@@ -1,5 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:app="http://schemas.android.com/apk/res-auto">
+  <item
+    android:id="@+id/action_nicklist"
+    android:icon="@drawable/ic_account_multiple"
+    android:title="@string/label_nicklist"
+    app:showAsAction="always" />
   <item
     android:id="@+id/action_filter_messages"
     android:title="@string/label_filter_messages" />
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index e8c655bd0..503ddec9a 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -37,6 +37,7 @@
   <string name="label_new_identity">Identität hinzufügen</string>
   <string name="label_new_network">Netzwerk hinzufügen</string>
   <string name="label_new_nick">Spitzname hinzufügen</string>
+  <string name="label_nicklist">Benutzerliste</string>
   <string name="label_no">Nein</string>
   <string name="label_reset">Zurücksetzen</string>
   <string name="label_open">Öffnen</string>
@@ -59,4 +60,4 @@
   <string name="notification_channel_highlight_title">Erwähnungen</string>
 
   <string name="buffer_delete_confirmation">Bist du sicher, dass du diesen Chat auf ewig löschen möchtest?</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5ced578d3..64d745e20 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -37,6 +37,7 @@
   <string name="label_new_identity">New Identity</string>
   <string name="label_new_network">New Network</string>
   <string name="label_new_nick">New Nick</string>
+  <string name="label_nicklist">Nick List</string>
   <string name="label_no">No</string>
   <string name="label_reset">Reset</string>
   <string name="label_open">Open</string>
-- 
GitLab