From 0d6967bc5a1540cdf787e7d47d593000523e36fe Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Mon, 26 Mar 2018 13:40:42 +0200
Subject: [PATCH] Implements improved autocomplete

---
 .../quasseldroid/dagger/SettingsModule.kt     | 27 +++++++++++++---
 .../settings/AppearanceSettings.kt            |  1 -
 .../settings/AutoCompleteSettings.kt          | 12 +++++++
 .../kuschku/quasseldroid/settings/Settings.kt |  4 ---
 .../quasseldroid/ui/chat/ChatActivity.kt      |  1 +
 .../quasseldroid/ui/chat/input/Editor.kt      | 31 +++++++++++++++---
 .../ui/chat/input/FormatHandler.kt            |  4 ++-
 .../util/service/ServiceBoundActivity.kt      |  4 +++
 .../res/values-de/strings_preferences.xml     | 14 +++++++-
 .../main/res/values/strings_preferences.xml   | 19 +++++++++--
 app/src/main/res/xml/preferences.xml          | 32 ++++++++++++++++---
 11 files changed, 126 insertions(+), 23 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/settings/AutoCompleteSettings.kt

diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
index 0441232d6..e2fae088e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
@@ -5,6 +5,7 @@ import dagger.Module
 import dagger.Provides
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
+import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.settings.BacklogSettings
 import de.kuschku.quasseldroid.settings.ConnectionSettings
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
@@ -58,10 +59,6 @@ class SettingsModule {
         context.getString(R.string.preference_colorize_mirc_key),
         AppearanceSettings.DEFAULT.colorizeMirc
       ),
-      showAutocomplete = getBoolean(
-        context.getString(R.string.preference_autocomplete_key),
-        AppearanceSettings.DEFAULT.showAutocomplete
-      ),
       showHostmask = getBoolean(
         context.getString(R.string.preference_hostmask_key),
         AppearanceSettings.DEFAULT.showHostmask
@@ -73,6 +70,28 @@ class SettingsModule {
     )
   }
 
+  @Provides
+  fun provideAutoCompleteSettings(context: Context) = context.sharedPreferences {
+    AutoCompleteSettings(
+      button = getBoolean(
+        context.getString(R.string.preference_autocomplete_button_key),
+        AutoCompleteSettings.DEFAULT.button
+      ),
+      doubleTap = getBoolean(
+        context.getString(R.string.preference_autocomplete_doubletap_key),
+        AutoCompleteSettings.DEFAULT.button
+      ),
+      auto = getBoolean(
+        context.getString(R.string.preference_autocomplete_auto_key),
+        AutoCompleteSettings.DEFAULT.button
+      ),
+      prefix = getBoolean(
+        context.getString(R.string.preference_autocomplete_prefix_key),
+        AutoCompleteSettings.DEFAULT.button
+      )
+    )
+  }
+
   @Provides
   fun provideBacklogSettings(context: Context) = context.sharedPreferences {
     BacklogSettings(
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
index 31b2c0e94..4589a3a95 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
@@ -12,7 +12,6 @@ data class AppearanceSettings(
   val textSize: Int = 14,
   val showSeconds: Boolean = false,
   val use24hClock: Boolean = true,
-  val showAutocomplete: Boolean = true,
   val showHostmask: Boolean = false,
   val showLag: Boolean = true,
   val theme: Theme = Theme.QUASSEL_LIGHT
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/AutoCompleteSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/AutoCompleteSettings.kt
new file mode 100644
index 000000000..f66f35a67
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/AutoCompleteSettings.kt
@@ -0,0 +1,12 @@
+package de.kuschku.quasseldroid.settings
+
+data class AutoCompleteSettings(
+  val button: Boolean = false,
+  val doubleTap: Boolean = true,
+  val auto: Boolean = true,
+  val prefix: Boolean = true
+) {
+  companion object {
+    val DEFAULT = AutoCompleteSettings()
+  }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
index 926e270e3..2bb8a0cc7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
@@ -52,10 +52,6 @@ object Settings {
         context.getString(R.string.preference_colorize_mirc_key),
         AppearanceSettings.DEFAULT.colorizeMirc
       ),
-      showAutocomplete = getBoolean(
-        context.getString(R.string.preference_autocomplete_key),
-        AppearanceSettings.DEFAULT.showAutocomplete
-      ),
       showHostmask = getBoolean(
         context.getString(R.string.preference_hostmask_key),
         AppearanceSettings.DEFAULT.showHostmask
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 cf6d3b697..7f74e4e07 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
@@ -118,6 +118,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       findViewById(R.id.formatting_menu),
       findViewById(R.id.formatting_toolbar),
       appearanceSettings,
+      autoCompleteSettings,
       { lines ->
         viewModel.session { sessionOptional ->
           val session = sessionOptional.orNull()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
index 96884a004..aae660e5f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
@@ -7,11 +7,14 @@ import android.support.v7.widget.*
 import android.text.Editable
 import android.text.InputType
 import android.text.TextWatcher
+import android.view.GestureDetector
 import android.view.KeyEvent
 import android.view.MenuItem
+import android.view.MotionEvent
 import android.view.inputmethod.EditorInfo
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
+import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.util.helper.lastWordIndices
 import de.kuschku.quasseldroid.util.helper.lineSequence
@@ -34,6 +37,7 @@ class Editor(
   formattingToolbar: Toolbar,
   // Settings
   private val appearanceSettings: AppearanceSettings,
+  private val autoCompleteSettings: AutoCompleteSettings,
   // Listeners
   private val sendCallback: (Sequence<Pair<CharSequence, String>>) -> Unit,
   private val panelStateCallback: (Boolean) -> Unit
@@ -116,7 +120,6 @@ class Editor(
 
     chatline.addTextChangedListener(textWatcher)
 
-
     val autocompleteAdapter = AutoCompleteAdapter(
       // This is still broken when mixing tab complete and UI auto complete
       formatHandler::autoComplete
@@ -124,12 +127,13 @@ class Editor(
 
     autoCompleteData.observe(activity, Observer {
       val query = it?.first ?: ""
-      val list = if (query.length >= 3) it?.second.orEmpty() else emptyList()
-
-      autocompleteAdapter.submitList(list)
+      val shouldShowResults = (autoCompleteSettings.auto && query.length >= 3) ||
+                              (autoCompleteSettings.prefix && query.startsWith('@')) ||
+                              (autoCompleteSettings.prefix && query.startsWith('#'))
+      autocompleteAdapter.submitList(if (shouldShowResults) it?.second.orEmpty() else emptyList())
     })
 
-    if (appearanceSettings.showAutocomplete) {
+    if (autoCompleteSettings.prefix || autoCompleteSettings.auto) {
       for (autoCompleteList in autoCompleteLists) {
         autoCompleteList.layoutManager = LinearLayoutManager(activity)
         autoCompleteList.itemAnimator = DefaultItemAnimator()
@@ -137,6 +141,23 @@ class Editor(
       }
     }
 
+    if (autoCompleteSettings.doubleTap) {
+      val gestureDetector = GestureDetector(
+        chatline.context, object : GestureDetector.SimpleOnGestureListener() {
+        override fun onDoubleTap(e: MotionEvent?): Boolean {
+          autoComplete()
+          return true
+        }
+
+        override fun onDoubleTapEvent(e: MotionEvent?): Boolean {
+          return true
+        }
+      })
+      chatline.setOnTouchListener { _, event ->
+        gestureDetector.onTouchEvent(event)
+      }
+    }
+
     lastWordContainer.onNext(lastWord)
 
     activity.menuInflater.inflate(formatHandler.menu, formattingMenu.menu)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
index e1656a01e..bce5465b2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
@@ -19,7 +19,9 @@ import de.kuschku.quasseldroid.util.helper.selection
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer
 import de.kuschku.quasseldroid.util.irc.format.spans.*
 
-class FormatHandler(private val editText: EditText) {
+class FormatHandler(
+  private val editText: EditText
+) {
   private val serializer = IrcFormatSerializer(editText.context)
   val formattedText: Sequence<String>
     get() = editText.text.lineSequence().map { serializer.toEscapeCodes(SpannableString(it)) }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
index 4c0283e63..e620847e6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
@@ -19,6 +19,7 @@ import de.kuschku.libquassel.util.Optional
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
+import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.settings.ConnectionSettings
 import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity
@@ -70,6 +71,9 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
   @Inject
   lateinit var appearanceSettings: AppearanceSettings
 
+  @Inject
+  lateinit var autoCompleteSettings: AutoCompleteSettings
+
   @Inject
   lateinit var connectionSettings: ConnectionSettings
 
diff --git a/app/src/main/res/values-de/strings_preferences.xml b/app/src/main/res/values-de/strings_preferences.xml
index e10cb5406..18dcf1f24 100644
--- a/app/src/main/res/values-de/strings_preferences.xml
+++ b/app/src/main/res/values-de/strings_preferences.xml
@@ -37,7 +37,19 @@
   <string name="preference_input_enter_entry_emoji">Emoji-Auswahl</string>
   <string name="preference_input_enter_entry_send">Senden</string>
 
-  <string name="preference_autocomplete_title">Autovervollständigungs-UI</string>
+  <string name="preference_autocomplete_title">Autovervollständigung</string>
+
+  <string name="preference_autocomplete_button_title">Autovervollständigungsknopf</string>
+  <string name="preference_autocomplete_button_summary">Zeigt einen Knopf um Namen und Chats zu vervollständigen</string>
+
+  <string name="preference_autocomplete_doubletap_title">Doppelclick-Autocomplete</string>
+  <string name="preference_autocomplete_doubletap_summary">Vervollständigt Namen und Chats automatisch, wenn auf das Eingabefeld doppelgeklickt wird</string>
+
+  <string name="preference_autocomplete_auto_title">Automatisch anzeigen</string>
+  <string name="preference_autocomplete_auto_summary">Vervollständigt Namen und Chats automatischen nach den ersten 3 Buchstaben</string>
+
+  <string name="preference_autocomplete_prefix_title">Nach Präfix anzeigen</string>
+  <string name="preference_autocomplete_prefix_summary">Vervollständigt Namen und Chats automatisch nach einem @ oder #</string>
 
   <string name="preference_hostmask_title">Hostmaske</string>
   <string name="preference_hostmask_summary">Zeigt die gesame Spitzname!Ident@Host Information an</string>
diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml
index 8993c6ae3..66e6c5b1e 100644
--- a/app/src/main/res/values/strings_preferences.xml
+++ b/app/src/main/res/values/strings_preferences.xml
@@ -92,8 +92,23 @@
     <item>SEND</item>
   </string-array>
 
-  <string name="preference_autocomplete_key" translatable="false">autocomplete</string>
-  <string name="preference_autocomplete_title">Show AutoComplete UI</string>
+  <string name="preference_autocomplete_title">Autocomplete</string>
+
+  <string name="preference_autocomplete_button_key" translatable="false">autocomplete_button</string>
+  <string name="preference_autocomplete_button_title">Autocomplete Button</string>
+  <string name="preference_autocomplete_button_summary">Shows a button on the left of the input line that triggers tabcomplete</string>
+
+  <string name="preference_autocomplete_doubletap_key" translatable="false">autocomplete_doubletap</string>
+  <string name="preference_autocomplete_doubletap_title">Double tap to autocomplete</string>
+  <string name="preference_autocomplete_doubletap_summary">Suggest nicks and channels after doubleclicking on the input field</string>
+
+  <string name="preference_autocomplete_auto_key" translatable="false">autocomplete_auto</string>
+  <string name="preference_autocomplete_auto_title">Show automatically</string>
+  <string name="preference_autocomplete_auto_summary">Suggest nicks and channels after entering the first 3 characters</string>
+
+  <string name="preference_autocomplete_prefix_key" translatable="false">autocomplete_prefix</string>
+  <string name="preference_autocomplete_prefix_title">Show after prefix</string>
+  <string name="preference_autocomplete_prefix_summary">Suggest nicks and channels after entering @ or #</string>
 
   <string name="preference_hostmask_key" translatable="false">hostmask</string>
   <string name="preference_hostmask_title">Show Hostmask</string>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index aa6a89553..768aec531 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -59,11 +59,6 @@
       android:key="@string/preference_show_prefix_key"
       android:title="@string/preference_show_prefix_title" />
 
-    <SwitchPreference
-      android:defaultValue="true"
-      android:key="@string/preference_autocomplete_key"
-      android:title="@string/preference_autocomplete_title" />
-
     <SwitchPreference
       android:defaultValue="false"
       android:key="@string/preference_hostmask_key"
@@ -77,6 +72,33 @@
       android:title="@string/preference_show_lag_title" />
   </PreferenceCategory>
 
+  <PreferenceCategory android:title="@string/preference_autocomplete_title">
+
+    <SwitchPreference
+      android:defaultValue="false"
+      android:key="@string/preference_autocomplete_button_key"
+      android:summary="@string/preference_autocomplete_button_summary"
+      android:title="@string/preference_autocomplete_button_title" />
+
+    <SwitchPreference
+      android:defaultValue="true"
+      android:key="@string/preference_autocomplete_doubletap_key"
+      android:summary="@string/preference_autocomplete_doubletap_summary"
+      android:title="@string/preference_autocomplete_doubletap_title" />
+
+    <SwitchPreference
+      android:defaultValue="true"
+      android:key="@string/preference_autocomplete_auto_key"
+      android:summary="@string/preference_autocomplete_auto_summary"
+      android:title="@string/preference_autocomplete_auto_title" />
+
+    <SwitchPreference
+      android:defaultValue="true"
+      android:key="@string/preference_autocomplete_prefix_key"
+      android:summary="@string/preference_autocomplete_prefix_summary"
+      android:title="@string/preference_autocomplete_prefix_title" />
+  </PreferenceCategory>
+
   <PreferenceCategory android:title="@string/preference_backlog_title">
     <EditTextPreference
       android:defaultValue="150"
-- 
GitLab