diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 6bf22e96c5132d991d6523421b70664b5ce2030a..94f488ed1706f2184d15015ddbe14fa11dae40ff 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -17,16 +17,6 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import org.gradle.api.Project
-import java.io.FileInputStream
-import java.util.*
-import org.gradle.api.artifacts.ExternalModuleDependency
-import org.gradle.kotlin.dsl.*
-import org.jetbrains.kotlin.gradle.plugin.KaptExtension
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import java.io.ByteArrayOutputStream
-import java.util.*
-
 plugins {
   id("com.android.application")
   kotlin("android")
@@ -115,7 +105,7 @@ android {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   // App Compat
   implementation("com.google.android.material", "material", "1.0.0-rc01")
diff --git a/app/sampledata/channels.json b/app/sampledata/channels.json
new file mode 100644
index 0000000000000000000000000000000000000000..60acd6fc5c9cd6de57d0881824f525a42e808aef
--- /dev/null
+++ b/app/sampledata/channels.json
@@ -0,0 +1,34 @@
+{
+  "data": [
+    {
+      "name": "#fdroid",
+      "topic": "Due to spam you temporarily need to be registered to speak. | https://f-droid.org | https://forum.f-droid.org | https://mastodon.technology/@fdroidorg | For development discussion use #fdroid-dev | This channel is logged via matrix at https://view.matrix.org/alias/%23fdroid:f-droid.org",
+      "users": "673 users"
+    },
+    {
+      "name": "#fdroid-dev",
+      "topic": "Due to spam you temporarily need to be registered to speak. | | F-Droid development discussion only, use #fdroid for general, app and repo-related matters | This channel is logged via matrix at https://view.matrix.org/alias/%23fdroid-dev:f-droid.org",
+      "users": "59 users"
+    },
+    {
+      "name": "#ircdocs",
+      "topic": "http://ircdocs.horse/ and associated projects - http://defs.ircdocs.horse/ - http://stats.ircdocs.horse/ - http://modern.ircdocs.horse/ - https://wooooms.ircdocs.horse/ - https://github.com/irc-archive/ - combating IRC spec nonsense, one document at a time <3        👌😩 < merivingian~",
+      "users": "54 users"
+    },
+    {
+      "name": "#ircv3",
+      "topic": "https://ircv3.net | Roadmap: https://git.io/IRCv3-Roadmap | Code of conduct: https://ircv3.net/conduct",
+      "users": "202 users"
+    },
+    {
+      "name": "#quassel",
+      "topic": "Quassel IRC - https://quassel-irc.org || Latest: 0.13.0 || Mailing Lists: https://lists.quassel-irc.org || Tracker: https://bugs.quassel-irc.org || Activity RSS: #quassel-announce || German: #quassel.de || Quassel on Android: #quasseldroid; on iOS: #woboquassel",
+      "users": "667 users"
+    },
+    {
+      "name": "#quasseldroid",
+      "topic": "Quasseldroid is an Android client for #quassel ♥ https://quasseldroid.info/ ♥ Requires a Quassel 0.13 Core for full functionality: https://quasseldroid.info/releases/ ♥ https://git.kuschku.de/justjanne/Quasseldroid-NG/",
+      "users": "165 users"
+    }
+  ]
+}
diff --git a/app/sampledata/libraries.json b/app/sampledata/libraries.json
index ef266d06dc6bb77e0c815f62ae7e2b23a133c1fc..8b776f74bd00a47f875a5e0703971f40acf0d962 100644
--- a/app/sampledata/libraries.json
+++ b/app/sampledata/libraries.json
@@ -152,7 +152,7 @@
     },
     {
       "name": "Kotlin Standard Library",
-      "version": "1.3.11",
+      "version": "1.3.20",
       "license": {
         "short_name": "Apache-2.0",
         "full_name": "Apache License"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a828efd2ab4c93590767fdfb65db980b7dc1c1f1..33dc972515c14f4478d64fe3c6970957fd1ae2cf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -76,33 +76,37 @@
         <data android:scheme="ircs" />
       </intent-filter>
     </activity>
+
+    <!-- Info -->
+
+
     <activity
-      android:name=".ui.chat.info.user.UserInfoActivity"
+      android:name="de.kuschku.quasseldroid.ui.info.user.UserInfoActivity"
       android:exported="false"
       android:label="@string/label_info_user"
       android:parentActivityName=".ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.chat.info.channel.ChannelInfoActivity"
+      android:name="de.kuschku.quasseldroid.ui.info.channel.ChannelInfoActivity"
       android:exported="false"
       android:label="@string/label_info_channel"
       android:parentActivityName=".ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.chat.info.core.CoreInfoActivity"
+      android:name="de.kuschku.quasseldroid.ui.info.core.CoreInfoActivity"
       android:exported="false"
       android:label="@string/label_info_core"
       android:parentActivityName=".ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.chat.topic.TopicActivity"
+      android:name="de.kuschku.quasseldroid.ui.info.topic.TopicActivity"
       android:exported="false"
       android:label="@string/label_topic"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.chat.passwordchange.PasswordChangeActivity"
+      android:name="de.kuschku.quasseldroid.ui.info.channellist.ChannelListActivity"
       android:exported="false"
-      android:label="@string/label_password_change"
+      android:label="@string/label_info_channellist"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Core Settings -->
@@ -195,6 +199,11 @@
       android:label="@string/settings_networkconfig_title"
       android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
+    <activity
+      android:name="de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeActivity"
+      android:exported="false"
+      android:label="@string/label_password_change"
+      android:windowSoftInputMode="adjustResize" />
 
     <!-- Client Settings -->
     <activity
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
index 8613fdf86f6c68bd4296f7d8b2f52d6720c643ed..fef17c67fec2aebd293a8a72c64b84db3d05331d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
@@ -26,15 +26,6 @@ import de.kuschku.quasseldroid.service.QuasselServiceModule
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.ui.chat.ChatActivityModule
 import de.kuschku.quasseldroid.ui.chat.ChatFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoActivity
-import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.info.core.CoreInfoActivity
-import de.kuschku.quasseldroid.ui.chat.info.core.CoreInfoFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity
-import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.passwordchange.PasswordChangeActivity
-import de.kuschku.quasseldroid.ui.chat.passwordchange.PasswordChangeFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity
 import de.kuschku.quasseldroid.ui.chat.topic.TopicFragmentProvider
 import de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity
 import de.kuschku.quasseldroid.ui.clientsettings.about.AboutFragmentProvider
@@ -76,6 +67,17 @@ import de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigActivi
 import de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigFragmentProvider
 import de.kuschku.quasseldroid.ui.coresettings.networkserver.NetworkServerActivity
 import de.kuschku.quasseldroid.ui.coresettings.networkserver.NetworkServerFragmentProvider
+import de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeActivity
+import de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeFragmentProvider
+import de.kuschku.quasseldroid.ui.info.channel.ChannelInfoActivity
+import de.kuschku.quasseldroid.ui.info.channel.ChannelInfoFragmentProvider
+import de.kuschku.quasseldroid.ui.info.channellist.ChannelListActivity
+import de.kuschku.quasseldroid.ui.info.channellist.ChannelListFragmentProvider
+import de.kuschku.quasseldroid.ui.info.core.CoreInfoActivity
+import de.kuschku.quasseldroid.ui.info.core.CoreInfoFragmentProvider
+import de.kuschku.quasseldroid.ui.info.topic.TopicActivity
+import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity
+import de.kuschku.quasseldroid.ui.info.user.UserInfoFragmentProvider
 import de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity
 import de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditFragmentProvider
 import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity
@@ -112,8 +114,10 @@ abstract class ActivityModule {
   abstract fun bindTopicActivity(): TopicActivity
 
   @ActivityScope
-  @ContributesAndroidInjector(modules = [PasswordChangeFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
-  abstract fun bindPasswordChangeActivity(): PasswordChangeActivity
+  @ContributesAndroidInjector(modules = [ChannelListFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
+  abstract fun bindChannelListActivity(): ChannelListActivity
+
+  // Client Settings
 
   @ActivityScope
   @ContributesAndroidInjector(modules = [ClientSettingsFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
@@ -135,6 +139,8 @@ abstract class ActivityModule {
   @ContributesAndroidInjector(modules = [LicenseFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
   abstract fun bindLicenseActivity(): LicenseActivity
 
+  // Core Settings
+
   @ActivityScope
   @ContributesAndroidInjector(modules = [CoreSettingsFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
   abstract fun bindCoreSettingsActivity(): CoreSettingsActivity
@@ -195,6 +201,12 @@ abstract class ActivityModule {
   @ContributesAndroidInjector(modules = [NetworkConfigFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
   abstract fun bindNetworkConfigActivity(): NetworkConfigActivity
 
+  @ActivityScope
+  @ContributesAndroidInjector(modules = [PasswordChangeFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
+  abstract fun bindPasswordChangeActivity(): PasswordChangeActivity
+
+  // Setup
+
   @ActivityScope
   @ContributesAndroidInjector(modules = [AccountSetupFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
   abstract fun bindAccountSetupActivity(): AccountSetupActivity
@@ -219,6 +231,8 @@ abstract class ActivityModule {
   @ContributesAndroidInjector(modules = [CoreSetupFragmentProvider::class, SettingsModule::class, DatabaseModule::class, ActivityBaseModule::class])
   abstract fun bindCoreSetupActivity(): CoreSetupActivity
 
+   // Service
+
   @ActivityScope
   @ContributesAndroidInjector(modules = [QuasselServiceModule::class, SettingsModule::class, DatabaseModule::class])
   abstract fun bindQuasselService(): QuasselService
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
index ffe2a1e1ffb49b2141a4622330b8246f3b766d0f..b12d68196802f5c2c0a6db28bd3f59401a538210 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
@@ -36,8 +36,8 @@ import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
-import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoActivity
-import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity
+import de.kuschku.quasseldroid.ui.info.channel.ChannelInfoActivity
+import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity
 import de.kuschku.quasseldroid.util.ColorContext
 import de.kuschku.quasseldroid.util.avatars.AvatarHelper
 import de.kuschku.quasseldroid.util.helper.*
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 67387cf0c59ad6edd06fa95eb00fec864bb626ef..b16056bd58e00443120ba11f7c93f9c624d7e445 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
@@ -57,6 +57,7 @@ import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity
+import de.kuschku.quasseldroid.ui.info.channellist.ChannelListActivity
 import de.kuschku.quasseldroid.util.ColorContext
 import de.kuschku.quasseldroid.util.avatars.AvatarHelper
 import de.kuschku.quasseldroid.util.helper.*
@@ -119,6 +120,13 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
 
       return if (info != null && session != null) {
         when (item?.itemId) {
+          R.id.action_channellist  -> {
+            network?.let {
+              ChannelListActivity.launch(requireContext(), network = it.networkId())
+            }
+            actionMode?.finish()
+            true
+          }
           R.id.action_configure  -> {
             network?.let {
               NetworkEditActivity.launch(requireContext(), network = it.networkId())
@@ -394,6 +402,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
         val menu = actionMode?.menu
         if (menu != null) {
           val allActions = setOf(
+            R.id.action_channellist,
             R.id.action_configure,
             R.id.action_connect,
             R.id.action_disconnect,
@@ -428,7 +437,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
                   R.id.action_configure, R.id.action_connect
                 )
                 INetwork.ConnectionState.Initialized  -> setOf(
-                  R.id.action_configure, R.id.action_disconnect
+                  R.id.action_channellist, R.id.action_configure, R.id.action_disconnect
                 )
                 else                                  -> setOf(
                   R.id.action_configure, R.id.action_connect, R.id.action_disconnect
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
index 8c52b9d669f475b1307bfa326f2f17adf61e97a4..f273ecabc983c6502648b8a91d0c5fc410da9549 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
@@ -63,7 +63,7 @@ import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.settings.BacklogSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
-import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity
+import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity
 import de.kuschku.quasseldroid.util.Patterns
 import de.kuschku.quasseldroid.util.avatars.AvatarHelper
 import de.kuschku.quasseldroid.util.helper.*
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
index 9149a8bb11a3fe7037ca6e9bde166251e4fffc43..2fbe1b9cab14bd7ec9c30a19a06e272c24b1e08e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
@@ -46,7 +46,7 @@ import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
-import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity
+import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity
 import de.kuschku.quasseldroid.util.ColorContext
 import de.kuschku.quasseldroid.util.avatars.AvatarHelper
 import de.kuschku.quasseldroid.util.helper.loadWithFallbacks
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
index 48a4dd845128df7ec175a3acf3144379e104576b..3db97c34473bb55eb7223066871fb818caee068f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
@@ -79,7 +79,7 @@ class TopicFragment : ServiceBoundSettingsFragment(), Savable {
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
-    val view = inflater.inflate(R.layout.fragment_topic, container, false)
+    val view = inflater.inflate(R.layout.fragment_info_topic, container, false)
     ButterKnife.bind(this, view)
 
     editorViewModel.quasselViewModel.onNext(viewModel)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragmentProvider.kt
index c4d418209e22da9101bebac481cb10f4b5db061d..0ec82a4a4f645984ee513869cf187655c2db9709 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragmentProvider.kt
@@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentActivity
 import dagger.Binds
 import dagger.Module
 import dagger.android.ContributesAndroidInjector
+import de.kuschku.quasseldroid.ui.info.topic.TopicActivity
 
 @Module
 abstract class TopicFragmentProvider {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
index cc1f5f7a8b218c73937bcb6fadd555151c2d7544..c28d5eb619ec474fef16baf02450ac6c17e7f49b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
@@ -195,7 +195,7 @@ class AboutFragment : DaggerFragment() {
       ),
       Library(
         name = "Kotlin Standard Library",
-        version = "1.3.11",
+        version = "1.3.20",
         license = apache2,
         url = "https://kotlinlang.org/"
       ),
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 e23d02b93a5ca43d36d6b53320136feda893f49a..d9a42f420244e69c542f892e5a3294868d6b5541 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
@@ -35,8 +35,6 @@ import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 import de.kuschku.libquassel.quassel.syncables.Identity
 import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.quasseldroid.R
-import de.kuschku.quasseldroid.ui.chat.info.core.CoreInfoActivity
-import de.kuschku.quasseldroid.ui.chat.passwordchange.PasswordChangeActivity
 import de.kuschku.quasseldroid.ui.coresettings.aliaslist.AliasListActivity
 import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity
 import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditActivity
@@ -47,6 +45,8 @@ import de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity
 import de.kuschku.quasseldroid.ui.coresettings.network.NetworkCreateActivity
 import de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity
 import de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigActivity
+import de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeActivity
+import de.kuschku.quasseldroid.ui.info.core.CoreInfoActivity
 import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.helper.visibleIf
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeActivity.kt
similarity index 94%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeActivity.kt
index 67d137603ce8682cba970a243e0afedd802664be..508318c7c8f515fd9094a99a549bd26c09b46866 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeActivity.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.passwordchange
+package de.kuschku.quasseldroid.ui.coresettings.passwordchange
 
 import android.content.Context
 import android.content.Intent
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
index 2a7cac192349f1f50239b2ec438034caa190aee2..a109cc96dab4afaa19002d2e673add95fdaa44ce 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.passwordchange
+package de.kuschku.quasseldroid.ui.coresettings.passwordchange
 
 import android.os.Bundle
 import android.text.Editable
@@ -80,7 +80,7 @@ class PasswordChangeFragment : ServiceBoundFragment() {
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
-    val view = inflater.inflate(R.layout.fragment_passwordchange, container, false)
+    val view = inflater.inflate(R.layout.settings_passwordchange, container, false)
     ButterKnife.bind(this, view)
 
     val account = accountDatabase.accounts().findById(accountId)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragmentProvider.kt
similarity index 94%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragmentProvider.kt
index ca55637560d64fe584eb259482770b8e9d6c85c7..f95e1e8132df60614a6f1493020e3eece349bcfe 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/passwordchange/PasswordChangeFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragmentProvider.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.passwordchange
+package de.kuschku.quasseldroid.ui.coresettings.passwordchange
 
 import androidx.fragment.app.FragmentActivity
 import dagger.Binds
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoActivity.kt
similarity index 90%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoActivity.kt
index 0f1997e1e20fd98c416f421d4822f18545118a85..e23c27cf0a68f1454a9d8e0c6be96a25c4bf3fcf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoActivity.kt
@@ -17,10 +17,11 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.channel
+package de.kuschku.quasseldroid.ui.info.channel
 
 import android.content.Context
 import android.content.Intent
+import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class ChannelInfoActivity : ServiceBoundSettingsActivity(ChannelInfoFragment()) {
@@ -28,13 +29,13 @@ class ChannelInfoActivity : ServiceBoundSettingsActivity(ChannelInfoFragment())
     fun launch(
       context: Context,
       openBuffer: Boolean,
-      bufferId: Int
+      bufferId: BufferId
     ) = context.startActivity(intent(context, openBuffer, bufferId))
 
     fun intent(
       context: Context,
       openBuffer: Boolean,
-      bufferId: Int
+      bufferId: BufferId
     ) = Intent(context, ChannelInfoActivity::class.java).apply {
       putExtra("bufferId", bufferId)
       putExtra("openBuffer", openBuffer)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
index 4cd9e9043605de3627365cb1b93590ed6b0d86c0..85c2f7d9f1fa748709021ee5dd557b77b25c7a8c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.channel
+package de.kuschku.quasseldroid.ui.info.channel
 
 import android.os.Build
 import android.os.Bundle
@@ -35,7 +35,7 @@ import de.kuschku.libquassel.quassel.syncables.IrcChannel
 import de.kuschku.libquassel.util.helpers.value
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.MessageSettings
-import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity
+import de.kuschku.quasseldroid.ui.info.topic.TopicActivity
 import de.kuschku.quasseldroid.util.ShortcutCreationHelper
 import de.kuschku.quasseldroid.util.helper.*
 import de.kuschku.quasseldroid.util.irc.format.ContentFormatter
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragmentProvider.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragmentProvider.kt
index d4f8d04b461a24644391dd9d6712fdcd38b8b4c9..b2e9e32a7b525a7926272323576de1629523e79b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragmentProvider.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.channel
+package de.kuschku.quasseldroid.ui.info.channel
 
 import androidx.fragment.app.FragmentActivity
 import dagger.Binds
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListActivity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0258ce035b880b520ff4f9a89053be2585086913
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListActivity.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.ui.info.channellist
+
+import android.content.Context
+import android.content.Intent
+import de.kuschku.libquassel.protocol.NetworkId
+import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
+
+class ChannelListActivity : ServiceBoundSettingsActivity(ChannelListFragment()) {
+  companion object {
+    fun launch(
+      context: Context,
+      network: NetworkId
+    ) = context.startActivity(intent(context, network))
+
+    fun intent(
+      context: Context,
+      network: NetworkId
+    ) = Intent(context, ChannelListActivity::class.java).apply {
+      putExtra("network_id", network)
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..73cae27797e9ac118c77908a94e42f83879375c0
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt
@@ -0,0 +1,115 @@
+/*
+ * 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.ui.info.channellist
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.quassel.syncables.IrcListHelper
+import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.ui.chat.ChatActivity
+import de.kuschku.quasseldroid.util.ColorContext
+import de.kuschku.quasseldroid.util.helper.styledAttributes
+import de.kuschku.quasseldroid.util.irc.format.ContentFormatter
+import javax.inject.Inject
+
+class ChannelListAdapter @Inject constructor(
+  private val contentFormatter: ContentFormatter,
+  context: Context,
+  colorContext: ColorContext
+) :
+  ListAdapter<IrcListHelper.ChannelDescription, ChannelListAdapter.ChannelViewHolder>(
+    object : DiffUtil.ItemCallback<IrcListHelper.ChannelDescription>() {
+      override fun areItemsTheSame(oldItem: IrcListHelper.ChannelDescription, newItem: IrcListHelper.ChannelDescription) =
+        oldItem.channelName == newItem.channelName
+
+      override fun areContentsTheSame(oldItem: IrcListHelper.ChannelDescription, newItem: IrcListHelper.ChannelDescription) =
+        oldItem == newItem
+    }
+  ) {
+  val colorAccent = context.theme.styledAttributes(R.attr.colorAccent) {
+    getColor(0, 0)
+  }
+
+  private val fallbackDrawable = colorContext.buildTextDrawable("#", colorAccent)
+
+  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder {
+    return ChannelViewHolder(
+      LayoutInflater.from(parent.context).inflate(R.layout.widget_channel_search, parent, false),
+      contentFormatter,
+      fallbackDrawable
+    )
+  }
+
+  override fun onBindViewHolder(holder: ChannelViewHolder, position: Int) {
+    holder.bind(getItem(position))
+  }
+
+  class ChannelViewHolder(
+    itemView: View,
+    private val contentFormatter: ContentFormatter,
+    fallbackDrawable: Drawable
+  ) : RecyclerView.ViewHolder(itemView) {
+    @BindView(R.id.status)
+    lateinit var status: ImageView
+
+    @BindView(R.id.name)
+    lateinit var name: TextView
+
+    @BindView(R.id.users)
+    lateinit var users: TextView
+
+    @BindView(R.id.topic)
+    lateinit var topic: TextView
+
+    private var data: IrcListHelper.ChannelDescription? = null
+
+    init {
+      ButterKnife.bind(this, itemView)
+      status.setImageDrawable(fallbackDrawable)
+      itemView.setOnClickListener {
+        data?.let {
+          ChatActivity.launch(
+            itemView.context,
+            networkId = it.netId,
+            channel = it.channelName
+          )
+        }
+      }
+    }
+
+    fun bind(data: IrcListHelper.ChannelDescription) {
+      name.text = data.channelName
+      topic.text = contentFormatter.formatContent(data.topic, networkId = data.netId)
+      users.text = itemView.context.getString(R.string.label_user_count_display, data.userCount.toInt())
+
+      this.data = data
+    }
+  }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..b90a1cd49c84e2158dc9b51d573ac41164dbd7a1
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
@@ -0,0 +1,222 @@
+/*
+ * 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.ui.info.channellist
+
+import android.os.Bundle
+import android.view.*
+import android.widget.EditText
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.AppCompatImageButton
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import butterknife.BindView
+import butterknife.ButterKnife
+import de.kuschku.libquassel.protocol.NetworkId
+import de.kuschku.libquassel.protocol.QStringList
+import de.kuschku.libquassel.quassel.syncables.IrcListHelper
+import de.kuschku.libquassel.util.Optional
+import de.kuschku.libquassel.util.helpers.mapSwitchMap
+import de.kuschku.libquassel.util.helpers.value
+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 io.reactivex.subjects.BehaviorSubject
+import javax.inject.Inject
+
+class ChannelListFragment : ServiceBoundSettingsFragment() {
+  @BindView(R.id.search_input)
+  lateinit var searchInput: EditText
+
+  @BindView(R.id.search_button)
+  lateinit var searchButton: AppCompatImageButton
+
+  @BindView(R.id.progress)
+  lateinit var progress: MaterialContentLoadingProgressBar
+
+  @BindView(R.id.search_results)
+  lateinit var searchResults: RecyclerView
+
+  @BindView(R.id.error)
+  lateinit var errorDisplay: WarningBarView
+
+  @Inject
+  lateinit var adapter: ChannelListAdapter
+
+  private var query: Query? = null
+  private var state: State = State()
+
+  data class Query(
+    val networkId: NetworkId,
+    val filters: QStringList
+  )
+
+  data class State(
+    val loading: Boolean = false,
+    val error: String? = null
+  )
+
+  fun updateState(loading: Boolean = state.loading, error: String? = state.error) {
+    fun internalUpdateState(state: State) {
+      if (state.error != null) {
+        errorDisplay.setText(state.error)
+        errorDisplay.setMode(WarningBarView.MODE_ICON)
+      } else {
+        errorDisplay.setMode(WarningBarView.MODE_NONE)
+      }
+
+      if (state.loading) {
+        progress.show()
+      } else {
+        progress.hide()
+      }
+    }
+
+    val newState = State(loading, error)
+    if (newState != state) {
+      state = newState
+      internalUpdateState(newState)
+    }
+  }
+
+  val results = BehaviorSubject.createDefault(emptyList<IrcListHelper.ChannelDescription>())
+  val sort = BehaviorSubject.createDefault(Sort(Sort.Field.CHANNEL_NAME, Sort.Direction.ASC))
+
+  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                            savedInstanceState: Bundle?): View? {
+    val view = inflater.inflate(R.layout.fragment_info_channellist, container, false)
+    ButterKnife.bind(this, view)
+
+    val networkId = arguments?.getInt("network_id", -1) ?: -1
+
+    searchResults.adapter = adapter
+    searchResults.layoutManager = LinearLayoutManager(view.context)
+    searchResults.itemAnimator = DefaultItemAnimator()
+
+    combineLatest(results, sort).toLiveData().observe(this, Observer { (results, sort) ->
+      adapter.submitList(results.let {
+        when (sort.field) {
+          Sort.Field.CHANNEL_NAME -> {
+            when (sort.direction) {
+              Sort.Direction.ASC  ->
+                it.sortedBy(IrcListHelper.ChannelDescription::channelName)
+              Sort.Direction.DESC ->
+                it.sortedByDescending(IrcListHelper.ChannelDescription::channelName)
+            }
+          }
+          Sort.Field.USER_COUNT   -> {
+            when (sort.direction) {
+              Sort.Direction.ASC  ->
+                it.sortedBy(IrcListHelper.ChannelDescription::userCount)
+              Sort.Direction.DESC ->
+                it.sortedByDescending(IrcListHelper.ChannelDescription::userCount)
+            }
+          }
+          Sort.Field.TOPIC        -> {
+            when (sort.direction) {
+              Sort.Direction.ASC  ->
+                it.sortedBy(IrcListHelper.ChannelDescription::topic)
+              Sort.Direction.DESC ->
+                it.sortedByDescending(IrcListHelper.ChannelDescription::topic)
+            }
+          }
+        }
+      })
+    })
+
+    viewModel.ircListHelper
+      .mapSwitchMap(IrcListHelper::observable)
+      .filter(Optional<IrcListHelper.Event>::isPresent)
+      .map(Optional<IrcListHelper.Event>::get)
+      .toLiveData().observe(this, Observer {
+        when (it) {
+          is IrcListHelper.Event.ChannelList -> {
+            if (it.netId == query?.networkId) {
+              results.onNext(it.data)
+            }
+          }
+          is IrcListHelper.Event.Finished    -> {
+            if (it.netId == query?.networkId) {
+              updateState(false, null)
+            }
+          }
+          is IrcListHelper.Event.Error       -> {
+            updateState(false, it.error)
+          }
+        }
+      })
+
+    searchButton.setOnClickListener {
+      viewModel.ircListHelper.value?.orNull()?.let { ircListHelper ->
+        val query = Query(
+          networkId,
+          listOf(searchInput.text.toString())
+        )
+
+        ircListHelper.requestChannelList(networkId, query.filters)
+        updateState(true, null)
+        results.onNext(emptyList())
+        this.query = query
+      }
+    }
+    return view
+  }
+
+  override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+    inflater?.inflate(R.menu.activity_channellist, menu)
+    (activity as? AppCompatActivity)?.supportActionBar?.themedContext?.let {
+      menu?.retint(it)
+    }
+    super.onCreateOptionsMenu(menu, inflater)
+  }
+
+  override fun onOptionsItemSelected(item: MenuItem?) = when (item?.itemId) {
+    R.id.channel_name_asc  -> {
+      sort.onNext(Sort(Sort.Field.CHANNEL_NAME, Sort.Direction.ASC))
+      true
+    }
+    R.id.channel_name_desc -> {
+      sort.onNext(Sort(Sort.Field.CHANNEL_NAME, Sort.Direction.DESC))
+      true
+    }
+    R.id.user_count_asc    -> {
+      sort.onNext(Sort(Sort.Field.USER_COUNT, Sort.Direction.ASC))
+      true
+    }
+    R.id.user_count_desc   -> {
+      sort.onNext(Sort(Sort.Field.USER_COUNT, Sort.Direction.DESC))
+      true
+    }
+    R.id.topic_asc         -> {
+      sort.onNext(Sort(Sort.Field.TOPIC, Sort.Direction.ASC))
+      true
+    }
+    R.id.topic_desc        -> {
+      sort.onNext(Sort(Sort.Field.TOPIC, Sort.Direction.DESC))
+      true
+    }
+    else                   -> super.onOptionsItemSelected(item)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragmentProvider.kt
new file mode 100644
index 0000000000000000000000000000000000000000..40b9174cf4a0934b5d00046be8f81513f2ca158c
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragmentProvider.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.ui.info.channellist
+
+import androidx.fragment.app.FragmentActivity
+import dagger.Binds
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class ChannelListFragmentProvider {
+  @Binds
+  abstract fun bindFragmentActivity(activity: ChannelListActivity): FragmentActivity
+
+  @ContributesAndroidInjector
+  abstract fun bindChannelListFragment(): ChannelListFragment
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/Sort.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/Sort.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3a9eb5182747852e8bc9c5e6e75fdd18f5215953
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/Sort.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.ui.info.channellist
+
+data class Sort(
+  val field: Field,
+  val direction: Direction
+) {
+  enum class Field {
+    CHANNEL_NAME,
+    USER_COUNT,
+    TOPIC
+  }
+
+  enum class Direction {
+    ASC,
+    DESC
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/ClientAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/ClientAdapter.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt
index adcef0ab7f74b43df6ae26bc62542c388544a338..4cc2203ddd0472aa176fa29ff6943c46cd678abc 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/ClientAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.core
+package de.kuschku.quasseldroid.ui.info.core
 
 import android.graphics.drawable.Drawable
 import android.text.Html
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoActivity.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoActivity.kt
index 847f735f7cb4acaea0edebf0859f8939fee72d05..8f3036b264f30211681569a2b0bd8d684c8c1701 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoActivity.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.core
+package de.kuschku.quasseldroid.ui.info.core
 
 import android.content.Context
 import android.content.Intent
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
index 86f7f5ff1ec96bbfc06023df128b711ed78c80b6..79f65707e19c0ec73bbce33790a0bc2bec26288e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.core
+package de.kuschku.quasseldroid.ui.info.core
 
 import android.os.Bundle
 import android.text.Html
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragmentProvider.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragmentProvider.kt
index 6d70614410f0e4f7f28df79fa538f694ba02bff7..013dc92e744735ed6a6770b1818e96e28f3d23d6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/core/CoreInfoFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragmentProvider.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.core
+package de.kuschku.quasseldroid.ui.info.core
 
 import androidx.fragment.app.FragmentActivity
 import dagger.Binds
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/topic/TopicActivity.kt
similarity index 87%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/topic/TopicActivity.kt
index 7e77391cf13ff5b2d534d5da08280483e9b88101..468a6de9d96d25c537e7c8f3377452ffe93f64e9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/topic/TopicActivity.kt
@@ -17,10 +17,11 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.topic
+package de.kuschku.quasseldroid.ui.info.topic
 
 import android.content.Context
 import android.content.Intent
+import de.kuschku.quasseldroid.ui.chat.topic.TopicFragment
 import de.kuschku.quasseldroid.util.ui.settings.ServiceBoundSettingsActivity
 
 class TopicActivity : ServiceBoundSettingsActivity(TopicFragment()) {
@@ -28,7 +29,9 @@ class TopicActivity : ServiceBoundSettingsActivity(TopicFragment()) {
     fun launch(
       context: Context,
       buffer: Int
-    ) = context.startActivity(intent(context, buffer))
+    ) = context.startActivity(intent(
+      context,
+      buffer))
 
     fun intent(
       context: Context,
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/IrcUserInfo.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/user/IrcUserInfo.kt
index f49fc0a9696ecdebf4d297eb6ae31e8fc9443904..7d51299a455e70bbfa85fe586304b215b6f74c7a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/IrcUserInfo.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.user
+package de.kuschku.quasseldroid.ui.info.user
 
 import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.quassel.syncables.IrcUser
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoActivity.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoActivity.kt
index 291988ddd22eaea7e3c3ac7309b15f6ad780b533..ad0237d0bb781adb43c12263d93a41824ffe9f98 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoActivity.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.user
+package de.kuschku.quasseldroid.ui.info.user
 
 import android.content.Context
 import android.content.Intent
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
index 858c298f47d6a800a0c1d358bde3804108adcd72..5f5069bb1c0f82f5a0b55032d12079881370508d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.user
+package de.kuschku.quasseldroid.ui.info.user
 
 import android.content.Intent
 import android.net.Uri
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragmentProvider.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragmentProvider.kt
index a3b8ba4888ad479f0c885ceff7a4a266dafaeaf2..cfba0ecf696f86cd45021e5a16345499f6ca8374 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragmentProvider.kt
@@ -17,7 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid.ui.chat.info.user
+package de.kuschku.quasseldroid.ui.info.user
 
 import androidx.fragment.app.FragmentActivity
 import dagger.Binds
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 26a701833641590dd4ac190840b5b4dd65b88905..5f6be2fad54914ea65ba205c673603d1750241ba 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
@@ -28,8 +28,12 @@ import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.util.helper.styledAttributes
 import de.kuschku.quasseldroid.util.ui.TextDrawable
 import de.kuschku.quasseldroid.viewmodel.EditorViewModel
+import javax.inject.Inject
 
-class ColorContext(context: Context, private val messageSettings: MessageSettings) {
+class ColorContext @Inject constructor(
+  context: Context,
+  private val messageSettings: MessageSettings
+) {
   private val senderColors = context.theme.styledAttributes(
     R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3,
     R.attr.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7,
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt
index 84e41e5feb44ee9a6c68970adac52c0122fd27f5..cd6c36f16032006428a15c533c9b4311c201e090 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt
@@ -24,7 +24,7 @@ import de.kuschku.libquassel.util.irc.HostmaskHelper
 import de.kuschku.libquassel.util.irc.IrcCaseMappers
 import de.kuschku.quasseldroid.persistence.QuasselDatabase
 import de.kuschku.quasseldroid.settings.MessageSettings
-import de.kuschku.quasseldroid.ui.chat.info.user.IrcUserInfo
+import de.kuschku.quasseldroid.ui.info.user.IrcUserInfo
 import de.kuschku.quasseldroid.util.Patterns
 import de.kuschku.quasseldroid.util.backport.codec.Hex
 import de.kuschku.quasseldroid.util.helper.letIf
diff --git a/app/src/main/res/drawable/ic_search.xml b/app/src/main/res/drawable/ic_search.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0910ca2c165a5978a4b8654e566fee29807da86a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_search.xml
@@ -0,0 +1,28 @@
+<?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="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_sort.xml b/app/src/main/res/drawable/ic_sort.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2e3eb57f3ce26a022bec07c7d364dfef0f95b4bb
--- /dev/null
+++ b/app/src/main/res/drawable/ic_sort.xml
@@ -0,0 +1,28 @@
+<?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="M3,13H15V11H3M3,6V8H21V6M3,18H9V16H3V18Z" />
+</vector>
diff --git a/app/src/main/res/layout/fragment_chat_list.xml b/app/src/main/res/layout/fragment_chat_list.xml
index a30ac1b15fcf3781ce2eb8b9cff675dd1fd3f71b..ac57993a109c02dfe3ba0d12711a044e6cfc55ba 100644
--- a/app/src/main/res/layout/fragment_chat_list.xml
+++ b/app/src/main/res/layout/fragment_chat_list.xml
@@ -50,56 +50,7 @@
 
   </com.google.android.material.appbar.AppBarLayout>
 
-  <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:background="?colorBackgroundSnackbar">
-
-    <androidx.cardview.widget.CardView
-      android:id="@+id/buffer_search_container"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_margin="6dp"
-      app:cardBackgroundColor="?colorBackgroundSearch"
-      app:cardElevation="2dp">
-
-      <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal">
-
-        <EditText
-          android:id="@+id/buffer_search"
-          android:layout_width="0dip"
-          android:layout_height="wrap_content"
-          android:layout_weight="1"
-          android:background="@android:color/transparent"
-          android:hint="@string/label_search_buffer"
-          android:imeOptions="actionSearch"
-          android:importantForAutofill="no"
-          android:inputType="textNoSuggestions"
-          android:lines="1"
-          android:minHeight="40dp"
-          android:paddingLeft="8dp"
-          android:paddingRight="8dp"
-          android:textColor="?colorTextSearch"
-          android:textColorHint="?colorTextSearchSecondary"
-          android:textSize="16sp" />
-
-        <androidx.appcompat.widget.AppCompatImageButton
-          android:id="@+id/buffer_search_clear"
-          android:layout_width="40dp"
-          android:layout_height="match_parent"
-          android:background="?selectableItemBackgroundBorderless"
-          android:contentDescription="@string/label_clear_search"
-          app:srcCompat="@drawable/ic_close"
-          app:tint="?colorTextSearchSecondary" />
-
-      </LinearLayout>
-
-    </androidx.cardview.widget.CardView>
-
-  </LinearLayout>
+  <include layout="@layout/widget_search" />
 
   <de.kuschku.quasseldroid.util.ui.WarningBarView
     android:id="@+id/feature_context_bufferactivitysync"
diff --git a/app/src/main/res/layout/fragment_info_channellist.xml b/app/src/main/res/layout/fragment_info_channellist.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8f5c8517850c7c7fa4c3a760ea9da79da603acc4
--- /dev/null
+++ b/app/src/main/res/layout/fragment_info_channellist.xml
@@ -0,0 +1,103 @@
+<?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/>.
+  -->
+
+<LinearLayout 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:orientation="vertical">
+
+  <androidx.cardview.widget.CardView
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_margin="6dp"
+    app:cardBackgroundColor="?colorBackgroundCard"
+    app:cardElevation="2dp">
+
+    <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:orientation="horizontal">
+
+        <EditText
+          android:id="@+id/search_input"
+          android:layout_width="0dip"
+          android:layout_height="wrap_content"
+          android:layout_weight="1"
+          android:background="@android:color/transparent"
+          android:hint="@string/label_search_channels"
+          android:imeOptions="actionSearch"
+          android:importantForAutofill="no"
+          android:inputType="textNoSuggestions"
+          android:lines="1"
+          android:minHeight="40dp"
+          android:paddingLeft="8dp"
+          android:paddingRight="8dp"
+          android:textColor="?colorTextPrimary"
+          android:textColorHint="?colorTextSecondary"
+          android:textSize="16sp" />
+
+        <androidx.appcompat.widget.AppCompatImageButton
+          android:id="@+id/search_button"
+          android:layout_width="40dp"
+          android:layout_height="match_parent"
+          android:background="?selectableItemBackgroundBorderless"
+          android:contentDescription="@string/label_search"
+          app:srcCompat="@drawable/ic_search"
+          app:tint="?colorTextSecondary" />
+
+      </LinearLayout>
+
+      <de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
+        android:id="@+id/progress"
+        style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:visibility="gone"
+        app:mpb_progressStyle="horizontal"
+        app:mpb_setBothDrawables="true"
+        app:mpb_useIntrinsicPadding="false"
+        tools:indeterminate="true" />
+
+    </LinearLayout>
+
+  </androidx.cardview.widget.CardView>
+
+  <de.kuschku.quasseldroid.util.ui.WarningBarView
+    android:id="@+id/error"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:icon="@drawable/ic_alert"
+    app:mode="none" />
+
+  <de.kuschku.quasseldroid.util.ui.fastscroll.views.FastScrollRecyclerView
+    android:id="@+id/search_results"
+    style="@style/Widget.FastScroller"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:listitem="@layout/widget_channel_search" />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_topic.xml b/app/src/main/res/layout/fragment_info_topic.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_topic.xml
rename to app/src/main/res/layout/fragment_info_topic.xml
diff --git a/app/src/main/res/layout/fragment_passwordchange.xml b/app/src/main/res/layout/settings_passwordchange.xml
similarity index 100%
rename from app/src/main/res/layout/fragment_passwordchange.xml
rename to app/src/main/res/layout/settings_passwordchange.xml
diff --git a/app/src/main/res/layout/widget_channel_search.xml b/app/src/main/res/layout/widget_channel_search.xml
new file mode 100644
index 0000000000000000000000000000000000000000..235744279a3047e8847068e44545c1b774a6b039
--- /dev/null
+++ b/app/src/main/res/layout/widget_channel_search.xml
@@ -0,0 +1,97 @@
+<?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/>.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:tools="http://schemas.android.com/tools"
+  android:layout_width="match_parent"
+  android:layout_height="wrap_content"
+  android:background="?attr/backgroundMenuItem"
+  android:minHeight="?listPreferredItemHeightSmall"
+  android:orientation="horizontal"
+  android:paddingLeft="16dp"
+  android:paddingTop="4dp"
+  android:paddingRight="16dp"
+  android:paddingBottom="4dp"
+  android:textAppearance="?android:attr/textAppearanceListItemSmall">
+
+  <ImageView
+    android:id="@+id/status"
+    android:layout_width="@dimen/avatar_size_buffer"
+    android:layout_height="@dimen/avatar_size_buffer"
+    android:layout_gravity="center_vertical"
+    android:layout_marginEnd="16dp"
+    android:layout_marginRight="16dp"
+    android:contentDescription="@string/label_avatar"
+    tools:src="@tools:sample/avatars" />
+
+  <LinearLayout
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_vertical"
+    android:orientation="vertical">
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="horizontal">
+
+
+      <TextView
+        android:id="@+id/name"
+        style="@style/Widget.RtlConformTextView"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical|start"
+        android:layout_weight="1"
+        android:ellipsize="marquee"
+        android:fontFamily="sans-serif-medium"
+        android:singleLine="true"
+        android:textColor="?attr/colorTextPrimary"
+        android:textSize="13sp"
+        tools:text="@sample/channels.json/data/name" />
+
+      <TextView
+        android:id="@+id/users"
+        style="@style/Widget.RtlConformTextView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:layout_marginLeft="8dp"
+        android:layout_marginStart="8dp"
+        android:textColor="?attr/colorTextSecondary"
+        android:textSize="12sp"
+        tools:text="@sample/channels.json/data/users"
+        tools:visibility="visible" />
+
+    </LinearLayout>
+
+    <TextView
+      android:id="@+id/topic"
+      style="@style/Widget.RtlConformTextView"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:ellipsize="marquee"
+      android:singleLine="true"
+      android:textColor="?attr/colorTextSecondary"
+      android:textSize="12sp"
+      tools:text="@sample/channels.json/data/topic"
+      tools:visibility="visible" />
+  </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/widget_search.xml b/app/src/main/res/layout/widget_search.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eed89f9ec6aecd92ab47425c32eb36b9f4e306c9
--- /dev/null
+++ b/app/src/main/res/layout/widget_search.xml
@@ -0,0 +1,70 @@
+<?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/>.
+  -->
+
+<LinearLayout 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"
+  android:background="?colorBackgroundSnackbar">
+
+  <androidx.cardview.widget.CardView
+    android:id="@+id/buffer_search_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_margin="6dp"
+    app:cardBackgroundColor="?colorBackgroundSearch"
+    app:cardElevation="2dp">
+
+    <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="horizontal">
+
+      <EditText
+        android:id="@+id/buffer_search"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:background="@android:color/transparent"
+        android:hint="@string/label_search_buffer"
+        android:imeOptions="actionSearch"
+        android:importantForAutofill="no"
+        android:inputType="textNoSuggestions"
+        android:lines="1"
+        android:minHeight="40dp"
+        android:paddingLeft="8dp"
+        android:paddingRight="8dp"
+        android:textColor="?colorTextSearch"
+        android:textColorHint="?colorTextSearchSecondary"
+        android:textSize="16sp" />
+
+      <androidx.appcompat.widget.AppCompatImageButton
+        android:id="@+id/buffer_search_clear"
+        android:layout_width="40dp"
+        android:layout_height="match_parent"
+        android:background="?selectableItemBackgroundBorderless"
+        android:contentDescription="@string/label_clear_search"
+        app:srcCompat="@drawable/ic_close"
+        app:tint="?colorTextSearchSecondary" />
+
+    </LinearLayout>
+
+  </androidx.cardview.widget.CardView>
+
+</LinearLayout>
diff --git a/app/src/main/res/menu/activity_channellist.xml b/app/src/main/res/menu/activity_channellist.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3154835936864678c846fee4c57eeaa7df321d00
--- /dev/null
+++ b/app/src/main/res/menu/activity_channellist.xml
@@ -0,0 +1,57 @@
+<?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/>.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:app="http://schemas.android.com/apk/res-auto">
+  <item
+    android:id="@+id/action_sort"
+    android:icon="@drawable/ic_sort"
+    android:title="@string/label_sort"
+    app:showAsAction="always">
+    <menu>
+      <item android:id="@+id/channel_name"
+        android:title="@string/label_channel_name">
+        <menu>
+          <item android:id="@+id/channel_name_asc"
+            android:title="@string/label_ascending" />
+          <item android:id="@+id/channel_name_desc"
+            android:title="@string/label_descending" />
+        </menu>
+      </item>
+      <item android:id="@+id/user_count"
+        android:title="@string/label_user_count">
+        <menu>
+          <item android:id="@+id/user_count_asc"
+            android:title="@string/label_ascending" />
+          <item android:id="@+id/user_count_desc"
+            android:title="@string/label_descending" />
+        </menu>
+      </item>
+      <item android:id="@+id/topic"
+        android:title="@string/label_topic">
+        <menu>
+          <item android:id="@+id/topic_asc"
+            android:title="@string/label_ascending" />
+          <item android:id="@+id/topic_desc"
+            android:title="@string/label_descending" />
+        </menu>
+      </item>
+    </menu>
+  </item>
+</menu>
diff --git a/app/src/main/res/menu/context_buffer.xml b/app/src/main/res/menu/context_buffer.xml
index f89dad9e2f932684a623d722b346fc50ceec01de..36c535533982f45bd301e5f4d265283903110eab 100644
--- a/app/src/main/res/menu/context_buffer.xml
+++ b/app/src/main/res/menu/context_buffer.xml
@@ -19,6 +19,9 @@
 
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
+  <item
+    android:id="@+id/action_channellist"
+    android:title="@string/label_info_channellist" />
   <item
     android:id="@+id/action_configure"
     android:title="@string/label_configure" />
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9d4c95ce85b45b2fd68fb3882066bc17dd42aff0..888094451750c9bc35e1f3417374c66209e06468 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -27,13 +27,14 @@
 
   <string name="label_about">Über</string>
   <string name="label_accept">Akzeptieren</string>
+  <string name="label_ascending">Aufsteigend</string>
   <string name="label_autocomplete">Autovervollständigung</string>
   <string name="label_avatar">Avatar</string>
   <string name="label_back">Zurück</string>
   <string name="label_buffer_name">Chatname</string>
   <string name="label_cancel">Abbrechen</string>
-  <string name="label_update_user_password">Benutzernamen/Passwort ändern</string>
   <string name="label_certificates">Zertifikate</string>
+  <string name="label_channel_name">Kanalname</string>
   <string name="label_clear_search">Eingabe löschen</string>
   <string name="label_close">Schließen</string>
   <string name="label_colors_custom">Anpassen</string>
@@ -44,10 +45,9 @@
   <string name="label_copy">Kopieren</string>
   <string name="label_crashes">Absturzberichte</string>
   <string name="label_crashes_empty">Keine Absturzberichte gefunden</string>
-  <string name="label_shortcut">Verknüpfung</string>
-  <string name="label_shortcut_long">Erstellt eine Verknüpfung auf dem Startbildschirm</string>
   <string name="label_delete">Löschen</string>
   <string name="label_delete_all">Alle Löschen</string>
+  <string name="label_descending">Absteigend</string>
   <string name="label_disconnect">Verbindung trennen</string>
   <string name="label_edit_core">Account bearbeiten</string>
   <string name="label_edit_nick">Spitznamen bearbeiten</string>
@@ -61,6 +61,7 @@
   <string name="label_ignore_long">Add/remove user to/from ignore list</string>
   <string name="label_info">Info</string>
   <string name="label_info_channel">Kanalinformationen</string>
+  <string name="label_info_channellist">Kanalliste</string>
   <string name="label_info_core">Core-Details</string>
   <string name="label_info_user">Benutzerinformationen</string>
   <string name="label_input_history">Eingabeverlauf</string>
@@ -68,31 +69,29 @@
   <string name="label_join_long">Kanal Betreten</string>
   <string name="label_libraries">Bibliotheken</string>
   <string name="label_license">Lizenz</string>
-  <string name="label_match_all">Betrifft alle Nachrichten</string>
   <string name="label_mark_read">Gelesen</string>
+  <string name="label_match_all">Betrifft alle Nachrichten</string>
   <string name="label_mention">Erwähnen</string>
   <string name="label_mention_long">Kopiert den Nutzernamen in die Eingabezeile</string>
-  <string name="label_next">Weiter</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_highlight_rule">Neue Hervorhebungsregel</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>
   <string name="label_new_server">Server hinzufügen</string>
+  <string name="label_next">Weiter</string>
   <string name="label_nicklist">Benutzerliste</string>
   <string name="label_no">Nein</string>
   <string name="label_no_away_message">Kein Abwesenheitsgrund verfügbar</string>
   <string name="label_no_sound">Ohne</string>
-  <string name="label_reply">Antworten</string>
-  <string name="label_reset">Zurücksetzen</string>
   <string name="label_open">Öffnen</string>
   <string name="label_part">Verlassen</string>
   <string name="label_part_long">Kanal verlassen</string>
   <string name="label_password_change">Passwort ändern</string>
-  <string name="label_password_error_wrong">Falsches Passwort</string>
   <string name="label_password_error_nomatch">Passwörter stimmen nicht überein</string>
+  <string name="label_password_error_wrong">Falsches Passwort</string>
   <string name="label_password_new">Neues Passwort</string>
   <string name="label_password_old">Altes Passwort</string>
   <string name="label_password_repeat">Passwort wiederholen</string>
@@ -102,10 +101,13 @@
   <string name="label_query">Dialog</string>
   <string name="label_query_long">Öffnet einen privaten Chat</string>
   <string name="label_rename">Umbenennen</string>
+  <string name="label_reply">Antworten</string>
+  <string name="label_reset">Zurücksetzen</string>
   <string name="label_save">Speichern</string>
   <string name="label_saving">Speichern…</string>
   <string name="label_search">Suchen…</string>
   <string name="label_search_buffer">Chats suchen</string>
+  <string name="label_search_channels">Kanäle suchen</string>
   <string name="label_select">Auswählen</string>
   <string name="label_send">Senden</string>
   <string name="label_service_connection_failed">Verbindung konnte nicht hergestellt werden, prüfe die Batterie-Spar-Einstellungen. Mehr Info findest du auf dontkillmyapp.com.</string>
@@ -115,20 +117,26 @@
   <string name="label_settings_core">Core-Einstellungen</string>
   <string name="label_share">Teilen</string>
   <string name="label_share_crashreport">Absturzbericht Teilen</string>
+  <string name="label_shortcut">Verknüpfung</string>
+  <string name="label_shortcut_long">Erstellt eine Verknüpfung auf dem Startbildschirm</string>
   <string name="label_show_hidden">Alle anzeigen</string>
+  <string name="label_sort">Sortieren</string>
   <string name="label_source">Quellcode</string>
   <string name="label_topic">Kanal-Thema</string>
   <string name="label_translators">Übersetzer</string>
   <string name="label_unhide">Nicht mehr ausblenden</string>
   <string name="label_unknown_sender">&lt;Unbekannt&gt;</string>
+  <string name="label_update_user_password">Benutzernamen/Passwort ändern</string>
   <string name="label_use_default">Standardwerte benutzen</string>
+  <string name="label_user_count_display">%1$d Nutzer</string>
+  <string name="label_user_count">Anzahl Nutzer</string>
   <string name="label_website">Webseite</string>
   <string name="label_whitelist">Ignorieren</string>
-  <string name="label_whitelist_ignore_date">Verfallsdatum wird ignoriert für dieses Zertifikat</string>
   <string name="label_whitelist_certificates">Zertifikate</string>
   <string name="label_whitelist_certificates_empty">Keine Zertifikate auf der Whitelist</string>
   <string name="label_whitelist_hostnames">Hosts</string>
   <string name="label_whitelist_hostnames_empty">Keine Hostnamen auf der Whitelist</string>
+  <string name="label_whitelist_ignore_date">Verfallsdatum wird ignoriert für dieses Zertifikat</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Informationen aller Nutzer aktualisieren</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values-fr-rCA/strings.xml b/app/src/main/res/values-fr-rCA/strings.xml
index a48568dd3e29b7cfe8aff09d7611ff65047d6ee1..d7885d4bea240a259c2f1b19543416a7927820d8 100644
--- a/app/src/main/res/values-fr-rCA/strings.xml
+++ b/app/src/main/res/values-fr-rCA/strings.xml
@@ -31,7 +31,6 @@
   <string name="label_back">Retour</string>
   <string name="label_buffer_name">Nom du Tchat</string>
   <string name="label_cancel">Annuler</string>
-  <string name="label_update_user_password">Mettre à Jour l\'Utilisateur ou le Mot de Passe</string>
   <string name="label_certificates">Certificats</string>
   <string name="label_close">Fermer</string>
   <string name="label_colors_custom">Personnalisé</string>
@@ -64,8 +63,8 @@
   <string name="label_mention_long">Copier le nom d\'utilisateur dans la zone de texte</string>
   <string name="label_new_account">Nouveau Compte</string>
   <string name="label_new_chatlist">Nouvelle Liste de Tchats</string>
-  <string name="label_new_highlight_rule">Nouvelle Règle de Highlight</string>
   <string name="label_new_highlight_ignore_rule">Nouvelle Règle de Highlight à Ignorer</string>
+  <string name="label_new_highlight_rule">Nouvelle Règle de Highlight</string>
   <string name="label_new_identity">Nouvelle Identité</string>
   <string name="label_new_network">Nouveau Réseau</string>
   <string name="label_new_nick">Nouveau Nom d\'Utilisateur</string>
@@ -74,8 +73,6 @@
   <string name="label_no">Non</string>
   <string name="label_no_away_message">Aucuns Messages d\'Absence Disponibles</string>
   <string name="label_no_sound">Aucun</string>
-  <string name="label_reply">Répondre</string>
-  <string name="label_reset">Réinitialiser</string>
   <string name="label_open">Ouvrir</string>
   <string name="label_part">Partir</string>
   <string name="label_part_long">Partir de la Chaîne</string>
@@ -85,6 +82,8 @@
   <string name="label_query">Requêter</string>
   <string name="label_query_long">Ouvrir une session privée avec cet utilisateur</string>
   <string name="label_rename">Renommer</string>
+  <string name="label_reply">Répondre</string>
+  <string name="label_reset">Réinitialiser</string>
   <string name="label_save">Enregistrer</string>
   <string name="label_select">Sélectionner</string>
   <string name="label_set_default">Définir par défaut</string>
@@ -98,12 +97,13 @@
   <string name="label_translators">Traducteurs</string>
   <string name="label_unhide">Rendre Visible</string>
   <string name="label_unknown_sender">&lt;Inconnu&gt;</string>
+  <string name="label_update_user_password">Mettre à Jour l\'Utilisateur ou le Mot de Passe</string>
   <string name="label_use_default">Utiliser les paramètres par défaut</string>
   <string name="label_website">Site Web</string>
   <string name="label_whitelist">Ignorer</string>
-  <string name="label_whitelist_ignore_date">La date d\'expiration est ignorée pour ce certificat</string>
   <string name="label_whitelist_certificates">Certificats</string>
   <string name="label_whitelist_hostnames">Hosts</string>
+  <string name="label_whitelist_ignore_date">La date d\'expiration est ignorée pour ce certificat</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Mettre à jour les informations sur tous les utilisateurs</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 70dfdd0d4905ba9079aca29f18ae83a9186502bf..0317537358f60cea43197a472100557934b87241 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -32,7 +32,6 @@
   <string name="label_back">Indietro</string>
   <string name="label_buffer_name">Nome della chat</string>
   <string name="label_cancel">Annulla</string>
-  <string name="label_update_user_password">Aggiorna il nome utente e la password</string>
   <string name="label_certificates">Certificati</string>
   <string name="label_clear_search">Pulisci cerca</string>
   <string name="label_close">Chiudi</string>
@@ -44,8 +43,6 @@
   <string name="label_copy">Copia</string>
   <string name="label_crashes">Arresti anomali</string>
   <string name="label_crashes_empty">Nessun rapporto di arresto anomalo trovato</string>
-  <string name="label_shortcut">Scorciatoia</string>
-  <string name="label_shortcut_long">Crea scorciatoia nella schermata Home</string>
   <string name="label_delete">Elimina</string>
   <string name="label_delete_all">Elimina tutto</string>
   <string name="label_disconnect">Disconnetti</string>
@@ -68,31 +65,29 @@
   <string name="label_join_long">Entra nel canale</string>
   <string name="label_libraries">Librerie</string>
   <string name="label_license">Licenza</string>
-  <string name="label_match_all">Corrisponde a tutti i messaggi</string>
   <string name="label_mark_read">Segna come letto</string>
+  <string name="label_match_all">Corrisponde a tutti i messaggi</string>
   <string name="label_mention">Menzionare</string>
   <string name="label_mention_long">Copia il nome utente nella casella di digitazione</string>
-  <string name="label_next">Successivo</string>
   <string name="label_new_account">Nuovo account</string>
   <string name="label_new_chatlist">Nuovo elenco chat</string>
-  <string name="label_new_highlight_rule">Nuova regola per menzione</string>
   <string name="label_new_highlight_ignore_rule">Nuova regola per ignorare menzione</string>
+  <string name="label_new_highlight_rule">Nuova regola per menzione</string>
   <string name="label_new_identity">Nuova identità</string>
   <string name="label_new_network">Nuova rete</string>
   <string name="label_new_nick">Nuovo nick</string>
   <string name="label_new_server">Nuovo server</string>
+  <string name="label_next">Successivo</string>
   <string name="label_nicklist">Elenco nick</string>
   <string name="label_no">No</string>
   <string name="label_no_away_message">Nessun messaggio d’assenza disponibile</string>
   <string name="label_no_sound">Nessuno</string>
-  <string name="label_reply">Rispondi</string>
-  <string name="label_reset">Reimposta</string>
   <string name="label_open">Apri</string>
   <string name="label_part">Esci</string>
   <string name="label_part_long">Esci dal canale</string>
   <string name="label_password_change">Cambia password</string>
-  <string name="label_password_error_wrong">Password sbagliata</string>
   <string name="label_password_error_nomatch">La password non corrisponde</string>
+  <string name="label_password_error_wrong">Password sbagliata</string>
   <string name="label_password_new">Nuova password</string>
   <string name="label_password_old">Vecchia password</string>
   <string name="label_password_repeat">Ripeti password</string>
@@ -102,6 +97,8 @@
   <string name="label_query">Privato</string>
   <string name="label_query_long">Apri conversazione privata con l’utente</string>
   <string name="label_rename">Rinomina</string>
+  <string name="label_reply">Rispondi</string>
+  <string name="label_reset">Reimposta</string>
   <string name="label_save">Salva</string>
   <string name="label_saving">Salvataggio…</string>
   <string name="label_search">Cerca…</string>
@@ -115,20 +112,23 @@
   <string name="label_settings_core">Impostazioni del core</string>
   <string name="label_share">Condividi</string>
   <string name="label_share_crashreport">Condividi rapporto dell’arresto anomalo</string>
+  <string name="label_shortcut">Scorciatoia</string>
+  <string name="label_shortcut_long">Crea scorciatoia nella schermata Home</string>
   <string name="label_show_hidden">Mostra nascosti</string>
   <string name="label_source">Sorgente</string>
   <string name="label_topic">Argomento del canale</string>
   <string name="label_translators">Traduttori</string>
   <string name="label_unhide">Rendi visibile</string>
   <string name="label_unknown_sender">&lt;Sconosciuto&gt;</string>
+  <string name="label_update_user_password">Aggiorna il nome utente e la password</string>
   <string name="label_use_default">Utilizza i valori predefiniti</string>
   <string name="label_website">Sito web</string>
   <string name="label_whitelist">Ignora</string>
-  <string name="label_whitelist_ignore_date">La data di scadenza viene ignorata per questo certificato</string>
   <string name="label_whitelist_certificates">Certificati</string>
   <string name="label_whitelist_certificates_empty">Nessun certificato consentito</string>
   <string name="label_whitelist_hostnames">Host</string>
   <string name="label_whitelist_hostnames_empty">Nessun host consentito</string>
+  <string name="label_whitelist_ignore_date">La data di scadenza viene ignorata per questo certificato</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Aggiorna le informazioni per tutti gli utenti</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index bb0cbd728ed480a78e3be1c3f6f7e7da3c9828b9..142af693cd8e80a4c119f141ac33cbca168977a7 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -31,7 +31,6 @@
   <string name="label_back">Atgal</string>
   <string name="label_buffer_name">Buferio pavadinimas</string>
   <string name="label_cancel">Nutraukti</string>
-  <string name="label_update_user_password">Atnaujinti Vartotoją/Slaptažodį</string>
   <string name="label_certificates">Certifikatai</string>
   <string name="label_close">Uždaryti</string>
   <string name="label_colors_custom">Rinktis</string>
@@ -64,8 +63,8 @@
   <string name="label_mention_long">Kopijuoti slapyvardį į įvedimo eilutę</string>
   <string name="label_new_account">Nauja paskyra</string>
   <string name="label_new_chatlist">Naujas pokalbių sąrašas</string>
-  <string name="label_new_highlight_rule">Nauja žymėjimo taisyklė</string>
   <string name="label_new_highlight_ignore_rule">Nauja nežymėjimo taisyklė</string>
+  <string name="label_new_highlight_rule">Nauja žymėjimo taisyklė</string>
   <string name="label_new_identity">Nauja tapatybė</string>
   <string name="label_new_network">Naujas tinklas</string>
   <string name="label_new_nick">Naujas slapyvardis</string>
@@ -74,8 +73,6 @@
   <string name="label_no">Ne</string>
   <string name="label_no_away_message">Nėra pasišalinimo žinutės</string>
   <string name="label_no_sound">Nėra</string>
-  <string name="label_reply">Atsakyti</string>
-  <string name="label_reset">Atstatyti</string>
   <string name="label_open">Atidaryti</string>
   <string name="label_part">Išeiti</string>
   <string name="label_part_long">Palikti kanalą</string>
@@ -85,6 +82,8 @@
   <string name="label_query">Užklausa</string>
   <string name="label_query_long">Atverti privatų pokalbį su vartotoju</string>
   <string name="label_rename">Pervardinti</string>
+  <string name="label_reply">Atsakyti</string>
+  <string name="label_reset">Atstatyti</string>
   <string name="label_save">Išsaugoti</string>
   <string name="label_select">Pasirinkti</string>
   <string name="label_set_default">Nustatyti numatytą</string>
@@ -98,12 +97,13 @@
   <string name="label_translators">Vertėjai</string>
   <string name="label_unhide">Rodyti</string>
   <string name="label_unknown_sender">&lt;Nežinoma&gt;</string>
+  <string name="label_update_user_password">Atnaujinti Vartotoją/Slaptažodį</string>
   <string name="label_use_default">Naudoti numatytas parinktis</string>
   <string name="label_website">Tinklalapis</string>
   <string name="label_whitelist">Ignoruoti</string>
-  <string name="label_whitelist_ignore_date">Galiojimo data yra ignoruojama šiam certifikatui</string>
   <string name="label_whitelist_certificates">Certifikatai</string>
   <string name="label_whitelist_hostnames">Host sąrašas</string>
+  <string name="label_whitelist_ignore_date">Galiojimo data yra ignoruojama šiam certifikatui</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Atnaujinti visų vartotojų informaciją</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 7c05f8fd20e6a147e63f41ae5971e215a75c182d..34ca51e0d4dd89dfdd921dd8dff58459ce745a20 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -32,7 +32,6 @@
   <string name="label_back">Voltar</string>
   <string name="label_buffer_name">Nome da Janela</string>
   <string name="label_cancel">Cancelar</string>
-  <string name="label_update_user_password">Actualizar Utilizador/Senha</string>
   <string name="label_certificates">Certificados</string>
   <string name="label_close">Fechar</string>
   <string name="label_colors_custom">Personalizado</string>
@@ -61,14 +60,14 @@
   <string name="label_join_long">Entrar no Canal</string>
   <string name="label_libraries">Bibliotecas</string>
   <string name="label_license">Licença</string>
-  <string name="label_match_all">Corresponde a todas as mensagens</string>
   <string name="label_mark_read">Marcar como lida</string>
+  <string name="label_match_all">Corresponde a todas as mensagens</string>
   <string name="label_mention">Mencionar</string>
   <string name="label_mention_long">Copia o nome de utilizador para a caixa de digitação</string>
   <string name="label_new_account">Adicionar Conta</string>
   <string name="label_new_chatlist">Adicionar Lista de Chats</string>
-  <string name="label_new_highlight_rule">Nova Regra de Menções</string>
   <string name="label_new_highlight_ignore_rule">Nova Regra para Ignorar Menções</string>
+  <string name="label_new_highlight_rule">Nova Regra de Menções</string>
   <string name="label_new_identity">Adicionar Identidade</string>
   <string name="label_new_network">Adicionar Rede</string>
   <string name="label_new_nick">Adicionar Alcunha</string>
@@ -77,8 +76,6 @@
   <string name="label_no">Não</string>
   <string name="label_no_away_message">Sem mensagem de ausência disponível</string>
   <string name="label_no_sound">Nenhum</string>
-  <string name="label_reply">Responder</string>
-  <string name="label_reset">Restabelecer</string>
   <string name="label_open">Abrir</string>
   <string name="label_part">Sair</string>
   <string name="label_part_long">Sair do Canal</string>
@@ -88,6 +85,8 @@
   <string name="label_query">Abrir conversa privada</string>
   <string name="label_query_long">Abrir conversa privada com o utilizador</string>
   <string name="label_rename">Renomear</string>
+  <string name="label_reply">Responder</string>
+  <string name="label_reset">Restabelecer</string>
   <string name="label_save">Guardar</string>
   <string name="label_select">Selecionar</string>
   <string name="label_send">Enviar</string>
@@ -103,14 +102,15 @@
   <string name="label_translators">Tradutores</string>
   <string name="label_unhide">Tornar Visível</string>
   <string name="label_unknown_sender">&lt;Desconhecido&gt;</string>
+  <string name="label_update_user_password">Actualizar Utilizador/Senha</string>
   <string name="label_use_default">Utilizar Padrão</string>
   <string name="label_website">Site</string>
   <string name="label_whitelist">Ignorar</string>
-  <string name="label_whitelist_ignore_date">A data de caducidade é ignorada para este certificado</string>
   <string name="label_whitelist_certificates">Certificados</string>
   <string name="label_whitelist_certificates_empty">Nenhum certificado permitido</string>
   <string name="label_whitelist_hostnames">Anfitriões</string>
   <string name="label_whitelist_hostnames_empty">Nenhum anfitrião permitido</string>
+  <string name="label_whitelist_ignore_date">A data de caducidade é ignorada para este certificado</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Atualizar as informações de utilizador de todos os utilizadores</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 89bb0d75bc53d05c69f76e8b7285915b78202407..655b7d5fc7a920105270ca654c76283d3940f6bf 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -32,7 +32,6 @@
   <string name="label_back">Nazad</string>
   <string name="label_buffer_name">Ime bafera</string>
   <string name="label_cancel">Otkaži</string>
-  <string name="label_update_user_password">Ažuriraj korisnika/lozinku</string>
   <string name="label_certificates">Sertifikati</string>
   <string name="label_close">Zatvori</string>
   <string name="label_colors_custom">Prilagođeno</string>
@@ -61,14 +60,14 @@
   <string name="label_join_long">Pridruži se kanalu</string>
   <string name="label_libraries">Biblioteke</string>
   <string name="label_license">Licenca</string>
-  <string name="label_match_all">Podudaranje sa svim porukama</string>
   <string name="label_mark_read">Označi pročitanim</string>
+  <string name="label_match_all">Podudaranje sa svim porukama</string>
   <string name="label_mention">Spomeni</string>
   <string name="label_mention_long">Kopiraj korisničko ime u polje za unos</string>
   <string name="label_new_account">Novi nalog</string>
   <string name="label_new_chatlist">Nova lista razgovora</string>
-  <string name="label_new_highlight_rule">Novo Pravilo Isticanja</string>
   <string name="label_new_highlight_ignore_rule">Novo Pravilo Ignorisanja Isticanja</string>
+  <string name="label_new_highlight_rule">Novo Pravilo Isticanja</string>
   <string name="label_new_identity">Novi identitet</string>
   <string name="label_new_network">Nova mreža</string>
   <string name="label_new_nick">Novi nadimak</string>
@@ -77,8 +76,6 @@
   <string name="label_no">Ne</string>
   <string name="label_no_away_message">Poruka iz odsustva nije dostupna</string>
   <string name="label_no_sound">Nijedno</string>
-  <string name="label_reply">Odgovori</string>
-  <string name="label_reset">Resetuj</string>
   <string name="label_open">Otvori</string>
   <string name="label_part">Napusti</string>
   <string name="label_part_long">Napusti kanal</string>
@@ -88,6 +85,8 @@
   <string name="label_query">Upit</string>
   <string name="label_query_long">Otvori privatni razgovor sa korisnikom</string>
   <string name="label_rename">Preimenuj</string>
+  <string name="label_reply">Odgovori</string>
+  <string name="label_reset">Resetuj</string>
   <string name="label_save">Sačuvaj</string>
   <string name="label_select">Odaberi</string>
   <string name="label_send">Pošalji</string>
@@ -103,14 +102,15 @@
   <string name="label_translators">Prevodioci</string>
   <string name="label_unhide">Učini vidljivim</string>
   <string name="label_unknown_sender">&lt;Nepoznato&gt;</string>
+  <string name="label_update_user_password">Ažuriraj korisnika/lozinku</string>
   <string name="label_use_default">Koristi podrazumevane parametre</string>
   <string name="label_website">Veb stranica</string>
   <string name="label_whitelist">Ignoriši</string>
-  <string name="label_whitelist_ignore_date">Datum isteka je ignorisan za ovaj sertifikat</string>
   <string name="label_whitelist_certificates">Sertifikati</string>
   <string name="label_whitelist_certificates_empty">Nema sertifikata u listi dozvoljenih</string>
   <string name="label_whitelist_hostnames">Hostovi</string>
   <string name="label_whitelist_hostnames_empty">Nema hostova u listi dozvoljenih</string>
+  <string name="label_whitelist_ignore_date">Datum isteka je ignorisan za ovaj sertifikat</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Ažuriraj korisničke informacije svakog korisnika</string>
   <string name="label_whois">Whois</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6184a04cbac7daec5b4c97634f9da2554aa5686a..b2402009ec5b8cd98651a694cdd5ef4660905b31 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -27,13 +27,14 @@
 
   <string name="label_about">About</string>
   <string name="label_accept">Accept</string>
+  <string name="label_ascending">Ascending</string>
   <string name="label_autocomplete">Autocomplete</string>
   <string name="label_avatar">Avatar</string>
   <string name="label_back">Back</string>
   <string name="label_buffer_name">Buffer Name</string>
   <string name="label_cancel">Cancel</string>
-  <string name="label_update_user_password">Update User/Password</string>
   <string name="label_certificates">Certificates</string>
+  <string name="label_channel_name">Channel Name</string>
   <string name="label_clear_search">Clear Search</string>
   <string name="label_close">Close</string>
   <string name="label_colors_custom">Custom</string>
@@ -44,10 +45,9 @@
   <string name="label_copy">Copy</string>
   <string name="label_crashes">Crashes</string>
   <string name="label_crashes_empty">No crash reports found</string>
-  <string name="label_shortcut">Shortcut</string>
-  <string name="label_shortcut_long">Create Shortcut on Homescreen</string>
   <string name="label_delete">Delete</string>
   <string name="label_delete_all">Delete All</string>
+  <string name="label_descending">Descending</string>
   <string name="label_disconnect">Disconnect</string>
   <string name="label_edit_core">Edit Account</string>
   <string name="label_edit_nick">Edit Nickname</string>
@@ -61,6 +61,7 @@
   <string name="label_ignore_long">Add/remove user to/from ignore list</string>
   <string name="label_info">Details</string>
   <string name="label_info_channel">Channel Details</string>
+  <string name="label_info_channellist">Channel List</string>
   <string name="label_info_core">Core Details</string>
   <string name="label_info_user">User Details</string>
   <string name="label_input_history">Input History</string>
@@ -68,31 +69,29 @@
   <string name="label_join_long">Join Channel</string>
   <string name="label_libraries">Libraries</string>
   <string name="label_license">License</string>
-  <string name="label_match_all">Matches all messages</string>
   <string name="label_mark_read">Mark Read</string>
+  <string name="label_match_all">Matches all messages</string>
   <string name="label_mention">Mention</string>
   <string name="label_mention_long">Copy username into input line</string>
-  <string name="label_next">Next</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_highlight_rule">New Highlight 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>
   <string name="label_new_server">New Server</string>
+  <string name="label_next">Next</string>
   <string name="label_nicklist">Nick List</string>
   <string name="label_no">No</string>
   <string name="label_no_away_message">No away message available</string>
   <string name="label_no_sound">None</string>
-  <string name="label_reply">Reply</string>
-  <string name="label_reset">Reset</string>
   <string name="label_open">Open</string>
   <string name="label_part">Leave</string>
   <string name="label_part_long">Leave Channel</string>
   <string name="label_password_change">Change Password</string>
-  <string name="label_password_error_wrong">Wrong Password</string>
   <string name="label_password_error_nomatch">Passwords do not match</string>
+  <string name="label_password_error_wrong">Wrong Password</string>
   <string name="label_password_new">New Password</string>
   <string name="label_password_old">Old Password</string>
   <string name="label_password_repeat">Repeat Password</string>
@@ -102,10 +101,13 @@
   <string name="label_query">Query</string>
   <string name="label_query_long">Open private chat with user</string>
   <string name="label_rename">Rename</string>
+  <string name="label_reply">Reply</string>
+  <string name="label_reset">Reset</string>
   <string name="label_save">Save</string>
   <string name="label_saving">Saving…</string>
   <string name="label_search">Search…</string>
   <string name="label_search_buffer">Search Chats</string>
+  <string name="label_search_channels">Search Channels</string>
   <string name="label_select">Select</string>
   <string name="label_send">Send</string>
   <string name="label_service_connection_failed">Could not create connection, check battery saving settings. See dontkillmyapp.com for more info.</string>
@@ -115,20 +117,26 @@
   <string name="label_settings_core">Core Settings</string>
   <string name="label_share">Share</string>
   <string name="label_share_crashreport">Share Crash Report</string>
+  <string name="label_shortcut">Shortcut</string>
+  <string name="label_shortcut_long">Create Shortcut on Homescreen</string>
   <string name="label_show_hidden">Show Hidden</string>
+  <string name="label_sort">Sort</string>
   <string name="label_source">Source</string>
   <string name="label_topic">Channel Topic</string>
   <string name="label_translators">Translators</string>
   <string name="label_unhide">Make Visible</string>
   <string name="label_unknown_sender">&lt;Unknown&gt;</string>
+  <string name="label_update_user_password">Update User/Password</string>
   <string name="label_use_default">Use Default</string>
+  <string name="label_user_count_display">%1$d users</string>
+  <string name="label_user_count">User Count</string>
   <string name="label_website">Website</string>
   <string name="label_whitelist">Ignore</string>
-  <string name="label_whitelist_ignore_date">Expiration date is ignored for this certificate</string>
   <string name="label_whitelist_certificates">Certificates</string>
   <string name="label_whitelist_certificates_empty">No certificates whitelisted</string>
   <string name="label_whitelist_hostnames">Hosts</string>
   <string name="label_whitelist_hostnames_empty">No hosts whitelisted</string>
+  <string name="label_whitelist_ignore_date">Expiration date is ignored for this certificate</string>
   <string name="label_who">Who</string>
   <string name="label_who_long">Update user information of all users</string>
   <string name="label_whois">Whois</string>
diff --git a/build.gradle.kts b/build.gradle.kts
index 4b20a5a9d312cf10e665aaf2829b5aaf7ff8a3f3..957774b1ec8a68435eac776ef7661a1d10c87f0c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -24,7 +24,7 @@ buildscript {
   }
   dependencies {
     classpath("com.android.tools.build:gradle:3.3.0")
-    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11")
+    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.20")
   }
 }
 
diff --git a/desktop/build.gradle.kts b/desktop/build.gradle.kts
index 88efe8d89b2f77e36472fe41ff1a6314d00149cd..0e48105c2f7671130e657d8413014b4fed9ac068 100644
--- a/desktop/build.gradle.kts
+++ b/desktop/build.gradle.kts
@@ -28,7 +28,7 @@ application {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("io.reactivex.rxjava2", "rxjava", "2.1.9")
   implementation("info.picocli", "picocli", "3.9.0")
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 551cede7ceced4f1777188f5eedeb42608b8ec39..1e90cc7321f8a9eb7c4cf0032796df61ae82c7c7 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -17,19 +17,13 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import org.gradle.api.Project
-import org.gradle.api.artifacts.ExternalModuleDependency
-import org.gradle.kotlin.dsl.*
-import org.jetbrains.kotlin.gradle.plugin.KaptExtension
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
 plugins {
   kotlin("jvm")
   kotlin("kapt")
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("androidx.annotation", "annotation", "1.0.0")
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
index f79e901e2f4546c3fb052a7a4938c4742857b6d3..e067c96bbb000f9cfb9253e1a567d6123b78cb8d 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
@@ -22,6 +22,7 @@ package de.kuschku.libquassel.quassel.syncables
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.protocol.QStringList
 import de.kuschku.libquassel.protocol.QVariantList
+import de.kuschku.libquassel.protocol.value
 import de.kuschku.libquassel.quassel.syncables.interfaces.IIrcListHelper
 import de.kuschku.libquassel.session.SignalProxy
 import de.kuschku.libquassel.util.rxjava.ReusableUnicastSubject
@@ -29,9 +30,18 @@ import de.kuschku.libquassel.util.rxjava.ReusableUnicastSubject
 class IrcListHelper constructor(
   proxy: SignalProxy
 ) : SyncableObject(proxy, "IrcListHelper"), IIrcListHelper {
+  private var waitingNetwork: NetworkId = 0
+
+  data class ChannelDescription(
+    val netId: NetworkId,
+    val channelName: String,
+    val userCount: UInt,
+    val topic: String
+  )
+
   sealed class Event {
     data class ChannelList(val netId: NetworkId, val channelFilters: QStringList,
-                           val data: QVariantList) : Event()
+                           val data: List<ChannelDescription>) : Event()
 
     data class Finished(val netId: NetworkId) : Event()
 
@@ -41,13 +51,34 @@ class IrcListHelper constructor(
   private val subject = ReusableUnicastSubject.create<Event>()
   val observable = subject.publish().refCount()
 
+  override fun requestChannelList(netId: NetworkId, channelFilters: QStringList): QVariantList {
+    waitingNetwork = netId
+    return super.requestChannelList(netId, channelFilters)
+  }
+
   override fun receiveChannelList(netId: NetworkId, channelFilters: QStringList,
-                                  data: QVariantList) {
-    subject.onNext(Event.ChannelList(netId, channelFilters, data))
+                                  channels: QVariantList) {
+    subject.onNext(Event.ChannelList(netId, channelFilters, channels.mapNotNull {
+      val list = it.value<QVariantList>(emptyList())
+      if (list.size == 3) {
+        ChannelDescription(
+          netId,
+          list[0].value(""),
+          list[1].value(0u),
+          list[2].value("")
+        )
+      } else {
+        null
+      }
+    }))
   }
 
   override fun reportFinishedList(netId: NetworkId) {
-    subject.onNext(Event.Finished(netId))
+    if (waitingNetwork == netId) {
+      waitingNetwork = 0
+      requestChannelList(netId, emptyList())
+      subject.onNext(Event.Finished(netId))
+    }
   }
 
   override fun reportError(error: String?) {
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
index 1d4411b91150fa6a512b5abd6cb4d1e68f67064c..3c37dd2bbe941ddc412f638c1352111b203f9560 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
@@ -36,7 +36,7 @@ interface IIrcListHelper : ISyncableObject {
   }
 
   @Slot
-  fun receiveChannelList(netId: NetworkId, channelFilters: QStringList, data: QVariantList)
+  fun receiveChannelList(netId: NetworkId, channelFilters: QStringList, channels: QVariantList)
 
   @Slot
   fun reportError(error: String?) {
diff --git a/lifecycle-ktx/build.gradle.kts b/lifecycle-ktx/build.gradle.kts
index c358b698687735ff242b82f5d0f37c3979e10e4d..cf3c1f41192a33b01d46c3991585ad579fc72585 100644
--- a/lifecycle-ktx/build.gradle.kts
+++ b/lifecycle-ktx/build.gradle.kts
@@ -27,7 +27,7 @@ plugins {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("androidx.annotation", "annotation", "1.0.0")
 
diff --git a/malheur/build.gradle.kts b/malheur/build.gradle.kts
index 985a0aa8788c12e3ec077cb11dd999a0820d1430..c378eaf171a0d1f3a3c3ea890934106a2afa3bc2 100644
--- a/malheur/build.gradle.kts
+++ b/malheur/build.gradle.kts
@@ -44,7 +44,7 @@ android {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("com.google.code.gson", "gson", "2.8.5")
 }
diff --git a/persistence/build.gradle.kts b/persistence/build.gradle.kts
index e2b8209df5f25d14c00aa4c7687d096cd39eaf2a..4c04ee7c8a25fe95b3f9f0b0af50be3dfdac2021 100644
--- a/persistence/build.gradle.kts
+++ b/persistence/build.gradle.kts
@@ -51,7 +51,7 @@ android {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("androidx.appcompat", "appcompat", "1.0.0")
 
diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts
index e7d57a2667160fbb2d3f4e8cff3626ebb9696a62..a4d86f44aa63b8a1af6fe66d607ab64d4ac87639 100644
--- a/viewmodel/build.gradle.kts
+++ b/viewmodel/build.gradle.kts
@@ -44,7 +44,7 @@ android {
 }
 
 dependencies {
-  implementation(kotlin("stdlib", "1.3.11"))
+  implementation(kotlin("stdlib", "1.3.20"))
 
   implementation("androidx.appcompat", "appcompat", "1.0.0")
 
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 b69690d558c92203eca5f81531b481ffce05beb9..688ebb2821c2dcad4c8a8fcec86fe0ddbef35838 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -84,6 +84,7 @@ class QuasselViewModel : ViewModel() {
   val sessionManager = backend.mapMapNullable(Backend::sessionManager)
   val session = sessionManager.mapSwitchMap(SessionManager::session)
   val rpcHandler = session.mapMapNullable(ISession::rpcHandler)
+  val ircListHelper = session.mapMapNullable(ISession::ircListHelper)
   val features = sessionManager.mapSwitchMap { manager ->
     manager.state.switchMap { state ->
       if (state != ConnectionState.CONNECTED) {