From 043375de88de2667cea1e03eb85c5cc6044e2f92 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 18 Apr 2018 00:42:56 +0200
Subject: [PATCH] Implement highlight rule management UI

---
 .../ui/coresettings/CoreSettingsFragment.kt   |   5 +
 .../DragSortItemTouchHelperCallback.kt        |  28 +++
 .../highlightlist/HighlightListFragment.kt    | 196 +++++++++++++++++-
 .../highlightlist/HighlightNickTypeAdapter.kt |  70 +++++++
 .../highlightlist/HighlightNickTypeItem.kt    |   9 +
 .../highlightlist/HighlightRuleAdapter.kt     | 127 ++++++++++++
 .../highlightrule/HighlightRuleActivity.kt    |   9 +-
 .../highlightrule/HighlightRuleFragment.kt    |  75 ++++++-
 .../ignoreitem/IgnoreItemFragment.kt          |  36 ++--
 .../ignorelist/IgnoreListAdapter.kt           |  12 +-
 .../ignorelist/IgnoreListFragment.kt          |   5 +-
 .../res/layout/settings_highlightlist.xml     | 178 ++++++++++++++++
 .../layout/settings_highlightlist_rule.xml    |  82 ++++++++
 .../res/layout/settings_highlightrule.xml     |  71 +++++++
 .../main/res/layout/settings_ignoreitem.xml   |   4 +-
 .../res/layout/settings_ignorelist_item.xml   |  32 +++
 app/src/main/res/values-de/strings.xml        |   2 +
 .../main/res/values-de/strings_settings.xml   |  13 ++
 app/src/main/res/values/strings.xml           |   2 +
 app/src/main/res/values/strings_settings.xml  |  13 ++
 app/src/main/res/values/styles_widgets.xml    |   8 +
 21 files changed, 935 insertions(+), 42 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/DragSortItemTouchHelperCallback.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeItem.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt
 create mode 100644 app/src/main/res/layout/settings_highlightlist.xml
 create mode 100644 app/src/main/res/layout/settings_highlightlist_rule.xml
 create mode 100644 app/src/main/res/layout/settings_highlightrule.xml

diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
index 25fdaaa01..238ed9032 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
@@ -18,6 +18,7 @@ import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity
 import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditActivity
+import de.kuschku.quasseldroid.ui.coresettings.highlightlist.HighlightListActivity
 import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityCreateActivity
 import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityEditActivity
 import de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity
@@ -131,6 +132,10 @@ class CoreSettingsFragment : ServiceBoundFragment() {
       IgnoreListActivity.launch(requireContext())
     }
 
+    highlightlist.setOnClickListener {
+      HighlightListActivity.launch(requireContext())
+    }
+
     newNetwork.setOnClickListener {
       NetworkCreateActivity.launch(requireContext())
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/DragSortItemTouchHelperCallback.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/DragSortItemTouchHelperCallback.kt
new file mode 100644
index 000000000..e6547650e
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/DragSortItemTouchHelperCallback.kt
@@ -0,0 +1,28 @@
+package de.kuschku.quasseldroid.ui.coresettings.highlightlist
+
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.helper.ItemTouchHelper
+
+class DragSortItemTouchHelperCallback(private val adapter: HighlightRuleAdapter) :
+  ItemTouchHelper.Callback() {
+  override fun isLongPressDragEnabled() = true
+
+  override fun isItemViewSwipeEnabled() = true
+
+  override fun getMovementFlags(recyclerView: RecyclerView,
+                                viewHolder: RecyclerView.ViewHolder): Int {
+    val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
+    val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END
+    return makeMovementFlags(dragFlags, swipeFlags)
+  }
+
+  override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
+                      target: RecyclerView.ViewHolder): Boolean {
+    adapter.move(viewHolder.adapterPosition, target.adapterPosition)
+    return true
+  }
+
+  override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+    adapter.remove(viewHolder.adapterPosition)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
index 8e2cf3a10..f94e0cf52 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
@@ -1,23 +1,209 @@
 package de.kuschku.quasseldroid.ui.coresettings.highlightlist
 
+import android.app.Activity
+import android.arch.lifecycle.Observer
+import android.content.Intent
 import android.os.Bundle
+import android.support.v7.widget.DefaultItemAnimator
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.SwitchCompat
+import android.support.v7.widget.helper.ItemTouchHelper
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.Button
+import android.widget.Spinner
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
+import de.kuschku.libquassel.quassel.syncables.interfaces.IHighlightRuleManager
+import de.kuschku.libquassel.util.Optional
+import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
+import de.kuschku.quasseldroid.ui.coresettings.highlightrule.HighlightRuleActivity
+import de.kuschku.quasseldroid.util.helper.toLiveData
 
 class HighlightListFragment : SettingsFragment(), SettingsFragment.Savable,
                               SettingsFragment.Changeable {
+  @BindView(R.id.highlight_nick_type)
+  lateinit var highlightNickType: Spinner
+
+  @BindView(R.id.is_case_sensitive)
+  lateinit var isCaseSensitive: SwitchCompat
+
+  @BindView(R.id.highlight_rules)
+  lateinit var rules: RecyclerView
+
+  @BindView(R.id.new_highlight_rule)
+  lateinit var newHighlightRule: Button
+
+  @BindView(R.id.highlight_ignore_rules)
+  lateinit var ignoreRules: RecyclerView
+
+  @BindView(R.id.new_highlight_ignore_rule)
+  lateinit var newHighlightIgnoreRule: Button
+
+  private var ruleManager: Pair<HighlightRuleManager, HighlightRuleManager>? = null
+
+  private lateinit var rulesHelper: ItemTouchHelper
+
+  private lateinit var ignoreRulesHelper: ItemTouchHelper
+
+  private val rulesAdapter = HighlightRuleAdapter(::ruleClick, ::startRuleDrag)
+
+  private val ignoreRulesAdapter = HighlightRuleAdapter(::ignoreRuleClick, ::startIgnoreRuleDrag)
+
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
-    return super.onCreateView(inflater, container, savedInstanceState)
+    val view = inflater.inflate(R.layout.settings_highlightlist, container, false)
+    ButterKnife.bind(this, view)
+
+    rules.adapter = rulesAdapter
+    rules.layoutManager = LinearLayoutManager(requireContext())
+    rules.itemAnimator = DefaultItemAnimator()
+
+    rulesHelper = ItemTouchHelper(DragSortItemTouchHelperCallback(rulesAdapter))
+    rulesHelper.attachToRecyclerView(rules)
+
+    ignoreRules.adapter = ignoreRulesAdapter
+    ignoreRules.layoutManager = LinearLayoutManager(requireContext())
+    ignoreRules.itemAnimator = DefaultItemAnimator()
+
+    ignoreRulesHelper = ItemTouchHelper(DragSortItemTouchHelperCallback(ignoreRulesAdapter))
+    ignoreRulesHelper.attachToRecyclerView(ignoreRules)
+
+    newHighlightRule.setOnClickListener {
+      startActivityForResult(
+        HighlightRuleActivity.intent(requireContext(), ignore = false),
+        REQUEST_CREATE_RULE
+      )
+    }
+
+    newHighlightIgnoreRule.setOnClickListener {
+      startActivityForResult(
+        HighlightRuleActivity.intent(requireContext(), ignore = true),
+        REQUEST_CREATE_RULE
+      )
+    }
+
+    val highlightNickTypeAdapter = HighlightNickTypeAdapter(listOf(
+      HighlightNickTypeItem(
+        value = IHighlightRuleManager.HighlightNickType.AllNicks,
+        name = R.string.settings_highlightlist_highlight_nick_all_nicks
+      ),
+      HighlightNickTypeItem(
+        value = IHighlightRuleManager.HighlightNickType.CurrentNick,
+        name = R.string.settings_highlightlist_highlight_nick_current_nick
+      ),
+      HighlightNickTypeItem(
+        value = IHighlightRuleManager.HighlightNickType.NoNick,
+        name = R.string.settings_highlightlist_highlight_nick_none
+      )
+    ))
+    highlightNickType.adapter = highlightNickTypeAdapter
+
+    viewModel.highlightRuleManager
+      .filter(Optional<HighlightRuleManager>::isPresent)
+      .map(Optional<HighlightRuleManager>::get)
+      .toLiveData().observe(this, Observer {
+        if (it != null) {
+          if (this.ruleManager == null) {
+            this.ruleManager = Pair(it, it.copy())
+            this.ruleManager?.let { (_, data) ->
+              rulesAdapter.list = data.highlightRuleList().filter { it.isInverse == false }
+              ignoreRulesAdapter.list = data.highlightRuleList().filter { it.isInverse == true }
+              highlightNickType.setSelection(highlightNickTypeAdapter.indexOf(data.highlightNick())
+                                             ?: 0)
+              isCaseSensitive.isChecked = data.nicksCaseSensitive()
+            }
+          }
+        }
+      })
+
+    return view
+  }
+
+  private fun ruleClick(rule: HighlightRuleManager.HighlightRule) {
+    startActivityForResult(
+      HighlightRuleActivity.intent(requireContext(), rule),
+      REQUEST_UPDATE_RULE
+    )
   }
 
-  override fun hasChanged(): Boolean {
-    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+  private fun startRuleDrag(holder: HighlightRuleAdapter.HighlightRuleViewHolder) =
+    rulesHelper.startDrag(holder)
+
+  private fun ignoreRuleClick(rule: HighlightRuleManager.HighlightRule) {
+    startActivityForResult(
+      HighlightRuleActivity.intent(requireContext(), rule),
+      REQUEST_UPDATE_IGNORE_RULE
+    )
+  }
+
+  private fun startIgnoreRuleDrag(holder: HighlightRuleAdapter.HighlightRuleViewHolder) =
+    ignoreRulesHelper.startDrag(holder)
+
+  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+    if (resultCode == Activity.RESULT_OK && data != null) {
+      when (requestCode) {
+        REQUEST_UPDATE_RULE        -> {
+          val oldRule = data.getSerializableExtra("old") as? HighlightRuleManager.HighlightRule
+          val newRule = data.getSerializableExtra("new") as? HighlightRuleManager.HighlightRule
+
+          if (oldRule != null && newRule != null) {
+            rulesAdapter.replace(rulesAdapter.indexOf(oldRule.name), newRule)
+          }
+        }
+        REQUEST_CREATE_RULE        -> {
+          val newRule = data.getSerializableExtra("new") as? HighlightRuleManager.HighlightRule
+
+          if (newRule != null) {
+            rulesAdapter.add(newRule)
+          }
+        }
+        REQUEST_UPDATE_IGNORE_RULE -> {
+          val oldRule = data.getSerializableExtra("old") as? HighlightRuleManager.HighlightRule
+          val newRule = data.getSerializableExtra("new") as? HighlightRuleManager.HighlightRule
+
+          if (oldRule != null && newRule != null) {
+            ignoreRulesAdapter.replace(ignoreRulesAdapter.indexOf(oldRule.name), newRule)
+          }
+        }
+        REQUEST_CREATE_IGNORE_RULE -> {
+          val newRule = data.getSerializableExtra("new") as? HighlightRuleManager.HighlightRule
+
+          if (newRule != null) {
+            ignoreRulesAdapter.add(newRule)
+          }
+        }
+      }
+    }
+  }
+
+  override fun onSave() = ruleManager?.let { (it, data) ->
+    applyChanges(data)
+    it.requestUpdate(data.toVariantMap())
+    true
+  } ?: false
+
+  override fun hasChanged() = ruleManager?.let { (it, data) ->
+    applyChanges(data)
+    data.highlightNick() != it.highlightNick() ||
+    data.nicksCaseSensitive() != it.nicksCaseSensitive() ||
+    data.highlightRuleList() != it.highlightRuleList()
+  } ?: false
+
+  private fun applyChanges(data: HighlightRuleManager) {
+    data.setHighlightNick(highlightNickType.selectedItemId.toInt())
+    data.setNicksCaseSensitive(isCaseSensitive.isChecked)
+    data.setHighlightRuleList(rulesAdapter.list + ignoreRulesAdapter.list)
   }
 
-  override fun onSave(): Boolean {
-    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+  companion object {
+    private const val REQUEST_UPDATE_RULE = 1
+    private const val REQUEST_CREATE_RULE = 2
+    private const val REQUEST_UPDATE_IGNORE_RULE = 3
+    private const val REQUEST_CREATE_IGNORE_RULE = 4
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt
new file mode 100644
index 000000000..8a2802d55
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt
@@ -0,0 +1,70 @@
+package de.kuschku.quasseldroid.ui.coresettings.highlightlist
+
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.ThemedSpinnerAdapter
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.quassel.syncables.interfaces.IHighlightRuleManager
+import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper
+import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter
+
+class HighlightNickTypeAdapter(val data: List<HighlightNickTypeItem>) :
+  RecyclerSpinnerAdapter<HighlightNickTypeAdapter.HighlightNickTypeViewHolder>(),
+  ThemedSpinnerAdapter {
+
+  override fun isEmpty() = data.isEmpty()
+
+  override fun onBindViewHolder(holder: HighlightNickTypeViewHolder, position: Int) =
+    holder.bind(getItem(position))
+
+  override fun onCreateViewHolder(parent: ViewGroup, dropDown: Boolean)
+    : HighlightNickTypeViewHolder {
+    val inflater = LayoutInflater.from(
+      if (dropDown)
+        ContextThemeWrapper(parent.context, dropDownViewTheme)
+      else
+        parent.context
+    )
+    val view = inflater.inflate(R.layout.widget_spinner_item_toolbar, parent, false)
+    return HighlightNickTypeViewHolder(
+      view
+    )
+  }
+
+  override fun getItem(position: Int) = data[position]
+
+  override fun getItemId(position: Int) = getItem(position).value.value.toLong()
+
+  override fun hasStableIds() = true
+
+  override fun getCount() = data.size
+
+  fun indexOf(value: IHighlightRuleManager.HighlightNickType): Int? {
+    for ((key, item) in data.withIndex()) {
+      if (item.value.value == value.value) {
+        return key
+      }
+    }
+    return null
+  }
+
+  class HighlightNickTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+    @BindView(android.R.id.text1)
+    lateinit var text: TextView
+
+    init {
+      ButterKnife.bind(this, itemView)
+    }
+
+    fun bind(activity: HighlightNickTypeItem?) {
+      activity?.let {
+        text.setText(it.name)
+      }
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeItem.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeItem.kt
new file mode 100644
index 000000000..f34fa9e20
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeItem.kt
@@ -0,0 +1,9 @@
+package de.kuschku.quasseldroid.ui.coresettings.highlightlist
+
+import android.support.annotation.StringRes
+import de.kuschku.libquassel.quassel.syncables.interfaces.IHighlightRuleManager
+
+data class HighlightNickTypeItem(
+  val value: IHighlightRuleManager.HighlightNickType,
+  @StringRes val name: Int
+)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt
new file mode 100644
index 000000000..970e903c7
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt
@@ -0,0 +1,127 @@
+package de.kuschku.quasseldroid.ui.coresettings.highlightlist
+
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.SwitchCompat
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
+import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.util.helper.visibleIf
+import java.util.*
+
+class HighlightRuleAdapter(
+  private val clickListener: (HighlightRuleManager.HighlightRule) -> Unit,
+  private val dragListener: (HighlightRuleViewHolder) -> Unit
+) : RecyclerView.Adapter<HighlightRuleAdapter.HighlightRuleViewHolder>() {
+  private val data = mutableListOf<HighlightRuleManager.HighlightRule>()
+  var list: List<HighlightRuleManager.HighlightRule>
+    get() = data
+    set(value) {
+      val length = data.size
+      data.clear()
+      notifyItemRangeRemoved(0, length)
+      data.addAll(value)
+      notifyItemRangeInserted(0, list.size)
+    }
+
+  fun add(item: HighlightRuleManager.HighlightRule) {
+    val index = data.size
+    data.add(item)
+    notifyItemInserted(index)
+  }
+
+  fun replace(index: Int, item: HighlightRuleManager.HighlightRule) {
+    data[index] = item
+    notifyItemChanged(index)
+  }
+
+  fun indexOf(rule: String) = data.map(HighlightRuleManager.HighlightRule::name).indexOf(rule)
+
+  fun remove(index: Int) {
+    data.removeAt(index)
+    notifyItemRemoved(index)
+  }
+
+  fun move(from: Int, to: Int) {
+    Collections.swap(data, from, to)
+    notifyItemMoved(from, to)
+  }
+
+  fun toggle(item: HighlightRuleManager.HighlightRule, isEnabled: Boolean) {
+    val index = indexOf(item.name)
+    data[index] = data[index].copy(isEnabled = isEnabled)
+  }
+
+  override fun getItemCount() = data.size
+
+  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = HighlightRuleViewHolder(
+    LayoutInflater.from(parent.context)
+      .inflate(R.layout.settings_highlightlist_rule, parent, false),
+    clickListener,
+    ::toggle,
+    dragListener
+  )
+
+  override fun onBindViewHolder(holder: HighlightRuleViewHolder, position: Int) {
+    holder.bind(data[position])
+  }
+
+  class HighlightRuleViewHolder(
+    itemView: View,
+    clickListener: (HighlightRuleManager.HighlightRule) -> Unit,
+    toggleListener: (HighlightRuleManager.HighlightRule, Boolean) -> Unit,
+    dragListener: (HighlightRuleViewHolder) -> Unit
+  ) : RecyclerView.ViewHolder(itemView) {
+    @BindView(R.id.name)
+    lateinit var name: TextView
+
+    @BindView(R.id.sender)
+    lateinit var sender: TextView
+
+    @BindView(R.id.channel)
+    lateinit var channel: TextView
+
+    @BindView(R.id.toggle)
+    lateinit var toggle: SwitchCompat
+
+    @BindView(R.id.handle)
+    lateinit var handle: View
+
+    private var item: HighlightRuleManager.HighlightRule? = null
+
+    init {
+      ButterKnife.bind(this, itemView)
+      itemView.setOnClickListener {
+        item?.let {
+          clickListener(it)
+        }
+      }
+      toggle.setOnCheckedChangeListener { _, isChecked ->
+        item?.let {
+          toggleListener.invoke(it, isChecked)
+        }
+      }
+      handle.setOnTouchListener { _, event ->
+        if (event.action == MotionEvent.ACTION_DOWN) {
+          dragListener.invoke(this)
+        }
+        false
+      }
+    }
+
+    fun bind(item: HighlightRuleManager.HighlightRule) {
+      this.item = item
+      name.text = item.name
+      sender.text = item.sender
+      sender.visibleIf(item.sender.isNotBlank())
+      channel.text = item.channel
+      channel.visibleIf(item.channel.isNotBlank())
+      toggle.isChecked = item.isEnabled
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
index b2136afa5..91d3792c5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleActivity.kt
@@ -9,16 +9,19 @@ class HighlightRuleActivity : SettingsActivity(HighlightRuleFragment()) {
   companion object {
     fun launch(
       context: Context,
-      rule: HighlightRuleManager.HighlightRule? = null
-    ) = context.startActivity(intent(context, rule))
+      rule: HighlightRuleManager.HighlightRule? = null,
+      ignore: Boolean = false
+    ) = context.startActivity(intent(context, rule, ignore))
 
     fun intent(
       context: Context,
-      rule: HighlightRuleManager.HighlightRule? = null
+      rule: HighlightRuleManager.HighlightRule? = null,
+      ignore: Boolean = false
     ) = Intent(context, HighlightRuleActivity::class.java).apply {
       if (rule != null) {
         putExtra("item", rule)
       }
+      putExtra("ignore", ignore)
     }
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
index 4c3229b71..7b158bb37 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
@@ -1,23 +1,86 @@
 package de.kuschku.quasseldroid.ui.coresettings.highlightrule
 
+import android.app.Activity
+import android.content.Intent
 import android.os.Bundle
+import android.support.v7.widget.SwitchCompat
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.EditText
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
+import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
 
 class HighlightRuleFragment : SettingsFragment(), SettingsFragment.Savable,
                               SettingsFragment.Changeable {
+  @BindView(R.id.enabled)
+  lateinit var enabled: SwitchCompat
+
+  @BindView(R.id.name)
+  lateinit var name: EditText
+
+  @BindView(R.id.is_regex)
+  lateinit var isRegex: SwitchCompat
+
+  @BindView(R.id.is_case_sensitive)
+  lateinit var isCaseSensitive: SwitchCompat
+
+  @BindView(R.id.sender)
+  lateinit var sender: EditText
+
+  @BindView(R.id.channel)
+  lateinit var channel: EditText
+
+  private var rule: HighlightRuleManager.HighlightRule? = null
+
+  private var isInverse: Boolean? = null
+
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
-    return super.onCreateView(inflater, container, savedInstanceState)
-  }
 
-  override fun hasChanged(): Boolean {
-    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    val view = inflater.inflate(R.layout.settings_highlightrule, container, false)
+    ButterKnife.bind(this, view)
+
+    isInverse = arguments?.getBoolean("inverse")
+    (arguments?.getSerializable("item") as? HighlightRuleManager.HighlightRule)?.let {
+      rule = it
+    }
+
+    rule?.let { data ->
+      enabled.isChecked = data.isEnabled
+      name.setText(data.name)
+      isRegex.isChecked = data.isRegEx
+      isCaseSensitive.isChecked = data.isCaseSensitive
+      sender.setText(data.sender)
+      channel.setText(data.channel)
+    }
+
+    return view
   }
 
-  override fun onSave(): Boolean {
-    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+  private fun applyChanges() = HighlightRuleManager.HighlightRule(
+    isInverse = rule?.isInverse ?: isInverse ?: false,
+    isEnabled = enabled.isChecked,
+    name = name.text.toString(),
+    isRegEx = isRegex.isChecked,
+    isCaseSensitive = isCaseSensitive.isChecked,
+    sender = sender.text.toString(),
+    channel = channel.text.toString()
+  )
+
+  override fun onSave() = rule.let { data ->
+    requireActivity().setResult(
+      Activity.RESULT_OK,
+      Intent().also {
+        it.putExtra("old", data)
+        it.putExtra("new", applyChanges())
+      }
+    )
+    true
   }
+
+  override fun hasChanged() = rule != applyChanges()
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
index 3ac7edbb7..5bc78d5b5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
@@ -22,7 +22,7 @@ class IgnoreItemFragment : SettingsFragment(), SettingsFragment.Savable,
   @BindView(R.id.enabled)
   lateinit var enabled: SwitchCompat
 
-  @BindView(R.id.ignorerule)
+  @BindView(R.id.ignore_rule)
   lateinit var ignoreRule: EditText
 
   @BindView(R.id.isregex)
@@ -37,7 +37,7 @@ class IgnoreItemFragment : SettingsFragment(), SettingsFragment.Savable,
   @BindView(R.id.scope)
   lateinit var scope: Spinner
 
-  @BindView(R.id.scoperule)
+  @BindView(R.id.scope_rule)
   lateinit var scopeRule: EditText
 
   @BindView(R.id.scopegroup)
@@ -125,24 +125,7 @@ class IgnoreItemFragment : SettingsFragment(), SettingsFragment.Savable,
     return view
   }
 
-  override fun onSave() = item.let { data ->
-    val intent = Intent()
-    intent.putExtra("old", data)
-    val new = IgnoreListManager.IgnoreListItem(
-      isActive = enabled.isChecked,
-      ignoreRule = ignoreRule.text.toString(),
-      isRegEx = isRegEx.isChecked,
-      type = type.selectedItemId.toInt(),
-      strictness = strictness.selectedItemId.toInt(),
-      scope = scope.selectedItemId.toInt(),
-      scopeRule = scopeRule.text.toString()
-    )
-    intent.putExtra("new", new)
-    requireActivity().setResult(Activity.RESULT_OK, intent)
-    true
-  }
-
-  override fun hasChanged() = item != IgnoreListManager.IgnoreListItem(
+  private fun applyChanges() = IgnoreListManager.IgnoreListItem(
     isActive = enabled.isChecked,
     ignoreRule = ignoreRule.text.toString(),
     isRegEx = isRegEx.isChecked,
@@ -151,4 +134,17 @@ class IgnoreItemFragment : SettingsFragment(), SettingsFragment.Savable,
     scope = scope.selectedItemId.toInt(),
     scopeRule = scopeRule.text.toString()
   )
+
+  override fun onSave() = item.let { data ->
+    requireActivity().setResult(
+      Activity.RESULT_OK,
+      Intent().also {
+        it.putExtra("old", data)
+        it.putExtra("new", applyChanges())
+      }
+    )
+    true
+  }
+
+  override fun hasChanged() = item != applyChanges()
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt
index 2c204b871..e190fbdba 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt
@@ -11,6 +11,7 @@ import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.IgnoreListManager
 import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.util.helper.visibleIf
 import java.util.*
 
 class IgnoreListAdapter(
@@ -75,8 +76,11 @@ class IgnoreListAdapter(
     toggleListener: (IgnoreListManager.IgnoreListItem, Boolean) -> Unit,
     dragListener: (IgnoreItemViewHolder) -> Unit
   ) : RecyclerView.ViewHolder(itemView) {
-    @BindView(R.id.title)
-    lateinit var title: TextView
+    @BindView(R.id.ignore_rule)
+    lateinit var ignoreRule: TextView
+
+    @BindView(R.id.scope_rule)
+    lateinit var scopeRule: TextView
 
     @BindView(R.id.toggle)
     lateinit var toggle: SwitchCompat
@@ -108,7 +112,9 @@ class IgnoreListAdapter(
 
     fun bind(item: IgnoreListManager.IgnoreListItem) {
       this.item = item
-      title.text = item.ignoreRule
+      ignoreRule.text = item.ignoreRule
+      scopeRule.text = item.scopeRule
+      scopeRule.visibleIf(item.scopeRule.isNotBlank() && item.scope != IgnoreListManager.ScopeType.GlobalScope)
       toggle.isChecked = item.isActive
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
index 967ab67c6..b1bf65b5f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
@@ -31,7 +31,7 @@ class IgnoreListFragment : SettingsFragment(), SettingsFragment.Savable,
 
   private var ignoreListManager: Pair<IgnoreListManager, IgnoreListManager>? = null
 
-  lateinit var helper: ItemTouchHelper
+  private lateinit var helper: ItemTouchHelper
 
   private val adapter = IgnoreListAdapter(::itemClick, ::startDrag)
 
@@ -83,8 +83,7 @@ class IgnoreListFragment : SettingsFragment(), SettingsFragment.Savable,
           val newRule = data.getSerializableExtra("new") as? IgnoreListManager.IgnoreListItem
 
           if (oldRule != null && newRule != null) {
-            val index = adapter.indexOf(oldRule.ignoreRule)
-            adapter.replace(index, newRule)
+            adapter.replace(adapter.indexOf(oldRule.ignoreRule), newRule)
           }
         }
         REQUEST_CREATE_RULE -> {
diff --git a/app/src/main/res/layout/settings_highlightlist.xml b/app/src/main/res/layout/settings_highlightlist.xml
new file mode 100644
index 000000000..0a5096f6a
--- /dev/null
+++ b/app/src/main/res/layout/settings_highlightlist.xml
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v4.widget.NestedScrollView 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:layout_width="match_parent"
+  android:layout_height="match_parent"
+  android:scrollbars="vertical">
+
+  <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_vertical"
+      android:minHeight="?listPreferredItemHeightSmall"
+      android:paddingEnd="?listPreferredItemPaddingRight"
+      android:paddingLeft="?listPreferredItemPaddingLeft"
+      android:paddingRight="?listPreferredItemPaddingRight"
+      android:paddingStart="?listPreferredItemPaddingLeft">
+
+      <android.support.v7.widget.AppCompatImageView
+        style="@style/Widget.CoreSettings.PrimaryItemIcon"
+        app:srcCompat="@drawable/ic_server_network" />
+
+      <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp">
+
+        <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/settings_highlightlist_highlight_nick"
+          android:textColor="?colorTextPrimary"
+          android:textSize="16sp" />
+      </LinearLayout>
+    </LinearLayout>
+
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_marginLeft="72dp"
+      android:layout_marginStart="72dp"
+      android:orientation="vertical">
+
+      <Spinner
+        android:id="@+id/highlight_nick_type"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        tools:listitem="@layout/widget_spinner_item_toolbar" />
+
+      <android.support.v7.widget.SwitchCompat
+        android:id="@+id/is_case_sensitive"
+        style="@style/Widget.CoreSettings.PrimaryItemSwitch"
+        android:text="@string/settings_highlightlist_nicks_case_sensitive" />
+    </LinearLayout>
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_vertical"
+      android:minHeight="?listPreferredItemHeightSmall"
+      android:paddingEnd="?listPreferredItemPaddingRight"
+      android:paddingLeft="?listPreferredItemPaddingLeft"
+      android:paddingRight="?listPreferredItemPaddingRight"
+      android:paddingStart="?listPreferredItemPaddingLeft">
+
+      <android.support.v7.widget.AppCompatImageView
+        style="@style/Widget.CoreSettings.PrimaryItemIcon"
+        app:srcCompat="@drawable/ic_server_network" />
+
+      <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp">
+
+        <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/settings_highlightlist_rules"
+          android:textColor="?colorTextPrimary"
+          android:textSize="16sp" />
+      </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_marginLeft="72dp"
+      android:layout_marginStart="72dp"
+      android:orientation="vertical">
+
+      <android.support.v7.widget.RecyclerView
+        android:id="@+id/highlight_rules"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        tools:itemCount="2"
+        tools:listitem="@layout/settings_highlightlist_rule" />
+
+      <LinearLayout
+        style="@style/Widget.CoreSettings.EditTextLayout"
+        android:orientation="horizontal">
+
+        <Button
+          android:id="@+id/new_highlight_rule"
+          style="@style/Widget.Button.Borderless.Colored"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/label_new_highlight_rule" />
+      </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_vertical"
+      android:minHeight="?listPreferredItemHeightSmall"
+      android:paddingEnd="?listPreferredItemPaddingRight"
+      android:paddingLeft="?listPreferredItemPaddingLeft"
+      android:paddingRight="?listPreferredItemPaddingRight"
+      android:paddingStart="?listPreferredItemPaddingLeft">
+
+      <android.support.v7.widget.AppCompatImageView
+        style="@style/Widget.CoreSettings.PrimaryItemIcon"
+        app:srcCompat="@drawable/ic_server_network" />
+
+      <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingBottom="16dp"
+        android:paddingTop="16dp">
+
+        <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:text="@string/settings_highlightlist_ignore_rules"
+          android:textColor="?colorTextPrimary"
+          android:textSize="16sp" />
+      </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_marginLeft="72dp"
+      android:layout_marginStart="72dp"
+      android:orientation="vertical">
+
+      <android.support.v7.widget.RecyclerView
+        android:id="@+id/highlight_ignore_rules"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        tools:itemCount="2"
+        tools:listitem="@layout/settings_highlightlist_rule" />
+
+      <LinearLayout
+        style="@style/Widget.CoreSettings.EditTextLayout"
+        android:orientation="horizontal">
+
+        <Button
+          android:id="@+id/new_highlight_ignore_rule"
+          style="@style/Widget.Button.Borderless.Colored"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/label_new_highlight_ignore_rule" />
+      </LinearLayout>
+    </LinearLayout>
+  </LinearLayout>
+</android.support.v4.widget.NestedScrollView>
diff --git a/app/src/main/res/layout/settings_highlightlist_rule.xml b/app/src/main/res/layout/settings_highlightlist_rule.xml
new file mode 100644
index 000000000..9bf0ae7f5
--- /dev/null
+++ b/app/src/main/res/layout/settings_highlightlist_rule.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.CardView 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:layout_width="match_parent"
+  android:layout_height="wrap_content"
+  android:layout_margin="2dp"
+  app:cardBackgroundColor="?colorBackgroundCard"
+  app:cardElevation="2dp">
+
+  <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?selectableItemBackground"
+    android:focusable="true"
+    android:gravity="center_vertical"
+    android:minHeight="?listPreferredItemHeightSmall">
+
+    <android.support.v7.widget.AppCompatImageView
+      android:id="@+id/handle"
+      android:layout_width="wrap_content"
+      android:layout_height="match_parent"
+      android:layout_gravity="center_vertical"
+      android:paddingEnd="32dp"
+      android:paddingLeft="?listPreferredItemPaddingRight"
+      android:paddingRight="32dp"
+      android:paddingStart="?listPreferredItemPaddingRight"
+      app:srcCompat="@drawable/ic_reorder"
+      app:tint="?colorTextSecondary" />
+
+    <LinearLayout
+      android:layout_width="0dip"
+      android:layout_height="wrap_content"
+      android:layout_weight="1"
+      android:orientation="vertical"
+      android:paddingBottom="16dp"
+      android:paddingTop="16dp">
+
+      <TextView
+        android:id="@+id/name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:orientation="vertical"
+        android:singleLine="true"
+        android:textAppearance="?android:textAppearanceMedium"
+        android:textColor="?colorTextPrimary"
+        android:textSize="16sp"
+        tools:text="(janne): " />
+
+      <TextView
+        android:id="@+id/sender"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:textAppearance="?textAppearanceListItemSecondary"
+        android:textColor="?colorTextSecondary"
+        tools:text="TARS" />
+
+      <TextView
+        android:id="@+id/channel"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:textAppearance="?textAppearanceListItemSecondary"
+        android:textColor="?colorTextSecondary"
+        tools:text="#yepityha" />
+
+    </LinearLayout>
+
+    <android.support.v7.widget.SwitchCompat
+      android:id="@+id/toggle"
+      android:layout_width="wrap_content"
+      android:layout_height="match_parent"
+      android:paddingEnd="?listPreferredItemPaddingRight"
+      android:paddingLeft="?listPreferredItemPaddingLeft"
+      android:paddingRight="?listPreferredItemPaddingRight"
+      android:paddingStart="?listPreferredItemPaddingLeft" />
+  </LinearLayout>
+</android.support.v7.widget.CardView>
diff --git a/app/src/main/res/layout/settings_highlightrule.xml b/app/src/main/res/layout/settings_highlightrule.xml
new file mode 100644
index 000000000..c0b248ffb
--- /dev/null
+++ b/app/src/main/res/layout/settings_highlightrule.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v4.widget.NestedScrollView 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:layout_width="match_parent"
+  android:layout_height="match_parent"
+  android:scrollbars="vertical">
+
+  <LinearLayout style="@style/Widget.CoreSettings.Wrapper">
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:minHeight="48dp">
+
+      <android.support.v7.widget.AppCompatImageView
+        style="@style/Widget.CoreSettings.PrimaryItemIcon"
+        app:srcCompat="@drawable/ic_filter" />
+
+      <android.support.v7.widget.SwitchCompat
+        android:id="@+id/enabled"
+        style="@style/Widget.CoreSettings.PrimaryItemSwitch"
+        android:text="@string/settings_highlightrule_enabled" />
+    </LinearLayout>
+
+    <LinearLayout
+      style="@style/Widget.CoreSettings.DependentGroup"
+      android:visibility="visible">
+
+      <android.support.design.widget.TextInputLayout
+        style="@style/Widget.CoreSettings.EditTextLayout"
+        android:hint="@string/settings_highlightrule_name">
+
+        <android.support.design.widget.TextInputEditText
+          android:id="@+id/name"
+          style="@style/Widget.CoreSettings.EditText"
+          tools:text="https://clbin.com/*.jpg*" />
+      </android.support.design.widget.TextInputLayout>
+
+      <android.support.v7.widget.SwitchCompat
+        android:id="@+id/is_regex"
+        style="@style/Widget.CoreSettings.PrimaryItemSwitch"
+        android:text="@string/settings_highlightrule_regular_expression" />
+
+      <android.support.v7.widget.SwitchCompat
+        android:id="@+id/is_case_sensitive"
+        style="@style/Widget.CoreSettings.PrimaryItemSwitch"
+        android:text="@string/settings_highlightrule_case_sensitive" />
+
+      <android.support.design.widget.TextInputLayout
+        style="@style/Widget.CoreSettings.EditTextLayout"
+        android:hint="@string/settings_highlightrule_sender">
+
+        <android.support.design.widget.TextInputEditText
+          android:id="@+id/sender"
+          style="@style/Widget.CoreSettings.EditText"
+          tools:text="TARS" />
+      </android.support.design.widget.TextInputLayout>
+
+      <android.support.design.widget.TextInputLayout
+        style="@style/Widget.CoreSettings.EditTextLayout"
+        android:hint="@string/settings_highlightrule_channel">
+
+        <android.support.design.widget.TextInputEditText
+          android:id="@+id/channel"
+          style="@style/Widget.CoreSettings.EditText"
+          tools:text="#yepityha" />
+      </android.support.design.widget.TextInputLayout>
+    </LinearLayout>
+  </LinearLayout>
+</android.support.v4.widget.NestedScrollView>
diff --git a/app/src/main/res/layout/settings_ignoreitem.xml b/app/src/main/res/layout/settings_ignoreitem.xml
index cec671aa9..49e81f1dd 100644
--- a/app/src/main/res/layout/settings_ignoreitem.xml
+++ b/app/src/main/res/layout/settings_ignoreitem.xml
@@ -32,7 +32,7 @@
         android:hint="@string/settings_ignoreitem_ignorerule">
 
         <android.support.design.widget.TextInputEditText
-          android:id="@+id/ignorerule"
+          android:id="@+id/ignore_rule"
           style="@style/Widget.CoreSettings.EditText"
           tools:text="https://clbin.com/*.jpg*" />
       </android.support.design.widget.TextInputLayout>
@@ -98,7 +98,7 @@
         android:hint="@string/settings_ignoreitem_scoperule">
 
         <android.support.design.widget.TextInputEditText
-          android:id="@+id/scoperule"
+          android:id="@+id/scope_rule"
           style="@style/Widget.CoreSettings.EditText"
           tools:text="https://clbin.com/*.jpg*" />
       </android.support.design.widget.TextInputLayout>
diff --git a/app/src/main/res/layout/settings_ignorelist_item.xml b/app/src/main/res/layout/settings_ignorelist_item.xml
index 0f716b7f8..c1cc3a59b 100644
--- a/app/src/main/res/layout/settings_ignorelist_item.xml
+++ b/app/src/main/res/layout/settings_ignorelist_item.xml
@@ -29,6 +29,38 @@
       app:srcCompat="@drawable/ic_reorder"
       app:tint="?colorTextSecondary" />
 
+    <LinearLayout
+      android:layout_width="0dip"
+      android:layout_height="wrap_content"
+      android:layout_weight="1"
+      android:orientation="vertical"
+      android:paddingBottom="16dp"
+      android:paddingTop="16dp">
+
+      <TextView
+        android:id="@+id/ignore_rule"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:orientation="vertical"
+        android:singleLine="true"
+        android:textAppearance="?android:textAppearanceMedium"
+        android:textColor="?colorTextPrimary"
+        android:textSize="16sp"
+        tools:text="SoniEx2" />
+
+      <TextView
+        android:id="@+id/scope_rule"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:textAppearance="?textAppearanceListItemSecondary"
+        android:textColor="?colorTextSecondary"
+        tools:text="#quasseldroid" />
+
+    </LinearLayout>
+
     <TextView
       android:id="@+id/title"
       android:layout_width="0dip"
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 3024c896e..09415fbd4 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -42,6 +42,8 @@
   <string name="label_mention_long">Kopiert den Nutzernamen in die Eingabezeile</string>
   <string name="label_new_account">Account hinzufügen</string>
   <string name="label_new_chatlist">Chatliste hinzufügen</string>
+  <string name="label_new_highlight_rule">Neue Hervorhebungsregel</string>
+  <string name="label_new_highlight_ignore_rule">Neue Hervorhebungsignorierregel</string>
   <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>
diff --git a/app/src/main/res/values-de/strings_settings.xml b/app/src/main/res/values-de/strings_settings.xml
index af48a964e..0e748aa91 100644
--- a/app/src/main/res/values-de/strings_settings.xml
+++ b/app/src/main/res/values-de/strings_settings.xml
@@ -96,8 +96,21 @@
   <string name="settings_ignoreitem_scoperule">Gültigkeitsregel</string>
 
   <string name="settings_highlightlist_title">Hervorhebungen</string>
+  <string name="settings_highlightlist_highlight_nick">Hervorgehobene Spitznamen</string>
+  <string name="settings_highlightlist_highlight_nick_all_nicks">Alle Spitznamen aus Identität</string>
+  <string name="settings_highlightlist_highlight_nick_current_nick">Aktueller Spitzname</string>
+  <string name="settings_highlightlist_highlight_nick_none">Keine</string>
+  <string name="settings_highlightlist_nicks_case_sensitive">Groß-/Kleinschreibung beachten</string>
+  <string name="settings_highlightlist_rules">Hervorhebungsregeln</string>
+  <string name="settings_highlightlist_ignore_rules">Hervorhebungsignorierregeln</string>
 
   <string name="settings_highlightrule_title">Hervorhebungsregel</string>
+  <string name="settings_highlightrule_enabled">Aktiviert</string>
+  <string name="settings_highlightrule_name">Name</string>
+  <string name="settings_highlightrule_regular_expression">Regulärer Ausdruck</string>
+  <string name="settings_highlightrule_case_sensitive">Groß-/Kleinschreibung beachten</string>
+  <string name="settings_highlightrule_sender">Absender</string>
+  <string name="settings_highlightrule_channel">Raum</string>
 
   <string name="settings_aliaslist_title">Aliase</string>
 
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 74d3af40c..cb8bdcf66 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -42,6 +42,8 @@
   <string name="label_mention_long">Copy username into input line</string>
   <string name="label_new_account">New Account</string>
   <string name="label_new_chatlist">New Chatlist</string>
+  <string name="label_new_highlight_rule">New Highlight Rule</string>
+  <string name="label_new_highlight_ignore_rule">New Highlight Ignore Rule</string>
   <string name="label_new_identity">New Identity</string>
   <string name="label_new_network">New Network</string>
   <string name="label_new_nick">New Nick</string>
diff --git a/app/src/main/res/values/strings_settings.xml b/app/src/main/res/values/strings_settings.xml
index be879b38a..11a0943a3 100644
--- a/app/src/main/res/values/strings_settings.xml
+++ b/app/src/main/res/values/strings_settings.xml
@@ -96,8 +96,21 @@
   <string name="settings_ignoreitem_scoperule">Scope Rule</string>
 
   <string name="settings_highlightlist_title">Highlights</string>
+  <string name="settings_highlightlist_highlight_nick">Highlight Nick</string>
+  <string name="settings_highlightlist_highlight_nick_all_nicks">All Nicks from Identity</string>
+  <string name="settings_highlightlist_highlight_nick_current_nick">Current Nick</string>
+  <string name="settings_highlightlist_highlight_nick_none">None</string>
+  <string name="settings_highlightlist_nicks_case_sensitive">Case Sensitive</string>
+  <string name="settings_highlightlist_rules">Highlight Rules</string>
+  <string name="settings_highlightlist_ignore_rules">Highlight Ignore Rules</string>
 
   <string name="settings_highlightrule_title">Highlight Rule</string>
+  <string name="settings_highlightrule_enabled">Enabled</string>
+  <string name="settings_highlightrule_name">Name</string>
+  <string name="settings_highlightrule_regular_expression">Regular Expression</string>
+  <string name="settings_highlightrule_case_sensitive">Case Sensitive</string>
+  <string name="settings_highlightrule_sender">Sender</string>
+  <string name="settings_highlightrule_channel">Channel</string>
 
   <string name="settings_aliaslist_title">Aliases</string>
 
diff --git a/app/src/main/res/values/styles_widgets.xml b/app/src/main/res/values/styles_widgets.xml
index 3aa0809a3..6d8a4743f 100644
--- a/app/src/main/res/values/styles_widgets.xml
+++ b/app/src/main/res/values/styles_widgets.xml
@@ -39,6 +39,14 @@
     <item name="android:textColorSecondary">?colorTextSecondary</item>
   </style>
 
+  <style name="Widget.TabLayout.Auto" parent="Widget.Design.TabLayout">
+    <item name="tabIndicatorColor">?colorAccent</item>
+    <item name="tabIndicatorHeight">3dp</item>
+    <item name="tabBackground">?backgroundMenuItem</item>
+    <item name="tabSelectedTextColor">?colorAccent</item>
+    <item name="android:textColor">?colorTextPrimary</item>
+  </style>
+
   <style name="Widget.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
     <item name="color">?attr/colorControlNormal</item>
   </style>
-- 
GitLab