From 5f3e964a01f825e0bc10c731af6ecaffc476ec11 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Tue, 5 Feb 2019 13:52:00 +0100
Subject: [PATCH] Display the current new activity/messages/highlights status
 in toolbar

---
 app/src/main/AndroidManifest.xml              |   1 -
 .../service/QuasselNotificationBackend.kt     |   2 +-
 .../settings/NotificationSettings.kt          |   3 +-
 .../kuschku/quasseldroid/settings/Settings.kt |   4 +
 .../quasseldroid/ui/chat/ChatActivity.kt      | 100 ++++++++++++++-
 .../chat/buffers/BufferViewConfigFragment.kt  |  18 ++-
 .../ui/coresettings/CoreSettingsFragment.kt   |   2 +-
 .../highlightlist/HighlightListFragment.kt    |   2 +-
 .../info/channellist/ChannelListFragment.kt   |   4 +-
 .../kuschku/quasseldroid/util/ColorContext.kt |   2 +-
 .../drawable/DrawerToggleActivityDrawable.kt  | 116 ++++++++++++++++++
 .../ui/{ => drawable}/NickCountDrawable.kt    |   2 +-
 .../util/ui/{ => drawable}/TextDrawable.java  |   2 +-
 .../util/ui/{ => view}/BannerView.kt          |   2 +-
 .../util/ui/{ => view}/DrawerRecyclerView.kt  |   2 +-
 .../MaterialContentLoadingProgressBar.kt      |   2 +-
 .../ui/{ => view}/NavigationDrawerLayout.kt   |   2 +-
 .../{ => view}/RipplePassthroughTextView.kt   |   2 +-
 .../util/ui/{ => view}/ShadowView.kt          |   9 +-
 .../TouchInterceptingFrameLayout.kt           |   2 +-
 .../util/ui/{ => view}/WarningBarView.kt      |   5 +-
 .../main/res/drawable/ic_drawer_toggle.xml    |  34 +++++
 app/src/main/res/layout-land/layout_main.xml  |   4 +-
 .../res/layout-sw600dp-land/layout_main.xml   |   4 +-
 app/src/main/res/layout/activity_drawable.xml |  63 ++++++++++
 app/src/main/res/layout/activity_main.xml     |   4 +-
 app/src/main/res/layout/chat_chatlist.xml     |   2 +-
 app/src/main/res/layout/chat_nicklist.xml     |   2 +-
 app/src/main/res/layout/info_channellist.xml  |   4 +-
 app/src/main/res/layout/layout_history.xml    |   4 +-
 app/src/main/res/layout/layout_main.xml       |   4 +-
 app/src/main/res/layout/layout_toolbar.xml    |   2 +-
 .../res/layout/settings_highlightlist.xml     |   2 +-
 app/src/main/res/layout/settings_list.xml     |   2 +-
 .../widget_advertisement_support_patreon.xml  |   2 +-
 .../res/layout/widget_chatmessage_action.xml  |   2 +-
 .../layout/widget_chatmessage_daychange.xml   |   2 +-
 .../res/layout/widget_chatmessage_error.xml   |   2 +-
 .../res/layout/widget_chatmessage_info.xml    |   2 +-
 .../res/layout/widget_chatmessage_notice.xml  |   2 +-
 .../res/layout/widget_chatmessage_plain.xml   |   4 +-
 .../res/layout/widget_chatmessage_server.xml  |   2 +-
 app/src/main/res/values/attrs.xml             |   1 +
 app/src/main/res/values/dimens.xml            |   3 +
 .../main/res/values/strings_preferences.xml   |   4 +
 app/src/main/res/values/themes_amoled.xml     |   1 +
 app/src/main/res/values/themes_dracula.xml    |   1 +
 app/src/main/res/values/themes_gruvbox.xml    |   2 +
 app/src/main/res/values/themes_material.xml   |   2 +
 app/src/main/res/values/themes_quassel.xml    |   2 +
 app/src/main/res/values/themes_solarized.xml  |   2 +
 app/src/main/res/xml/preferences.xml          |   6 +
 .../persistence/dao/AccountDao.kt             |   4 +
 .../persistence/dao/FilteredDao.kt            |   4 +
 .../util/helper/ObservableHelper.kt           |  48 +++++++-
 .../viewmodel/QuasselViewModel.kt             |   1 -
 56 files changed, 447 insertions(+), 67 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => drawable}/NickCountDrawable.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => drawable}/TextDrawable.java (99%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/BannerView.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/DrawerRecyclerView.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/MaterialContentLoadingProgressBar.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/NavigationDrawerLayout.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/RipplePassthroughTextView.kt (97%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/ShadowView.kt (97%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/TouchInterceptingFrameLayout.kt (96%)
 rename app/src/main/java/de/kuschku/quasseldroid/util/ui/{ => view}/WarningBarView.kt (95%)
 create mode 100644 app/src/main/res/drawable/ic_drawer_toggle.xml
 create mode 100644 app/src/main/res/layout/activity_drawable.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bfad59094..6caf75e7f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -79,7 +79,6 @@
 
     <!-- Info -->
 
-
     <activity
       android:name="de.kuschku.quasseldroid.ui.info.user.UserInfoActivity"
       android:exported="false"
diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
index c5876e6ba..6818bdf08 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
@@ -54,7 +54,7 @@ import de.kuschku.quasseldroid.util.helper.letIf
 import de.kuschku.quasseldroid.util.helper.loadWithFallbacks
 import de.kuschku.quasseldroid.util.helper.styledAttributes
 import de.kuschku.quasseldroid.util.irc.format.ContentFormatter
-import de.kuschku.quasseldroid.util.ui.TextDrawable
+import de.kuschku.quasseldroid.util.ui.drawable.TextDrawable
 import de.kuschku.quasseldroid.viewmodel.EditorViewModel
 import org.threeten.bp.Instant
 import java.util.concurrent.Executors
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
index 8f73a0f26..d033f816f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/NotificationSettings.kt
@@ -27,7 +27,8 @@ data class NotificationSettings(
   val vibrate: Boolean = true,
   val light: Boolean = true,
   val markReadOnSwipe: Boolean = true,
-  val networkNameInNotificationTitle: Boolean = false
+  val networkNameInNotificationTitle: Boolean = false,
+  val showAllActivitiesInToolbar: Boolean = false
 ) {
   enum class Level {
     ALL,
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 638755126..90b4d1701 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt
@@ -175,6 +175,10 @@ object Settings {
       networkNameInNotificationTitle = getBoolean(
         context.getString(R.string.preference_notification_network_name_in_notification_title_key),
         NotificationSettings.DEFAULT.networkNameInNotificationTitle
+      ),
+      showAllActivitiesInToolbar = getBoolean(
+        context.getString(R.string.preference_notification_show_all_activities_in_toolbar_key),
+        NotificationSettings.DEFAULT.showAllActivitiesInToolbar
       )
     )
   }
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 61c4db0e1..ddd522db5 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
@@ -58,6 +58,7 @@ import de.kuschku.libquassel.session.ISession
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.flag.and
 import de.kuschku.libquassel.util.flag.hasFlag
+import de.kuschku.libquassel.util.flag.minus
 import de.kuschku.libquassel.util.flag.or
 import de.kuschku.libquassel.util.helpers.nullIf
 import de.kuschku.libquassel.util.helpers.value
@@ -74,6 +75,7 @@ import de.kuschku.quasseldroid.persistence.models.SslHostnameWhitelistEntry
 import de.kuschku.quasseldroid.persistence.models.SslValidityWhitelistEntry
 import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
+import de.kuschku.quasseldroid.settings.NotificationSettings
 import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.chat.input.AutoCompleteAdapter
 import de.kuschku.quasseldroid.ui.chat.input.ChatlineFragment
@@ -92,9 +94,10 @@ import de.kuschku.quasseldroid.util.missingfeatures.MissingFeaturesDialog
 import de.kuschku.quasseldroid.util.missingfeatures.RequiredFeatures
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
 import de.kuschku.quasseldroid.util.ui.DragInterceptBottomSheetBehavior
-import de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
-import de.kuschku.quasseldroid.util.ui.NickCountDrawable
-import de.kuschku.quasseldroid.util.ui.WarningBarView
+import de.kuschku.quasseldroid.util.ui.drawable.DrawerToggleActivityDrawable
+import de.kuschku.quasseldroid.util.ui.drawable.NickCountDrawable
+import de.kuschku.quasseldroid.util.ui.view.MaterialContentLoadingProgressBar
+import de.kuschku.quasseldroid.util.ui.view.WarningBarView
 import de.kuschku.quasseldroid.viewmodel.data.BufferData
 import io.reactivex.BackpressureStrategy
 import org.threeten.bp.Instant
@@ -135,6 +138,9 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
   @Inject
   lateinit var messageSettings: MessageSettings
 
+  @Inject
+  lateinit var notificationSettings: NotificationSettings
+
   @Inject
   lateinit var ircFormatDeserializer: IrcFormatDeserializer
 
@@ -296,6 +302,84 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       }
     })
 
+    val maxBufferActivity = combineLatest(
+      viewModel.bufferList,
+      database.filtered().listenRx(accountId).toObservable().map {
+        it.associateBy(Filtered::bufferId, Filtered::filtered)
+      },
+      accountDatabase.accounts().listenDefaultFiltered(accountId, 0).toObservable()
+    ).map { (info, filteredList, defaultFiltered) ->
+      val (config, bufferList) = info
+
+      val minimumActivity = config?.minimumActivity()?.enabledValues()?.max()
+                            ?: Buffer_Activity.NoActivity
+
+      val maxActivity = bufferList.asSequence().map { props ->
+        val activity = props.activity - Message_Type.of(filteredList[props.info.bufferId]?.toUInt()
+                                                        ?: defaultFiltered?.toUInt()
+                                                        ?: 0u)
+        when {
+          props.highlights > 0                  -> Buffer_Activity.Highlight
+          activity.hasFlag(Message_Type.Plain) ||
+          activity.hasFlag(Message_Type.Notice) ||
+          activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage
+          activity.isNotEmpty()                 -> Buffer_Activity.OtherActivity
+          else                                  -> Buffer_Activity.NoActivity
+        }
+      }.max() ?: Buffer_Activity.NoActivity
+
+      val hasNotifications = bufferList.any { props ->
+        val activity = props.activity - Message_Type.of(filteredList[props.info.bufferId]?.toUInt()
+                                                        ?: defaultFiltered?.toUInt()
+                                                        ?: 0u)
+        when {
+          props.info.type hasFlag Buffer_Type.QueryBuffer   ->
+            activity.hasFlag(Message_Type.Plain) ||
+            activity.hasFlag(Message_Type.Notice) ||
+            activity.hasFlag(Message_Type.Action)
+          props.info.type hasFlag Buffer_Type.ChannelBuffer ->
+            props.highlights > 0
+          else                                              -> false
+        }
+      }
+
+      Pair(
+        if (maxActivity < minimumActivity) Buffer_Activity.NoActivity
+        else maxActivity,
+        hasNotifications
+      )
+    }
+
+    supportActionBar?.apply {
+      val toggleDefault = DrawerToggleActivityDrawable(themedContext, 0)
+      val toggleOtherActivity = DrawerToggleActivityDrawable(themedContext,
+                                                             R.attr.colorTintActivity)
+      val toggleNewMessage = DrawerToggleActivityDrawable(themedContext, R.attr.colorTintMessage)
+      val toggleHighlight = DrawerToggleActivityDrawable(themedContext, R.attr.colorTintHighlight)
+      val toggleNotification = DrawerToggleActivityDrawable(themedContext,
+                                                            R.attr.colorTintNotification)
+      maxBufferActivity.toLiveData().observe(this@ChatActivity,
+                                             Observer { (activity, hasNotifications) ->
+        setHomeAsUpIndicator(
+          when {
+            notificationSettings.showAllActivitiesInToolbar &&
+            activity == Buffer_Activity.Highlight     ->
+              toggleHighlight
+            notificationSettings.showAllActivitiesInToolbar &&
+            activity == Buffer_Activity.NewMessage    ->
+              toggleNewMessage
+            notificationSettings.showAllActivitiesInToolbar &&
+            activity == Buffer_Activity.OtherActivity ->
+              toggleOtherActivity
+            hasNotifications                          ->
+              toggleNotification
+            else                                      ->
+              toggleDefault
+          }
+        )
+      })
+    }
+
     if (autoCompleteSettings.prefix || autoCompleteSettings.auto) {
       val autoCompleteBottomSheet = BottomSheetBehavior.from(autoCompleteList)
       chatlineFragment?.let {
@@ -780,6 +864,9 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     if (Settings.message(this) != messageSettings) {
       recreate()
     }
+    if (Settings.notification(this) != notificationSettings) {
+      recreate()
+    }
     super.onStart()
   }
 
@@ -825,9 +912,10 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       (bufferData?.info?.type?.hasFlag(Buffer_Type.ChannelBuffer) ?: false ||
        bufferData?.info?.type?.hasFlag(Buffer_Type.QueryBuffer) ?: false)
     menu?.retint(toolbar.context)
-    menu?.findItem(R.id.action_nicklist)?.icon = NickCountDrawable(bufferData?.userCount ?: 0,
-                                                                   nickCountDrawableSize,
-                                                                   nickCountDrawableColor)
+    menu?.findItem(R.id.action_nicklist)?.icon = NickCountDrawable(
+      bufferData?.userCount ?: 0,
+      nickCountDrawableSize,
+      nickCountDrawableColor)
     return super.onCreateOptionsMenu(menu)
   }
 
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 80ebec8a8..2acc5cbca 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
@@ -63,7 +63,7 @@ import de.kuschku.quasseldroid.util.avatars.AvatarHelper
 import de.kuschku.quasseldroid.util.helper.*
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
-import de.kuschku.quasseldroid.util.ui.WarningBarView
+import de.kuschku.quasseldroid.util.ui.view.WarningBarView
 import de.kuschku.quasseldroid.viewmodel.data.BufferHiddenState
 import de.kuschku.quasseldroid.viewmodel.data.BufferListItem
 import de.kuschku.quasseldroid.viewmodel.data.BufferState
@@ -317,24 +317,22 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
 
     combineLatest(viewModel.bufferList,
                   viewModel.expandedNetworks,
-                  viewModel.selectedBuffer).toLiveData().switchMapNotNull { a ->
-      database.filtered().listen(accountId).zip(accountDatabase.accounts().listen(accountId)).map { (b, c) ->
-        Triple(a, b, c)
-      }
-    }.observe(this, Observer { it ->
-      it?.let { (data, activityList, account) ->
+                  viewModel.selectedBuffer,
+                  database.filtered().listenRx(accountId).toObservable(),
+                  accountDatabase.accounts().listenDefaultFiltered(accountId, 0).toObservable()
+    ).toLiveData().observe(this, Observer { it ->
+      it?.let { (info, expandedNetworks, selected, filteredList, defaultFiltered) ->
         runInBackground {
-          val (info, expandedNetworks, selected) = data
           val (config, list) = info ?: Pair(null, emptyList())
           val minimumActivity = config?.minimumActivity() ?: Buffer_Activity.NONE
-          val activities = activityList.associate { it.bufferId to it.filtered.toUInt() }
+          val activities = filteredList.associate { it.bufferId to it.filtered.toUInt() }
           val processedList = list.asSequence().sortedBy { props ->
             !props.info.type.hasFlag(Buffer_Type.StatusBuffer)
           }.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { props ->
             props.network.networkName
           }).map { props ->
             val activity = props.activity - (activities[props.info.bufferId]
-                                             ?: account?.defaultFiltered?.toUInt()
+                                             ?: defaultFiltered?.toUInt()
                                              ?: 0u)
             BufferListItem(
               props.copy(
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 33ce70726..d1c2c46ab 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
@@ -56,7 +56,7 @@ import de.kuschku.quasseldroid.util.missingfeatures.MissingFeature
 import de.kuschku.quasseldroid.util.missingfeatures.MissingFeaturesDialog
 import de.kuschku.quasseldroid.util.missingfeatures.RequiredFeatures
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
-import de.kuschku.quasseldroid.util.ui.BannerView
+import de.kuschku.quasseldroid.util.ui.view.BannerView
 import io.reactivex.Observable
 
 class CoreSettingsFragment : ServiceBoundFragment() {
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 a7e1d7646..eb777d056 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
@@ -42,10 +42,10 @@ import de.kuschku.libquassel.util.Optional
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.highlightrule.HighlightRuleActivity
 import de.kuschku.quasseldroid.util.helper.toLiveData
-import de.kuschku.quasseldroid.util.ui.WarningBarView
 import de.kuschku.quasseldroid.util.ui.settings.fragment.Changeable
 import de.kuschku.quasseldroid.util.ui.settings.fragment.Savable
 import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFragment
+import de.kuschku.quasseldroid.util.ui.view.WarningBarView
 
 class HighlightListFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
   @BindView(R.id.feature_context_coresidehighlights)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
index b8e1baf97..5ceb32c8f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
@@ -40,9 +40,9 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.retint
 import de.kuschku.quasseldroid.util.helper.toLiveData
-import de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
-import de.kuschku.quasseldroid.util.ui.WarningBarView
 import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFragment
+import de.kuschku.quasseldroid.util.ui.view.MaterialContentLoadingProgressBar
+import de.kuschku.quasseldroid.util.ui.view.WarningBarView
 import io.reactivex.subjects.BehaviorSubject
 import javax.inject.Inject
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
index 5f6be2fad..1d575c0a4 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
@@ -26,7 +26,7 @@ import de.kuschku.libquassel.util.irc.SenderColorUtil
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.util.helper.styledAttributes
-import de.kuschku.quasseldroid.util.ui.TextDrawable
+import de.kuschku.quasseldroid.util.ui.drawable.TextDrawable
 import de.kuschku.quasseldroid.viewmodel.EditorViewModel
 import javax.inject.Inject
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
new file mode 100644
index 000000000..a7568a11c
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
@@ -0,0 +1,116 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid.util.ui.drawable
+
+import android.content.Context
+import android.graphics.*
+import android.graphics.drawable.Drawable
+import androidx.annotation.ColorRes
+import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.util.helper.styledAttributes
+
+class DrawerToggleActivityDrawable(context: Context, @ColorRes colorAttribute: Int) : Drawable() {
+  private val size = context.resources.getDimensionPixelSize(R.dimen.drawer_toggle_size)
+  private val thickness = context.resources.getDimension(R.dimen.drawer_toggle_thickness)
+
+  private val overlayPaint = Paint().apply {
+    color = context.theme.styledAttributes(colorAttribute) {
+      getColor(0, 0)
+    }
+    style = Paint.Style.FILL
+    isAntiAlias = true
+  }
+
+  private val togglePaint = Paint().apply {
+    color = context.theme.styledAttributes(R.attr.colorControlNormal) {
+      getColor(0, 0)
+    }
+    style = Paint.Style.STROKE
+    strokeJoin = Paint.Join.MITER
+    strokeCap = Paint.Cap.BUTT
+    isAntiAlias = true
+    strokeWidth = thickness
+  }
+
+
+  private val overlayPath = Path().apply {
+    arcTo(RectF(22f, 22f, 24f, 24f), 0f, 90f)
+    arcTo(RectF(16f, 22f, 18f, 24f), 90f, 90f)
+    arcTo(RectF(16f, 16f, 18f, 18f), 180f, 90f)
+    arcTo(RectF(22f, 16f, 24f, 18f), 270f, 90f)
+    close()
+  }
+
+  private val togglePath = Path().apply {
+    // top bar
+    moveTo(3f, 7f)
+    rLineTo(18f, 0f)
+
+    // draw middle bar
+    moveTo(3f, 12f)
+    rLineTo(18f, 0f)
+
+    // bottom bar
+    moveTo(3f, 17f)
+    rLineTo(18f, 0f)
+  }
+
+  override fun getIntrinsicHeight() = size
+  override fun getIntrinsicWidth() = size
+
+  // Not supported
+  override fun setAlpha(alpha: Int) = Unit
+
+  override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
+
+  // Not supported
+  override fun setColorFilter(colorFilter: ColorFilter?) = Unit
+
+  private val transformationMatrix = Matrix()
+  private val transformedOverlayPath = Path()
+  private val transformedTogglePath = Path()
+
+  private fun transformPaths() {
+    transformationMatrix.reset()
+    transformationMatrix.apply {
+      val smallestDimension = Math.min(bounds.width(), bounds.height())
+      preScale(smallestDimension / 24f, smallestDimension / 24f, 0f, 0f)
+    }
+
+    transformedOverlayPath.set(overlayPath)
+    transformedOverlayPath.transform(transformationMatrix)
+    transformedTogglePath.set(togglePath)
+    transformedTogglePath.transform(transformationMatrix)
+  }
+
+  override fun onBoundsChange(bounds: Rect?) {
+    transformPaths()
+  }
+
+  override fun draw(canvas: Canvas) {
+    if (bounds.width() <= 0 || bounds.height() <= 0) {
+      // Nothing to draw
+      return
+    }
+
+    canvas.drawPath(transformedTogglePath, togglePaint)
+    canvas.drawPath(transformedOverlayPath, overlayPaint)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/NickCountDrawable.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/NickCountDrawable.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/NickCountDrawable.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/NickCountDrawable.kt
index 6fcb4f204..0083c0943 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/NickCountDrawable.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/NickCountDrawable.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.drawable
 
 import android.graphics.*
 import android.graphics.drawable.Drawable
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/TextDrawable.java
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/TextDrawable.java
index 7372d0e14..fb7de1424 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/TextDrawable.java
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/TextDrawable.java
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui;
+package de.kuschku.quasseldroid.util.ui.drawable;
 
 import android.graphics.Canvas;
 import android.graphics.Color;
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/BannerView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/BannerView.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
index 75d874afe..49ab369a7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/BannerView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.content.Context
 import android.util.AttributeSet
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/DrawerRecyclerView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/DrawerRecyclerView.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/DrawerRecyclerView.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/DrawerRecyclerView.kt
index 95c9fe4e2..9477fae25 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/DrawerRecyclerView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/DrawerRecyclerView.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.content.Context
 import android.graphics.Canvas
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/MaterialContentLoadingProgressBar.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/MaterialContentLoadingProgressBar.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/MaterialContentLoadingProgressBar.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/MaterialContentLoadingProgressBar.kt
index 36141fd17..9b68afc56 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/MaterialContentLoadingProgressBar.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/MaterialContentLoadingProgressBar.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.content.Context
 import android.util.AttributeSet
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/NavigationDrawerLayout.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/NavigationDrawerLayout.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/NavigationDrawerLayout.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/NavigationDrawerLayout.kt
index c8050e509..14dcca512 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/NavigationDrawerLayout.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/NavigationDrawerLayout.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.content.Context
 import android.graphics.Canvas
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/RipplePassthroughTextView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/RipplePassthroughTextView.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/RipplePassthroughTextView.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/RipplePassthroughTextView.kt
index 1121d22f9..2a16bd876 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/RipplePassthroughTextView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/RipplePassthroughTextView.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.annotation.SuppressLint
 import android.content.Context
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ShadowView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/ShadowView.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/ShadowView.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/ShadowView.kt
index a79345e86..89636356e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ShadowView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/ShadowView.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.annotation.SuppressLint
 import android.content.Context
@@ -153,7 +153,12 @@ class ShadowView : View {
       }
     }
 
-    paintDrawable.shaderFactory = ShadowShaderFactory(x0, y0, x1, y1, stopColors)
+    paintDrawable.shaderFactory = ShadowShaderFactory(
+      x0,
+      y0,
+      x1,
+      y1,
+      stopColors)
     cubicGradientScrimCache.put(cacheKeyHash, paintDrawable)
     return paintDrawable
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/TouchInterceptingFrameLayout.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/TouchInterceptingFrameLayout.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/TouchInterceptingFrameLayout.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/TouchInterceptingFrameLayout.kt
index ec65b3049..dd2408c48 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/TouchInterceptingFrameLayout.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/TouchInterceptingFrameLayout.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.annotation.SuppressLint
 import android.content.Context
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/WarningBarView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/util/ui/WarningBarView.kt
rename to app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
index 77338642c..414559ff3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/WarningBarView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.util.ui
+package de.kuschku.quasseldroid.util.ui.view
 
 import android.annotation.SuppressLint
 import android.content.Context
@@ -64,7 +64,8 @@ class WarningBarView : FrameLayout {
         text.text = it.getString(R.styleable.WarningBarView_text)
 
       if (it.hasValue(R.styleable.WarningBarView_mode))
-        setMode(it.getInt(R.styleable.WarningBarView_mode, MODE_NONE))
+        setMode(it.getInt(R.styleable.WarningBarView_mode,
+                          MODE_NONE))
     }
   }
 
diff --git a/app/src/main/res/drawable/ic_drawer_toggle.xml b/app/src/main/res/drawable/ic_drawer_toggle.xml
new file mode 100644
index 000000000..536cfaf9f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_drawer_toggle.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2019 Janne Koschinski
+  Copyright (c) 2019 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+  android:width="24dp"
+  android:height="24dp"
+  android:viewportWidth="24"
+  android:viewportHeight="24">
+  <path
+    android:fillColor="#000"
+    android:pathData="
+    M20,6 a-1,1 0 0,0 1,1 a-1,1 0 0,0 -1,1 l -16,0 a-1,1 0 0,0 -1,-1 a-1,1 0 0,0 1,-1Z
+    M20,11 a-1,1 0 0,0 1,1 a-1,1 0 0,0 -1,1 l -16,0 a-1,1 0 0,0 -1,-1 a-1,1 0 0,0 1,-1Z
+    M20,16 a-1,1 0 0,0 1,1 a-1,1 0 0,0 -1,1 l -16,0 a-1,1 0 0,0 -1,-1 a-1,1 0 0,0 1,-1Z" />
+  <path
+    android:fillColor="#f00"
+    android:pathData="M16,17 16,23 A1,1 0 0,0 17,24 L 23,24 A1,1 0 0,0 24,23 L 24,17 A1,1 0 0,0 23,16 L 17,16 A1,1 0 0,0 16,17" />
+</vector>
diff --git a/app/src/main/res/layout-land/layout_main.xml b/app/src/main/res/layout-land/layout_main.xml
index 32ca88aea..d985f496f 100644
--- a/app/src/main/res/layout-land/layout_main.xml
+++ b/app/src/main/res/layout-land/layout_main.xml
@@ -44,7 +44,7 @@
         android:layout_height="match_parent"
         tools:layout="@layout/chat_messages" />
 
-      <de.kuschku.quasseldroid.util.ui.WarningBarView
+      <de.kuschku.quasseldroid.util.ui.view.WarningBarView
         android:id="@+id/connection_status"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -70,7 +70,7 @@
     app:layout_anchor="@id/fragment_chatline"
     app:layout_anchorGravity="top">
 
-    <de.kuschku.quasseldroid.util.ui.ShadowView
+    <de.kuschku.quasseldroid.util.ui.view.ShadowView
       android:layout_width="match_parent"
       android:layout_height="@dimen/shadow_height"
       android:gravity="bottom" />
diff --git a/app/src/main/res/layout-sw600dp-land/layout_main.xml b/app/src/main/res/layout-sw600dp-land/layout_main.xml
index 544a7eba4..c7b87d074 100644
--- a/app/src/main/res/layout-sw600dp-land/layout_main.xml
+++ b/app/src/main/res/layout-sw600dp-land/layout_main.xml
@@ -50,7 +50,7 @@
           android:layout_height="match_parent"
           tools:layout="@layout/chat_messages" />
 
-        <de.kuschku.quasseldroid.util.ui.WarningBarView
+        <de.kuschku.quasseldroid.util.ui.view.WarningBarView
           android:id="@+id/connection_status"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
@@ -76,7 +76,7 @@
       app:layout_anchor="@id/fragment_chatline"
       app:layout_anchorGravity="top">
 
-      <de.kuschku.quasseldroid.util.ui.ShadowView
+      <de.kuschku.quasseldroid.util.ui.view.ShadowView
         android:layout_width="match_parent"
         android:layout_height="@dimen/shadow_height"
         android:gravity="bottom" />
diff --git a/app/src/main/res/layout/activity_drawable.xml b/app/src/main/res/layout/activity_drawable.xml
new file mode 100644
index 000000000..77b93d314
--- /dev/null
+++ b/app/src/main/res/layout/activity_drawable.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2019 Janne Koschinski
+  Copyright (c) 2019 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
+  android:layout_width="match_parent"
+  android:layout_height="match_parent"
+  android:fitsSystemWindows="true">
+
+  <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
+    android:orientation="vertical">
+
+    <com.google.android.material.appbar.AppBarLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:theme="?attr/actionBarTheme"
+      tools:showIn="@layout/activity_main">
+
+      <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="?attr/actionBarSize"
+        app:popupTheme="?attr/actionBarPopupTheme" />
+
+    </com.google.android.material.appbar.AppBarLayout>
+
+    <androidx.appcompat.widget.AppCompatImageView
+      android:id="@+id/imageView"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:layout_gravity="center"
+      android:scaleType="fitCenter" />
+  </LinearLayout>
+
+  <de.kuschku.quasseldroid.util.ui.view.NavigationDrawerLayout
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="start"
+    android:background="?attr/colorBackground"
+    android:fitsSystemWindows="true"
+    app:insetBackground="?attr/colorPrimaryDark" />
+</androidx.drawerlayout.widget.DrawerLayout>
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 26d3f2772..2fb95e4db 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -35,7 +35,7 @@
     android:layout_gravity="end"
     tools:layout="@layout/chat_nicklist" />
 
-  <de.kuschku.quasseldroid.util.ui.NavigationDrawerLayout
+  <de.kuschku.quasseldroid.util.ui.view.NavigationDrawerLayout
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="start"
@@ -49,5 +49,5 @@
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       tools:layout="@layout/chat_chatlist" />
-  </de.kuschku.quasseldroid.util.ui.NavigationDrawerLayout>
+  </de.kuschku.quasseldroid.util.ui.view.NavigationDrawerLayout>
 </androidx.drawerlayout.widget.DrawerLayout>
diff --git a/app/src/main/res/layout/chat_chatlist.xml b/app/src/main/res/layout/chat_chatlist.xml
index ac57993a1..75ebdd6ad 100644
--- a/app/src/main/res/layout/chat_chatlist.xml
+++ b/app/src/main/res/layout/chat_chatlist.xml
@@ -52,7 +52,7 @@
 
   <include layout="@layout/widget_search" />
 
-  <de.kuschku.quasseldroid.util.ui.WarningBarView
+  <de.kuschku.quasseldroid.util.ui.view.WarningBarView
     android:id="@+id/feature_context_bufferactivitysync"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/chat_nicklist.xml b/app/src/main/res/layout/chat_nicklist.xml
index a88720877..aea2498eb 100644
--- a/app/src/main/res/layout/chat_nicklist.xml
+++ b/app/src/main/res/layout/chat_nicklist.xml
@@ -17,7 +17,7 @@
   with this program. If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<de.kuschku.quasseldroid.util.ui.DrawerRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
+<de.kuschku.quasseldroid.util.ui.view.DrawerRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/nickList"
   style="@style/Widget.FastScroller"
diff --git a/app/src/main/res/layout/info_channellist.xml b/app/src/main/res/layout/info_channellist.xml
index 8f5c85178..b65732687 100644
--- a/app/src/main/res/layout/info_channellist.xml
+++ b/app/src/main/res/layout/info_channellist.xml
@@ -70,7 +70,7 @@
 
       </LinearLayout>
 
-      <de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
+      <de.kuschku.quasseldroid.util.ui.view.MaterialContentLoadingProgressBar
         android:id="@+id/progress"
         style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
         android:layout_width="match_parent"
@@ -86,7 +86,7 @@
 
   </androidx.cardview.widget.CardView>
 
-  <de.kuschku.quasseldroid.util.ui.WarningBarView
+  <de.kuschku.quasseldroid.util.ui.view.WarningBarView
     android:id="@+id/error"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/layout_history.xml b/app/src/main/res/layout/layout_history.xml
index 5f394dda6..81533b8ea 100644
--- a/app/src/main/res/layout/layout_history.xml
+++ b/app/src/main/res/layout/layout_history.xml
@@ -17,7 +17,7 @@
   with this program. If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<de.kuschku.quasseldroid.util.ui.TouchInterceptingFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<de.kuschku.quasseldroid.util.ui.view.TouchInterceptingFrameLayout 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/card_panel"
@@ -84,4 +84,4 @@
         tools:listitem="@layout/widget_history_message" />
     </LinearLayout>
   </com.google.android.material.card.MaterialCardView>
-</de.kuschku.quasseldroid.util.ui.TouchInterceptingFrameLayout>
+</de.kuschku.quasseldroid.util.ui.view.TouchInterceptingFrameLayout>
diff --git a/app/src/main/res/layout/layout_main.xml b/app/src/main/res/layout/layout_main.xml
index 814ffe99a..4debac099 100644
--- a/app/src/main/res/layout/layout_main.xml
+++ b/app/src/main/res/layout/layout_main.xml
@@ -50,7 +50,7 @@
           android:layout_height="match_parent"
           tools:layout="@layout/chat_messages" />
 
-        <de.kuschku.quasseldroid.util.ui.WarningBarView
+        <de.kuschku.quasseldroid.util.ui.view.WarningBarView
           android:id="@+id/connection_status"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
@@ -77,7 +77,7 @@
       app:layout_anchor="@id/fragment_chatline"
       app:layout_anchorGravity="top">
 
-      <de.kuschku.quasseldroid.util.ui.ShadowView
+      <de.kuschku.quasseldroid.util.ui.view.ShadowView
         android:layout_width="match_parent"
         android:layout_height="@dimen/shadow_height"
         android:gravity="bottom" />
diff --git a/app/src/main/res/layout/layout_toolbar.xml b/app/src/main/res/layout/layout_toolbar.xml
index a76ad7d5a..6f9a1ca56 100644
--- a/app/src/main/res/layout/layout_toolbar.xml
+++ b/app/src/main/res/layout/layout_toolbar.xml
@@ -45,7 +45,7 @@
 
     </androidx.appcompat.widget.Toolbar>
 
-    <de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
+    <de.kuschku.quasseldroid.util.ui.view.MaterialContentLoadingProgressBar
       android:id="@+id/progress_bar"
       style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
       android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/settings_highlightlist.xml b/app/src/main/res/layout/settings_highlightlist.xml
index f9a6d8d15..98a68545c 100644
--- a/app/src/main/res/layout/settings_highlightlist.xml
+++ b/app/src/main/res/layout/settings_highlightlist.xml
@@ -29,7 +29,7 @@
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <de.kuschku.quasseldroid.util.ui.WarningBarView
+    <de.kuschku.quasseldroid.util.ui.view.WarningBarView
       android:id="@+id/feature_context_coresidehighlights"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/settings_list.xml b/app/src/main/res/layout/settings_list.xml
index ed9e18d6e..bd04bb2f7 100644
--- a/app/src/main/res/layout/settings_list.xml
+++ b/app/src/main/res/layout/settings_list.xml
@@ -29,7 +29,7 @@
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <de.kuschku.quasseldroid.util.ui.BannerView
+    <de.kuschku.quasseldroid.util.ui.view.BannerView
       android:id="@+id/feature_context_missing"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/widget_advertisement_support_patreon.xml b/app/src/main/res/layout/widget_advertisement_support_patreon.xml
index cba45df7a..d632687ac 100644
--- a/app/src/main/res/layout/widget_advertisement_support_patreon.xml
+++ b/app/src/main/res/layout/widget_advertisement_support_patreon.xml
@@ -17,7 +17,7 @@
   with this program. If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<de.kuschku.quasseldroid.util.ui.BannerView xmlns:android="http://schemas.android.com/apk/res/android"
+<de.kuschku.quasseldroid.util.ui.view.BannerView xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
diff --git a/app/src/main/res/layout/widget_chatmessage_action.xml b/app/src/main/res/layout/widget_chatmessage_action.xml
index 920bbfff2..6247fb6d2 100644
--- a/app/src/main/res/layout/widget_chatmessage_action.xml
+++ b/app/src/main/res/layout/widget_chatmessage_action.xml
@@ -82,7 +82,7 @@
         android:layout_weight="1"
         android:orientation="vertical">
 
-        <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+        <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
           android:id="@+id/combined"
           style="@style/Widget.RtlConformTextView"
           android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/widget_chatmessage_daychange.xml b/app/src/main/res/layout/widget_chatmessage_daychange.xml
index 2e42f5fa1..a726aa38c 100644
--- a/app/src/main/res/layout/widget_chatmessage_daychange.xml
+++ b/app/src/main/res/layout/widget_chatmessage_daychange.xml
@@ -44,7 +44,7 @@
       android:layout_weight="1"
       android:background="?colorDivider" />
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+    <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
       android:id="@+id/daychange"
       style="@style/Widget.RtlConformTextView"
       android:layout_width="wrap_content"
diff --git a/app/src/main/res/layout/widget_chatmessage_error.xml b/app/src/main/res/layout/widget_chatmessage_error.xml
index ab8642beb..3de2ee8ac 100644
--- a/app/src/main/res/layout/widget_chatmessage_error.xml
+++ b/app/src/main/res/layout/widget_chatmessage_error.xml
@@ -59,7 +59,7 @@
       android:layout_marginRight="@dimen/message_horizontal"
       android:visibility="gone" />
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+    <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
       android:id="@+id/combined"
       style="@style/Widget.RtlConformTextView"
       android:layout_width="0dip"
diff --git a/app/src/main/res/layout/widget_chatmessage_info.xml b/app/src/main/res/layout/widget_chatmessage_info.xml
index a0fdb5664..343ba2e65 100644
--- a/app/src/main/res/layout/widget_chatmessage_info.xml
+++ b/app/src/main/res/layout/widget_chatmessage_info.xml
@@ -59,7 +59,7 @@
       android:layout_marginRight="@dimen/message_horizontal"
       android:visibility="gone" />
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+    <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
       android:id="@+id/combined"
       style="@style/Widget.RtlConformTextView"
       android:layout_width="0dip"
diff --git a/app/src/main/res/layout/widget_chatmessage_notice.xml b/app/src/main/res/layout/widget_chatmessage_notice.xml
index 18c602811..86b8dad5e 100644
--- a/app/src/main/res/layout/widget_chatmessage_notice.xml
+++ b/app/src/main/res/layout/widget_chatmessage_notice.xml
@@ -59,7 +59,7 @@
       android:layout_marginRight="@dimen/message_horizontal"
       android:visibility="gone" />
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+    <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
       android:id="@+id/combined"
       style="@style/Widget.RtlConformTextView"
       android:layout_width="0dip"
diff --git a/app/src/main/res/layout/widget_chatmessage_plain.xml b/app/src/main/res/layout/widget_chatmessage_plain.xml
index 78871b4b7..3ead811a1 100644
--- a/app/src/main/res/layout/widget_chatmessage_plain.xml
+++ b/app/src/main/res/layout/widget_chatmessage_plain.xml
@@ -120,7 +120,7 @@
           android:layout_weight="1"
           android:orientation="vertical">
 
-          <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+          <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
             android:id="@+id/content"
             style="@style/Widget.RtlConformTextView"
             android:layout_width="match_parent"
@@ -130,7 +130,7 @@
             tools:text="@sample/messages.json/data/content"
             tools:visibility="visible" />
 
-          <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+          <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
             android:id="@+id/combined"
             style="@style/Widget.RtlConformTextView"
             android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/widget_chatmessage_server.xml b/app/src/main/res/layout/widget_chatmessage_server.xml
index 2d86eabcb..1d37298d0 100644
--- a/app/src/main/res/layout/widget_chatmessage_server.xml
+++ b/app/src/main/res/layout/widget_chatmessage_server.xml
@@ -59,7 +59,7 @@
       android:layout_marginRight="@dimen/message_horizontal"
       android:visibility="gone" />
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+    <de.kuschku.quasseldroid.util.ui.view.RipplePassthroughTextView
       android:id="@+id/combined"
       style="@style/Widget.RtlConformTextView"
       android:layout_width="0dip"
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 8f69f8835..d5376574b 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -71,6 +71,7 @@
   <attr name="colorTintActivity" format="color" />
   <attr name="colorTintMessage" format="color" />
   <attr name="colorTintHighlight" format="color" />
+  <attr name="colorTintNotification" format="color" />
 
   <!-- Icons -->
   <attr name="colorOffline" format="color" />
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 4b547ceca..605437ff6 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -44,4 +44,7 @@
   <dimen name="notification_avatar_width">64dp</dimen>
   <dimen name="notification_avatar_height">64dp</dimen>
   <dimen name="size_nick_count">24dp</dimen>
+
+  <dimen name="drawer_toggle_size">24dp</dimen>
+  <dimen name="drawer_toggle_thickness">2dp</dimen>
 </resources>
diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml
index 67f2b67d5..0eb423980 100644
--- a/app/src/main/res/values/strings_preferences.xml
+++ b/app/src/main/res/values/strings_preferences.xml
@@ -142,6 +142,10 @@
   <string name="preference_notification_network_name_in_notification_title_key" translatable="false">network_name_in_notification_title</string>
   <string name="preference_notification_network_name_in_notification_title_title">Show network name in notifications title</string>
 
+  <string name="preference_notification_show_all_activities_in_toolbar_key" translatable="false">show_all_activities_in_toolbar</string>
+  <string name="preference_notification_show_all_activities_in_toolbar_title">Mark all activities in toolbar</string>
+  <string name="preference_notification_show_all_activities_in_toolbar_summary">Displays a colored bubble in the toolbar for all chat activities</string>
+
   <string name="preference_notification_configure_key" translatable="false">notification_configure</string>
   <string name="preference_notification_configure_title">Configure Notifications</string>
 
diff --git a/app/src/main/res/values/themes_amoled.xml b/app/src/main/res/values/themes_amoled.xml
index 12cb0535b..ad82f60e1 100644
--- a/app/src/main/res/values/themes_amoled.xml
+++ b/app/src/main/res/values/themes_amoled.xml
@@ -74,6 +74,7 @@
     <item name="colorTintActivity">#88cc33</item>
     <item name="colorTintMessage">#2277dd</item>
     <item name="colorTintHighlight">#ff8811</item>
+    <item name="colorTintNotification">#D32F2F</item>
 
     <item name="colorTintSecure">#88cc33</item>
     <item name="colorTintPartiallySecure">#ffaf3b</item>
diff --git a/app/src/main/res/values/themes_dracula.xml b/app/src/main/res/values/themes_dracula.xml
index c92f2fd14..59b0adba4 100644
--- a/app/src/main/res/values/themes_dracula.xml
+++ b/app/src/main/res/values/themes_dracula.xml
@@ -78,6 +78,7 @@
     <item name="colorTintActivity">#6272a4</item>
     <item name="colorTintMessage">#acb2b7</item>
     <item name="colorTintHighlight">#f8f8f2</item>
+    <item name="colorTintNotification">#ff5555</item>
 
     <item name="colorTintSecure">#50fa7b</item>
     <item name="colorTintPartiallySecure">#ffb86c</item>
diff --git a/app/src/main/res/values/themes_gruvbox.xml b/app/src/main/res/values/themes_gruvbox.xml
index 87db8b04b..f107b8fb9 100644
--- a/app/src/main/res/values/themes_gruvbox.xml
+++ b/app/src/main/res/values/themes_gruvbox.xml
@@ -77,6 +77,7 @@
     <item name="colorTintActivity">#98971a</item>
     <item name="colorTintMessage">#458588</item>
     <item name="colorTintHighlight">#d65d0e</item>
+    <item name="colorTintNotification">#cc241d</item>
 
     <item name="colorTintSecure">#98971a</item>
     <item name="colorTintPartiallySecure">#d79921</item>
@@ -140,6 +141,7 @@
     <item name="colorTintActivity">#98971a</item>
     <item name="colorTintMessage">#458588</item>
     <item name="colorTintHighlight">#d65d0e</item>
+    <item name="colorTintNotification">#cc241d</item>
 
     <item name="colorTintSecure">#98971a</item>
     <item name="colorTintPartiallySecure">#d79921</item>
diff --git a/app/src/main/res/values/themes_material.xml b/app/src/main/res/values/themes_material.xml
index 2338b21dd..55511afe5 100644
--- a/app/src/main/res/values/themes_material.xml
+++ b/app/src/main/res/values/themes_material.xml
@@ -68,6 +68,7 @@
     <item name="colorTintActivity">#AFB42B</item>
     <item name="colorTintMessage">#1976D2</item>
     <item name="colorTintHighlight">#FFAB00</item>
+    <item name="colorTintNotification">#D32F2F</item>
 
     <item name="colorTintSecure">#4CAF50</item>
     <item name="colorTintPartiallySecure">#FFC107</item>
@@ -123,6 +124,7 @@
     <item name="colorTintActivity">#AFB42B</item>
     <item name="colorTintMessage">#42A5F5</item>
     <item name="colorTintHighlight">#FFAB00</item>
+    <item name="colorTintNotification">#D32F2F</item>
 
     <item name="colorTintSecure">#4CAF50</item>
     <item name="colorTintPartiallySecure">#FFC107</item>
diff --git a/app/src/main/res/values/themes_quassel.xml b/app/src/main/res/values/themes_quassel.xml
index d100967cd..2fb569c03 100644
--- a/app/src/main/res/values/themes_quassel.xml
+++ b/app/src/main/res/values/themes_quassel.xml
@@ -70,6 +70,7 @@
     <item name="colorTintActivity">#88cc33</item>
     <item name="colorTintMessage">#2277dd</item>
     <item name="colorTintHighlight">#ff8811</item>
+    <item name="colorTintNotification">#BB2222</item>
 
     <item name="colorTintSecure">#88cc33</item>
     <item name="colorTintPartiallySecure">#ffaf3b</item>
@@ -127,6 +128,7 @@
     <item name="colorTintActivity">#88cc33</item>
     <item name="colorTintMessage">#2277dd</item>
     <item name="colorTintHighlight">#ff8811</item>
+    <item name="colorTintNotification">#BB2222</item>
 
     <item name="colorTintSecure">#88cc33</item>
     <item name="colorTintPartiallySecure">#ffaf3b</item>
diff --git a/app/src/main/res/values/themes_solarized.xml b/app/src/main/res/values/themes_solarized.xml
index 384e93909..33383cc39 100644
--- a/app/src/main/res/values/themes_solarized.xml
+++ b/app/src/main/res/values/themes_solarized.xml
@@ -77,6 +77,7 @@
     <item name="colorTintActivity">#859900</item>
     <item name="colorTintMessage">#268BD2</item>
     <item name="colorTintHighlight">#EB6B36</item>
+    <item name="colorTintNotification">#DC322f</item>
 
     <item name="colorTintSecure">#859900</item>
     <item name="colorTintPartiallySecure">#D5A920</item>
@@ -141,6 +142,7 @@
     <item name="colorTintActivity">#859900</item>
     <item name="colorTintMessage">#268BD2</item>
     <item name="colorTintHighlight">#EB6B36</item>
+    <item name="colorTintNotification">#DC322f</item>
 
     <item name="colorTintSecure">#859900</item>
     <item name="colorTintPartiallySecure">#B58900</item>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 4609d67a2..ef32d4780 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -95,6 +95,12 @@
       android:key="@string/preference_notification_network_name_in_notification_title_key"
       android:title="@string/preference_notification_network_name_in_notification_title_title" />
 
+    <SwitchPreference
+      android:defaultValue="false"
+      android:key="@string/preference_notification_show_all_activities_in_toolbar_key"
+      android:summary="@string/preference_notification_show_all_activities_in_toolbar_summary"
+      android:title="@string/preference_notification_show_all_activities_in_toolbar_title" />
+
     <de.kuschku.quasseldroid.util.ui.settings.RingtonePreference
       android:defaultValue="content://settings/system/notification_sound"
       android:key="@string/preference_notification_sound_key"
diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt
index 0489423b5..8d6a438df 100644
--- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt
+++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt
@@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.persistence.dao
 import androidx.lifecycle.LiveData
 import androidx.room.*
 import de.kuschku.quasseldroid.persistence.models.Account
+import io.reactivex.Flowable
 
 @Dao
 interface AccountDao {
@@ -37,6 +38,9 @@ interface AccountDao {
   @Query("SELECT * FROM account WHERE id = :id")
   fun listen(id: Long): LiveData<Account?>
 
+  @Query("SELECT IFNULL(t.defaultFiltered, :defaultValue) FROM (SELECT defaultFiltered FROM account WHERE id = :id UNION SELECT NULL ORDER BY defaultFiltered DESC LIMIT 1) t")
+  fun listenDefaultFiltered(id: Long, defaultValue: Int): Flowable<Int>
+
   @Query("SELECT * FROM account ORDER BY lastUsed DESC")
   fun all(): LiveData<List<Account>>
 
diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt
index 186346c19..482547cc6 100644
--- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt
+++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt
@@ -28,6 +28,7 @@ import androidx.room.Query
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.BufferId_Type
 import de.kuschku.quasseldroid.persistence.models.Filtered
+import io.reactivex.Flowable
 
 @Dao
 interface FilteredDao {
@@ -49,6 +50,9 @@ interface FilteredDao {
   @Query("SELECT * FROM filtered WHERE accountId = :accountId")
   fun listen(accountId: Long): LiveData<List<Filtered>>
 
+  @Query("SELECT * FROM filtered WHERE accountId = :accountId")
+  fun listenRx(accountId: Long): Flowable<List<Filtered>>
+
   @Query("DELETE FROM filtered")
   fun clear()
 
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
index c28eab4ca..92edd739a 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
@@ -55,8 +55,8 @@ inline fun <reified A, B, C> combineLatest(
   b: ObservableSource<B>,
   c: ObservableSource<C>
 ): Observable<Triple<A, B, C>> =
-  Observable.combineLatest(listOf(a, b, c)) { (t0, t1, t2) ->
-    Triple(t0, t1, t2) as Triple<A, B, C>
+  Observable.combineLatest(listOf(a, b, c)) {
+    Triple(it[0], it[1], it[2]) as Triple<A, B, C>
   }
 
 inline fun <reified A, B, C, D> combineLatest(
@@ -65,8 +65,31 @@ inline fun <reified A, B, C, D> combineLatest(
   c: ObservableSource<C>,
   d: ObservableSource<D>
 ): Observable<Tuple4<A, B, C, D>> =
-  Observable.combineLatest(listOf(a, b, c, d)) { (t0, t1, t2, t3) ->
-    Tuple4(t0, t1, t2, t3) as Tuple4<A, B, C, D>
+  Observable.combineLatest(listOf(a, b, c, d)) {
+    Tuple4(it[0], it[1], it[2], it[3]) as Tuple4<A, B, C, D>
+  }
+
+inline fun <reified A, B, C, D, E> combineLatest(
+  a: ObservableSource<A>,
+  b: ObservableSource<B>,
+  c: ObservableSource<C>,
+  d: ObservableSource<D>,
+  e: ObservableSource<E>
+): Observable<Tuple5<A, B, C, D, E>> =
+  Observable.combineLatest(listOf(a, b, c, d, e)) {
+    Tuple5(it[0], it[1], it[2], it[3], it[4]) as Tuple5<A, B, C, D, E>
+  }
+
+inline fun <reified A, B, C, D, E, F> combineLatest(
+  a: ObservableSource<A>,
+  b: ObservableSource<B>,
+  c: ObservableSource<C>,
+  d: ObservableSource<D>,
+  e: ObservableSource<E>,
+  f: ObservableSource<F>
+): Observable<Tuple6<A, B, C, D, E, F>> =
+  Observable.combineLatest(listOf(a, b, c, d, e, f)) {
+    Tuple6(it[0], it[1], it[2], it[3], it[4], it[5]) as Tuple6<A, B, C, D, E, F>
   }
 
 inline fun <reified T> combineLatest(sources: Iterable<ObservableSource<out T>?>) =
@@ -81,3 +104,20 @@ data class Tuple4<out A, out B, out C, out D>(
   val third: C,
   val fourth: D
 )
+
+data class Tuple5<out A, out B, out C, out D, out E>(
+  val first: A,
+  val second: B,
+  val third: C,
+  val fourth: D,
+  val fifth: E
+)
+
+data class Tuple6<out A, out B, out C, out D, out E, out F>(
+  val first: A,
+  val second: B,
+  val third: C,
+  val fourth: D,
+  val fifth: E,
+  val sixth: F
+)
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
index c72c95560..1c2442851 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -174,7 +174,6 @@ class QuasselViewModel : ViewModel() {
     }
   }
 
-  // Remove orElse
   val lag: Observable<Long> = session.mapSwitchMap(ISession::lag).mapOrElse(0)
 
   val bufferData = combineLatest(session, buffer).switchMap { (sessionOptional, id) ->
-- 
GitLab