From 76a2f092c49f537391219933f4d3d08e42d6c511 Mon Sep 17 00:00:00 2001
From: Janne Mareike Koschinski <janne@kuschku.de>
Date: Wed, 30 Aug 2023 02:06:31 +0200
Subject: [PATCH] feat: update dependencies and target API

---
 README.md                                     |   2 -
 app/build.gradle.kts                          |   7 +-
 app/sampledata/libraries.json                 |   9 --
 app/src/main/AndroidManifest.xml              | 109 +++++++++---------
 .../service/QuasselNotificationBackend.kt     |   8 +-
 .../settings/AppearanceSettings.kt            |   4 -
 .../quasseldroid/ui/chat/ChatActivity.kt      |   8 +-
 .../quasseldroid/ui/chat/ToolbarFragment.kt   |  16 ++-
 .../chat/add/create/ChannelCreateFragment.kt  |  26 ++---
 .../ui/chat/add/join/ChannelJoinFragment.kt   |  11 +-
 .../ui/chat/add/query/QueryCreateFragment.kt  |  17 +--
 .../ui/chat/archive/ArchiveFragment.kt        |   5 +-
 .../ui/chat/archive/ArchiveListAdapter.kt     |   2 +-
 .../ui/chat/buffers/BufferListAdapter.kt      |   2 +-
 .../chat/buffers/BufferViewConfigFragment.kt  |  26 ++---
 .../ui/chat/input/AutoCompleteHelper.kt       |   2 +-
 .../ui/chat/input/ChatlineFragment.kt         |  29 ++---
 .../quasseldroid/ui/chat/input/RichToolbar.kt |  32 ++---
 .../ui/chat/messages/MessageListFragment.kt   |  14 +--
 .../ui/chat/nicks/NickListFragment.kt         |   8 +-
 .../ui/chat/topic/TopicFragment.kt            |  11 +-
 .../ui/clientsettings/about/AboutFragment.kt  |  35 ++----
 .../client/ClientSettingsFragment.kt          |   4 +-
 .../ui/clientsettings/crash/CrashFragment.kt  |   8 +-
 .../clientsettings/license/LicenseFragment.kt |   5 +-
 .../whitelist/WhitelistFragment.kt            |  14 +--
 .../ui/coresettings/CoreSettingsFragment.kt   |  41 +++----
 .../aliasitem/AliasItemFragment.kt            |  14 +--
 .../aliaslist/AliasListFragment.kt            |   8 +-
 .../chatlist/ChatListBaseFragment.kt          |  35 ++----
 .../highlightlist/HighlightListFragment.kt    |  23 ++--
 .../highlightrule/HighlightRuleFragment.kt    |  20 +---
 .../identity/IdentityBaseFragment.kt          |  39 ++-----
 .../ignoreitem/IgnoreItemFragment.kt          |  26 ++---
 .../ignorelist/IgnoreListFragment.kt          |   8 +-
 .../network/NetworkBaseFragment.kt            |  77 ++++---------
 .../networkconfig/NetworkConfigFragment.kt    |  32 ++---
 .../networkserver/NetworkServerFragment.kt    |  38 ++----
 .../passwordchange/PasswordChangeFragment.kt  |  29 ++---
 .../certificate/CertificateInfoFragment.kt    |  54 ++++-----
 .../ui/info/channel/ChannelInfoFragment.kt    |  24 ++--
 .../ui/info/channellist/ChannelListAdapter.kt |   2 +-
 .../info/channellist/ChannelListFragment.kt   |  17 +--
 .../ui/info/core/CoreInfoFragment.kt          |  39 ++-----
 .../ui/info/user/UserInfoFragment.kt          |  61 ++++------
 .../ui/setup/ServiceBoundSetupActivity.kt     |  11 +-
 .../quasseldroid/ui/setup/SetupActivity.kt    |  11 +-
 .../quasseldroid/ui/setup/SlideFragment.kt    |   6 +-
 .../accounts/edit/AccountEditFragment.kt      |  25 ++--
 .../selection/AccountSelectionSlide.kt        |  13 +--
 .../setup/AccountSetupConnectionSlide.kt      |  17 +--
 .../accounts/setup/AccountSetupNameSlide.kt   |   7 +-
 .../accounts/setup/AccountSetupUserSlide.kt   |  14 +--
 .../ui/setup/core/CoreBackendChooseSlide.kt   |   5 +-
 .../ui/setup/core/CoreBackendSetupSlide.kt    |   8 +-
 .../ui/setup/core/QuasselSetupEntry.kt        |   8 +-
 .../network/NetworkSetupChannelsSlide.kt      |   8 +-
 .../setup/network/NetworkSetupNetworkSlide.kt |  32 ++---
 .../ui/setup/user/UserSetupChannelsSlide.kt   |   8 +-
 .../ui/setup/user/UserSetupIdentitySlide.kt   |  14 +--
 .../ui/setup/user/UserSetupNetworkSlide.kt    |  29 ++---
 .../kuschku/quasseldroid/util/ColorContext.kt |   2 +-
 .../util/ShortcutCreationHelper.kt            |   4 +-
 .../DeceptiveNetworkDialog.kt                 |   5 +-
 .../quasseldroid/util/helper/GlideHelper.kt   |  31 +++--
 .../quasseldroid/util/helper/MenuHelper.kt    |   2 +-
 .../util/lists/AsyncListDiffer.kt             |   2 +-
 .../quasseldroid/util/lists/ListAdapter.kt    |   2 +-
 .../missingfeatures/MissingFeaturesDialog.kt  |   8 +-
 .../util/ui/ColorChooserDialog.java           |  10 +-
 .../util/ui/ContextThemeWrapper.kt            |   2 +-
 .../quasseldroid/util/ui/DoubleClickHelper.kt |   6 +-
 .../util/ui/FixedNestingScrollView.kt         |   2 +-
 .../drawable/DrawerToggleActivityDrawable.kt  |   4 +-
 .../util/ui/settings/SeekBarPreference.kt     |  14 +--
 .../settings/ServiceBoundSettingsActivity.kt  |   5 +-
 .../util/ui/settings/SettingsActivity.kt      |   5 +-
 .../quasseldroid/util/ui/view/BannerView.kt   |  13 +--
 .../util/ui/view/InlineSnackBar.kt            |   8 +-
 .../util/ui/view/WarningBarView.kt            |  11 +-
 app/src/main/res/values/strings.xml           |   2 +
 app/src/main/res/values/themes_daynight.xml   |  29 -----
 build.gradle.kts                              |  14 +++
 gradle/convention/build.gradle.kts            |  29 ++++-
 .../gradle/wrapper/gradle-wrapper.properties  |   4 +-
 gradle/convention/settings.gradle.kts         |  14 +++
 .../kotlin/AndroidApplicationConvention.kt    |  79 +++++++++++++
 .../main/kotlin/AndroidLibraryConvention.kt   |  34 ++++++
 .../main/kotlin/KotlinAndroidConvention.kt    |  52 +++++++++
 .../src/main/kotlin/KotlinConvention.kt       |  55 +++++++++
 ...roid.signing.gradle.kts => SigningData.kt} |  30 -----
 .../kotlin/justjanne.android.app.gradle.kts   |  94 ---------------
 .../justjanne.android.library.gradle.kts      |  23 ----
 .../src/main/kotlin/justjanne.java.gradle.kts |  10 --
 .../justjanne.kotlin.android.gradle.kts       |  22 ----
 .../main/kotlin/justjanne.kotlin.gradle.kts   |  23 ----
 .../kotlin/util/BaseExtensionExtensions.kt    |   8 ++
 .../src/main/kotlin/util/ProjectExtensions.kt |  22 ++++
 gradle/libs.versions.toml                     |  60 ++++++----
 gradle/wrapper/gradle-wrapper.properties      |   4 +-
 invokergenerator/build.gradle.kts             |   4 -
 malheur/build.gradle.kts                      |   4 +
 malheur/src/main/AndroidManifest.xml          |  20 ----
 persistence/build.gradle.kts                  |   4 +
 persistence/src/main/AndroidManifest.xml      |  20 ----
 settings.gradle.kts                           |  27 +++--
 ui_spinner/build.gradle.kts                   |   4 +
 ui_spinner/src/main/AndroidManifest.xml       |  20 ----
 .../kuschku/ui/internal/ThemeEnforcement.java |   2 +-
 .../ui/shape/MaterialShapeDrawable.java       |   5 +-
 .../ui/spinner/MaterialSpinnerLayout.java     |   2 +-
 viewmodel/build.gradle.kts                    |   4 +
 viewmodel/src/main/AndroidManifest.xml        |  20 ----
 .../util/helper/LiveDataHelper.kt             |   8 +-
 .../util/helper/ObservableHelper.kt           |  12 +-
 115 files changed, 848 insertions(+), 1269 deletions(-)
 delete mode 100644 app/src/main/res/values/themes_daynight.xml
 create mode 100644 gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt
 create mode 100644 gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt
 create mode 100644 gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt
 create mode 100644 gradle/convention/src/main/kotlin/KotlinConvention.kt
 rename gradle/convention/src/main/kotlin/{justjanne.android.signing.gradle.kts => SigningData.kt} (51%)
 delete mode 100644 gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
 delete mode 100644 gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
 delete mode 100644 gradle/convention/src/main/kotlin/justjanne.java.gradle.kts
 delete mode 100644 gradle/convention/src/main/kotlin/justjanne.kotlin.android.gradle.kts
 delete mode 100644 gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts
 create mode 100644 gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt
 create mode 100644 gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
 delete mode 100644 malheur/src/main/AndroidManifest.xml
 delete mode 100644 persistence/src/main/AndroidManifest.xml
 delete mode 100644 ui_spinner/src/main/AndroidManifest.xml
 delete mode 100644 viewmodel/src/main/AndroidManifest.xml

diff --git a/README.md b/README.md
index 1d68e8e2f..0b45d9fb4 100644
--- a/README.md
+++ b/README.md
@@ -65,8 +65,6 @@ Authors of legacy Quasseldroid:
   Apache-2.0
 * [**Better Link Movement Method**](https://github.com/Saketme/Better-Link-Movement-Method)
   Apache-2.0
-* [**Butter Knife**](http://jakewharton.github.io/butterknife/)
-  Apache-2.0
 * [**Dagger 2**](https://google.github.io/dagger/)
   Apache-2.0
 * [**Glide**](https://bumptech.github.io/glide/)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5f21385b9..9b254dd23 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -18,11 +18,11 @@
  */
 
 plugins {
-  id("justjanne.android.signing")
   id("justjanne.android.app")
 }
 
 android {
+  namespace = "de.kuschku.quasseldroid"
 
   defaultConfig {
     resourceConfigurations += setOf(
@@ -94,8 +94,6 @@ dependencies {
   implementation(libs.reactivenetwork)
   implementation(libs.retrofit.core)
   implementation(libs.retrofit.converter.gson)
-  implementation(libs.butterknife.core)
-  kapt(libs.butterknife.compiler)
 
   // Quassel
   implementation(project(":viewmodel"))
@@ -113,7 +111,7 @@ dependencies {
   implementation(libs.materialdialogs.commons)
   implementation(libs.glide.core)
   implementation(libs.glide.recyclerview)
-  kapt(libs.glide.compiler)
+  ksp(libs.glide.compiler)
 
   // Quality Assurance
   implementation(project(":malheur"))
@@ -138,5 +136,4 @@ dependencies {
   androidTestImplementation(libs.androidx.test.espresso.contrib)
   androidTestImplementation(libs.androidx.test.junit)
   androidTestImplementation(libs.androidx.test.runner)
-  androidTestImplementation(libs.androidx.test.rules)
 }
diff --git a/app/sampledata/libraries.json b/app/sampledata/libraries.json
index 5031bdb06..2a3b2c1fe 100644
--- a/app/sampledata/libraries.json
+++ b/app/sampledata/libraries.json
@@ -34,15 +34,6 @@
       },
       "url": "https://github.com/Saketme/Better-Link-Movement-Method"
     },
-    {
-      "name": "Butter Knife",
-      "version": "8.8.1",
-      "license": {
-        "short_name": "Apache-2.0",
-        "full_name": "Apache License"
-      },
-      "url": "http://jakewharton.github.io/butterknife/"
-    },
     {
       "name": "Dagger 2",
       "version": "2.15",
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 23987aca5..ab32d2076 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,8 +17,7 @@
   with this program. If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="de.kuschku.quasseldroid">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
   <uses-feature
     android:name="android.hardware.type.pc"
@@ -33,7 +32,7 @@
   <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 
   <application
-    android:name=".Quasseldroid"
+    android:name="de.kuschku.quasseldroid.Quasseldroid"
     android:allowBackup="true"
     android:description="@string/app_description"
     android:fullBackupContent="@xml/backup_content"
@@ -43,7 +42,7 @@
     android:theme="@style/Theme.SplashTheme">
 
     <activity
-      android:name=".ui.chat.ChatActivity"
+      android:name="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:exported="true"
       android:launchMode="singleTask"
       android:windowSoftInputMode="adjustResize">
@@ -72,7 +71,7 @@
       android:name="de.kuschku.quasseldroid.ui.info.user.UserInfoActivity"
       android:exported="false"
       android:label="@string/label_info_user"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Normal Chat -->
@@ -80,7 +79,7 @@
       android:name="de.kuschku.quasseldroid.ui.info.channel.ChannelInfoActivity"
       android:exported="false"
       android:label="@string/label_info_channel"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Info -->
@@ -88,7 +87,7 @@
       android:name="de.kuschku.quasseldroid.ui.info.core.CoreInfoActivity"
       android:exported="false"
       android:label="@string/label_info_core"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
       android:name="de.kuschku.quasseldroid.ui.chat.topic.TopicActivity"
@@ -130,95 +129,95 @@
       android:label="@string/label_query_medium"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.CoreSettingsActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:exported="false"
       android:label="@string/label_settings_core"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.network.NetworkCreateActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.network.NetworkCreateActivity"
       android:exported="false"
       android:label="@string/settings_network_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Core Settings -->
     <activity
-      android:name=".ui.coresettings.network.NetworkEditActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity"
       android:exported="false"
       android:label="@string/settings_network_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.networkserver.NetworkServerActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.networkserver.NetworkServerActivity"
       android:exported="false"
       android:label="@string/settings_networkserver_title"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.identity.IdentityCreateActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.identity.IdentityCreateActivity"
       android:exported="false"
       android:label="@string/settings_identity_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.identity.IdentityEditActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.identity.IdentityEditActivity"
       android:exported="false"
       android:label="@string/settings_identity_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.chatlist.ChatlistCreateActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity"
       android:exported="false"
       android:label="@string/settings_chatlist_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.chatlist.ChatlistEditActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditActivity"
       android:exported="false"
       android:label="@string/settings_chatlist_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.ignorelist.IgnoreListActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity"
       android:exported="false"
       android:label="@string/settings_ignorelist_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.ignoreitem.IgnoreItemActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.ignoreitem.IgnoreItemActivity"
       android:exported="false"
       android:label="@string/settings_ignoreitem_title"
-      android:parentActivityName=".ui.coresettings.ignorelist.IgnoreListActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.highlightlist.HighlightListActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.highlightlist.HighlightListActivity"
       android:exported="false"
       android:label="@string/settings_highlightlist_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.highlightrule.HighlightRuleActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.highlightrule.HighlightRuleActivity"
       android:exported="false"
       android:label="@string/settings_highlightrule_title"
-      android:parentActivityName=".ui.coresettings.highlightlist.HighlightListActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.highlightlist.HighlightListActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.aliaslist.AliasListActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.aliaslist.AliasListActivity"
       android:exported="false"
       android:label="@string/settings_aliaslist_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.aliasitem.AliasItemActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.aliasitem.AliasItemActivity"
       android:exported="false"
       android:label="@string/settings_aliasitem_title"
-      android:parentActivityName=".ui.coresettings.aliaslist.AliasListActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.aliaslist.AliasListActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.networkconfig.NetworkConfigActivity"
+      android:name="de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigActivity"
       android:exported="false"
       android:label="@string/settings_networkconfig_title"
-      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
       android:name="de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeActivity"
@@ -226,69 +225,69 @@
       android:label="@string/label_password_change"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.clientsettings.client.ClientSettingsActivity"
+      android:name="de.kuschku.quasseldroid.ui.clientsettings.client.ClientSettingsActivity"
       android:exported="false"
       android:label="@string/label_settings_client"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.clientsettings.crash.CrashActivity"
+      android:name="de.kuschku.quasseldroid.ui.clientsettings.crash.CrashActivity"
       android:exported="false"
       android:label="@string/label_crashes"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Client Settings -->
     <activity
-      android:name=".ui.clientsettings.whitelist.WhitelistActivity"
+      android:name="de.kuschku.quasseldroid.ui.clientsettings.whitelist.WhitelistActivity"
       android:exported="false"
       android:label="@string/label_certificates"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.clientsettings.about.AboutActivity"
+      android:name="de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity"
       android:exported="false"
       android:label="@string/label_about"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.clientsettings.license.LicenseActivity"
+      android:name="de.kuschku.quasseldroid.ui.clientsettings.license.LicenseActivity"
       android:exported="false"
       android:label="@string/label_license"
-      android:parentActivityName=".ui.clientsettings.about.AboutActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.setup.accounts.selection.AccountSelectionActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:exported="false"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.setup.accounts.setup.AccountSetupActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupActivity"
       android:exported="false"
-      android:parentActivityName=".ui.setup.accounts.selection.AccountSelectionActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Client Setup Flow -->
     <activity
-      android:name=".ui.setup.accounts.edit.AccountEditActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity"
       android:exported="false"
-      android:parentActivityName=".ui.setup.accounts.selection.AccountSelectionActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.setup.core.CoreSetupActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.core.CoreSetupActivity"
       android:exported="false"
       android:label="@string/setup_core_title"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.setup.user.UserSetupActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.user.UserSetupActivity"
       android:exported="false"
       android:label="@string/setup_user_title"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Core Setup Flow -->
     <activity
-      android:name=".ui.setup.network.NetworkSetupActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.network.NetworkSetupActivity"
       android:exported="false"
       android:label="@string/setup_network_title"
-      android:parentActivityName=".ui.chat.ChatActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
 
     <!-- Core User Setup Flow -->
@@ -313,7 +312,7 @@
     </provider>
 
     <service
-      android:name=".service.QuasselService"
+      android:name="de.kuschku.quasseldroid.service.QuasselService"
       android:description="@string/connection_service_description"
       android:exported="false"
       android:label="@string/connection_service_title" />
diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
index c1796fcc7..883ca16ac 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt
@@ -24,6 +24,8 @@ import android.graphics.Typeface
 import android.graphics.drawable.Drawable
 import android.text.SpannableStringBuilder
 import androidx.annotation.ColorInt
+import com.bumptech.glide.Glide
+import com.bumptech.glide.RequestBuilder
 import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.quassel.ExtendedFeature
@@ -35,8 +37,6 @@ import de.kuschku.libquassel.util.helper.clampOf
 import de.kuschku.libquassel.util.helper.or
 import de.kuschku.libquassel.util.irc.HostmaskHelper
 import de.kuschku.libquassel.util.irc.SenderColorUtil
-import de.kuschku.quasseldroid.GlideApp
-import de.kuschku.quasseldroid.GlideRequest
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.dao.all
 import de.kuschku.quasseldroid.persistence.dao.buffers
@@ -313,8 +313,8 @@ class QuasselNotificationBackend @Inject constructor(
 
         val avatarList = AvatarHelper.avatar(messageSettings, ident, realName, avatarUrl, size)
         val avatarResult = try {
-          GlideApp.with(context).loadWithFallbacks(avatarList)
-            ?.letIf(!messageSettings.squareAvatars, GlideRequest<Drawable>::optionalCircleCrop)
+          Glide.with(context).loadWithFallbacks(avatarList)
+            ?.letIf(!messageSettings.squareAvatars, RequestBuilder<Drawable>::optionalCircleCrop)
             ?.placeholder(TextDrawable.builder().beginConfig()
                             .textColor((colorBackground and 0xFFFFFF) or (0x8A shl 24)).useFont(
                 Typeface.DEFAULT_BOLD).endConfig().let {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
index 0176e398f..edc81f495 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/AppearanceSettings.kt
@@ -42,17 +42,13 @@ data class AppearanceSettings(
   }
 
   enum class Theme(@StyleRes val style: Int) {
-    MATERIAL_DAYNIGHT(R.style.Theme_ChatTheme_Material_DayNight),
     MATERIAL_LIGHT(R.style.Theme_ChatTheme_Material_Light),
     MATERIAL_DARK(R.style.Theme_ChatTheme_Material_Dark),
-    QUASSEL_DAYNIGHT(R.style.Theme_ChatTheme_Quassel_DayNight),
     QUASSEL_LIGHT(R.style.Theme_ChatTheme_Quassel_Light),
     QUASSEL_DARK(R.style.Theme_ChatTheme_Quassel_Dark),
     AMOLED(R.style.Theme_ChatTheme_Amoled),
-    SOLARIZED_DAYNIGHT(R.style.Theme_ChatTheme_Solarized_DayNight),
     SOLARIZED_LIGHT(R.style.Theme_ChatTheme_Solarized_Light),
     SOLARIZED_DARK(R.style.Theme_ChatTheme_Solarized_Dark),
-    GRUVBOX_DAYNIGHT(R.style.Theme_ChatTheme_Gruvbox_DayNight),
     GRUVBOX_LIGHT(R.style.Theme_ChatTheme_Gruvbox_Light),
     GRUVBOX_DARK(R.style.Theme_ChatTheme_Gruvbox_Dark),
     DRACULA(R.style.Theme_ChatTheme_Dracula);
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
index 028c5095e..32734dcb6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
@@ -900,7 +900,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     }
     actionMode = mode
     statusBarColor = window.statusBarColor
-    window.statusBarColor = theme.styledAttributes(R.attr.colorPrimaryDark) {
+    window.statusBarColor = theme.styledAttributes(androidx.appcompat.R.attr.colorPrimaryDark) {
       getColor(0, 0)
     }
     super.onActionModeStarted(mode)
@@ -959,9 +959,9 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
   override fun onCreateOptionsMenu(menu: Menu?): Boolean {
     val nickCountDrawableSize = resources.getDimensionPixelSize(R.dimen.size_nick_count)
-    val nickCountDrawableColor = binding.layoutMain.layoutToolbar.toolbar.context.theme.styledAttributes(R.attr.colorControlNormal) {
-      getColor(0, 0)
-    }
+    val nickCountDrawableColor = binding.layoutMain.layoutToolbar.toolbar.context.theme.styledAttributes(
+      androidx.appcompat.R.attr.colorControlNormal
+    ) { getColor(0, 0) }
 
     menuInflater.inflate(R.menu.activity_main, menu)
     menu?.findItem(R.id.action_nicklist)?.isVisible = bufferData?.info?.type?.hasFlag(Buffer_Type.ChannelBuffer)
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 0f4fd291d..10292d879 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
@@ -26,14 +26,13 @@ import android.view.ViewGroup
 import android.widget.TextView
 import androidx.appcompat.widget.AppCompatImageView
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
+import com.bumptech.glide.Glide
+
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.helper.combineLatest
 import de.kuschku.libquassel.util.helper.value
-import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
@@ -52,16 +51,12 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class ToolbarFragment : ServiceBoundFragment() {
-  @BindView(R.id.toolbar_title)
   lateinit var toolbarTitle: TextView
 
-  @BindView(R.id.toolbar_subtitle)
   lateinit var toolbarSubtitle: TextView
 
-  @BindView(R.id.toolbar_icon)
   lateinit var icon: AppCompatImageView
 
-  @BindView(R.id.toolbar_action_area)
   lateinit var actionArea: View
 
   @Inject
@@ -98,7 +93,10 @@ class ToolbarFragment : ServiceBoundFragment() {
     savedInstanceState: Bundle?
   ): View? {
     val view = inflater.inflate(R.layout.chat_toolbar, container, false)
-    ButterKnife.bind(this, view)
+    this.toolbarTitle = view.findViewById(R.id.toolbar_title)
+    this.toolbarSubtitle = view.findViewById(R.id.toolbar_subtitle)
+    this.icon = view.findViewById(R.id.toolbar_icon)
+    this.actionArea = view.findViewById(R.id.toolbar_action_area)
 
     fun colorizeDescription(description: String?) = ircFormatDeserializer.formatString(
       description, messageSettings.colorizeMirc
@@ -136,7 +134,7 @@ class ToolbarFragment : ServiceBoundFragment() {
             icon.loadAvatars(avatarUrls, fallbackDrawable, crop = !messageSettings.squareAvatars)
             icon.visibility = View.VISIBLE
           } else {
-            GlideApp.with(icon).clear(icon)
+            Glide.with(icon).clear(icon)
             icon.visibility = View.GONE
           }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt
index 2f1d1e6ba..b51d438e6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt
@@ -29,8 +29,6 @@ import android.widget.EditText
 import androidx.appcompat.widget.AppCompatSpinner
 import androidx.appcompat.widget.SwitchCompat
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.syncables.IrcChannel
@@ -52,28 +50,13 @@ import io.reactivex.disposables.Disposable
 import javax.inject.Inject
 
 class ChannelCreateFragment : ServiceBoundSettingsFragment() {
-  @BindView(R.id.network)
   lateinit var network: AppCompatSpinner
-
-  @BindView(R.id.name)
   lateinit var name: EditText
-
-  @BindView(R.id.hidden)
   lateinit var hidden: SwitchCompat
-
-  @BindView(R.id.invite_only)
   lateinit var inviteOnly: SwitchCompat
-
-  @BindView(R.id.password_protected)
   lateinit var passwordProtected: SwitchCompat
-
-  @BindView(R.id.password_group)
   lateinit var passwordGroup: ViewGroup
-
-  @BindView(R.id.password)
   lateinit var password: EditText
-
-  @BindView(R.id.save)
   lateinit var save: Button
 
   @Inject
@@ -85,7 +68,14 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.add_create, container, false)
-    ButterKnife.bind(this, view)
+    this.network = view.findViewById(R.id.network)
+    this.name = view.findViewById(R.id.name)
+    this.hidden = view.findViewById(R.id.hidden)
+    this.inviteOnly = view.findViewById(R.id.invite_only)
+    this.passwordProtected = view.findViewById(R.id.password_protected)
+    this.passwordGroup = view.findViewById(R.id.password_group)
+    this.password = view.findViewById(R.id.password)
+    this.save = view.findViewById(R.id.save)
 
     networkId = NetworkId(
       savedInstanceState?.getInt("network_id", 0)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt
index f5b5e3c5c..c03d2d1e5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt
@@ -28,8 +28,6 @@ import android.widget.Button
 import android.widget.EditText
 import androidx.appcompat.widget.AppCompatSpinner
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.libquassel.util.helper.combineLatest
@@ -44,13 +42,8 @@ import de.kuschku.quasseldroid.viewmodel.helper.QuasselViewModelHelper
 import javax.inject.Inject
 
 class ChannelJoinFragment : ServiceBoundFragment() {
-  @BindView(R.id.network)
   lateinit var network: AppCompatSpinner
-
-  @BindView(R.id.name)
   lateinit var name: EditText
-
-  @BindView(R.id.join)
   lateinit var join: Button
 
   @Inject
@@ -62,7 +55,9 @@ class ChannelJoinFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.add_join, container, false)
-    ButterKnife.bind(this, view)
+    this.network = view.findViewById(R.id.network)
+    this.name = view.findViewById(R.id.name)
+    this.join = view.findViewById(R.id.join)
 
     networkId = NetworkId(
       savedInstanceState?.getInt("network_id", 0)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt
index 7f2545996..6a4e78aaa 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt
@@ -33,8 +33,6 @@ 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 com.bumptech.glide.Glide
 import com.bumptech.glide.ListPreloader
 import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
@@ -49,7 +47,6 @@ import de.kuschku.libquassel.util.helper.mapSwitchMap
 import de.kuschku.libquassel.util.helper.safeSwitchMap
 import de.kuschku.libquassel.util.irc.IrcCaseMappers
 import de.kuschku.libquassel.util.irc.SenderColorUtil
-import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
@@ -74,16 +71,9 @@ import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
 class QueryCreateFragment : ServiceBoundFragment() {
-  @BindView(R.id.network)
   lateinit var network: AppCompatSpinner
-
-  @BindView(R.id.name)
   lateinit var name: EditText
-
-  @BindView(R.id.query)
   lateinit var query: Button
-
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
 
   @Inject
@@ -104,7 +94,10 @@ class QueryCreateFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.add_query, container, false)
-    ButterKnife.bind(this, view)
+    this.network = view.findViewById(R.id.network)
+    this.name = view.findViewById(R.id.name)
+    this.query = view.findViewById(R.id.query)
+    this.list = view.findViewById(R.id.list)
 
     networkId = NetworkId(
       savedInstanceState?.getInt("network_id", 0)
@@ -195,7 +188,7 @@ class QueryCreateFragment : ServiceBoundFragment() {
       )
 
       override fun getPreloadRequestBuilder(item: List<Avatar>) =
-        GlideApp.with(this@QueryCreateFragment).loadWithFallbacks(item)?.override(avatarSize)
+        Glide.with(this@QueryCreateFragment).loadWithFallbacks(item)?.override(avatarSize)
     }
 
     val preloader = RecyclerViewPreloader(Glide.with(this), preloadModelProvider, sizeProvider, 10)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
index 2178edf34..9df3fcca9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
@@ -26,8 +26,6 @@ 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.BufferId
 import de.kuschku.libquassel.util.helper.combineLatest
 import de.kuschku.libquassel.util.helper.safeValue
@@ -49,7 +47,6 @@ import de.kuschku.quasseldroid.viewmodel.helper.ArchiveViewModelHelper
 import javax.inject.Inject
 
 class ArchiveFragment : ServiceBoundFragment() {
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
 
   @Inject
@@ -116,7 +113,7 @@ class ArchiveFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.chat_archive, container, false)
-    ButterKnife.bind(this, view)
+    this.list = view.findViewById(R.id.list)
 
     val chatlistId = arguments?.getInt("chatlist_id", -1) ?: -1
     modelHelper.archive.bufferViewConfigId.onNext(chatlistId)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
index 4402eb0fe..6ba43ce1a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
@@ -332,7 +332,7 @@ class ArchiveListAdapter(
           offline = itemView.context.getVectorDrawableCompat(R.drawable.ic_status_offline)?.mutate()
 
           itemView.context.theme.styledAttributes(
-            R.attr.colorAccent, R.attr.colorAway,
+            androidx.appcompat.R.attr.colorAccent, R.attr.colorAway,
             R.attr.colorTextPrimary, R.attr.colorTintActivity, R.attr.colorTintMessage,
             R.attr.colorTintHighlight
           ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
index c068ffe27..5e681052d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
@@ -286,7 +286,7 @@ class BufferListAdapter(
         offline = itemView.context.getVectorDrawableCompat(R.drawable.ic_status_offline)?.mutate()
 
         itemView.context.theme.styledAttributes(
-          R.attr.colorAccent, R.attr.colorAway,
+          androidx.appcompat.R.attr.colorAccent, R.attr.colorAway,
           R.attr.colorTextPrimary, R.attr.colorTintActivity, R.attr.colorTintMessage,
           R.attr.colorTintHighlight
         ) {
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 be0694344..77293d7c5 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
@@ -34,8 +34,6 @@ 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 com.leinardi.android.speeddial.SpeedDialActionItem
 import com.leinardi.android.speeddial.SpeedDialView
 import de.kuschku.libquassel.protocol.BufferId
@@ -71,28 +69,13 @@ import de.kuschku.quasseldroid.viewmodel.helper.ChatViewModelHelper
 import javax.inject.Inject
 
 class BufferViewConfigFragment : ServiceBoundFragment() {
-  @BindView(R.id.chatListToolbar)
   lateinit var chatListToolbar: Toolbar
-
-  @BindView(R.id.chatListSpinner)
   lateinit var chatListSpinner: AppCompatSpinner
-
-  @BindView(R.id.chatList)
   lateinit var chatList: RecyclerView
-
-  @BindView(R.id.feature_context_bufferactivitysync)
   lateinit var featureContextBufferActivitySync: WarningBarView
-
-  @BindView(R.id.buffer_search)
   lateinit var bufferSearch: EditText
-
-  @BindView(R.id.buffer_search_clear)
   lateinit var bufferSearchClear: AppCompatImageButton
-
-  @BindView(R.id.buffer_search_container)
   lateinit var bufferSearchContainer: ViewGroup
-
-  @BindView(R.id.fab_chatlist)
   lateinit var fab: SpeedDialView
 
   @Inject
@@ -169,7 +152,14 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
     savedInstanceState: Bundle?
   ): View? {
     val view = inflater.inflate(R.layout.chat_chatlist, container, false)
-    ButterKnife.bind(this, view)
+    this.chatListToolbar = view.findViewById(R.id.chatListToolbar)
+    this.chatListSpinner = view.findViewById(R.id.chatListSpinner)
+    this.chatList = view.findViewById(R.id.chatList)
+    this.featureContextBufferActivitySync = view.findViewById(R.id.feature_context_bufferactivitysync)
+    this.bufferSearch = view.findViewById(R.id.buffer_search)
+    this.bufferSearchClear = view.findViewById(R.id.buffer_search_clear)
+    this.bufferSearchContainer = view.findViewById(R.id.buffer_search_container)
+    this.fab = view.findViewById(R.id.fab_chatlist)
 
     val adapter = BufferViewConfigAdapter()
     modelHelper.bufferViewConfigs.safeSwitchMap {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
index 187d4b1fe..bdfe45ac2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
@@ -75,7 +75,7 @@ class AutoCompleteHelper(
     getColor(0, 0)
   }
 
-  private val colorAccent = activity.theme.styledAttributes(R.attr.colorAccent) {
+  private val colorAccent = activity.theme.styledAttributes(androidx.appcompat.R.attr.colorAccent) {
     getColor(0, 0)
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt
index 8874c6fb3..d00526885 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt
@@ -30,8 +30,6 @@ 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 com.google.android.material.bottomsheet.BottomSheetBehavior
 import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
 import de.kuschku.libquassel.util.Optional
@@ -50,31 +48,14 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class ChatlineFragment : ServiceBoundFragment() {
-  @BindView(R.id.chatline)
   lateinit var chatline: RichEditText
-
-  @BindView(R.id.formatting_toolbar)
   lateinit var toolbar: RichToolbar
-
-  @BindView(R.id.send)
   lateinit var send: AppCompatImageButton
-
-  @BindView(R.id.tab_complete)
   lateinit var tabComplete: AppCompatImageButton
-
-  @BindView(R.id.msg_history)
   lateinit var messageHistory: RecyclerView
-
-  @BindView(R.id.autocomplete_list)
   lateinit var autoCompleteList: RecyclerView
-
-  @BindView(R.id.close)
   lateinit var close: AppCompatImageButton
-
-  @BindView(R.id.card_panel)
   lateinit var cardPanel: View
-
-  @BindView(R.id.editor_container)
   lateinit var editorContainer: View
 
   @Inject
@@ -121,7 +102,15 @@ class ChatlineFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.chat_chatline, container, false)
-    ButterKnife.bind(this, view)
+    this.chatline = view.findViewById(R.id.chatline)
+    this.toolbar = view.findViewById(R.id.formatting_toolbar)
+    this.send = view.findViewById(R.id.send)
+    this.tabComplete = view.findViewById(R.id.tab_complete)
+    this.messageHistory = view.findViewById(R.id.msg_history)
+    this.autoCompleteList = view.findViewById(R.id.autocomplete_list)
+    this.close = view.findViewById(R.id.close)
+    this.cardPanel = view.findViewById(R.id.card_panel)
+    this.editorContainer = view.findViewById(R.id.editor_container)
 
     autoCompleteHelper = AutoCompleteHelper(
       requireActivity(),
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/RichToolbar.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/RichToolbar.kt
index 8f821563b..10243ee08 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/RichToolbar.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/RichToolbar.kt
@@ -25,40 +25,19 @@ import android.view.LayoutInflater
 import android.view.View
 import androidx.annotation.ColorInt
 import androidx.appcompat.widget.Toolbar
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.setTooltip
 
 class RichToolbar : Toolbar {
-  @BindView(R.id.action_format_bold)
   lateinit var boldButton: View
-
-  @BindView(R.id.action_format_italic)
   lateinit var italicButton: View
-
-  @BindView(R.id.action_format_underline)
   lateinit var underlineButton: View
-
-  @BindView(R.id.action_format_strikethrough)
   lateinit var strikethroughButton: View
-
-  @BindView(R.id.action_format_monospace)
   lateinit var monospaceButton: View
-
-  @BindView(R.id.action_format_foreground)
   lateinit var foregroundButton: View
-
-  @BindView(R.id.action_format_foreground_preview)
   lateinit var foregroundButtonPreview: View
-
-  @BindView(R.id.action_format_background)
   lateinit var backgroundButton: View
-
-  @BindView(R.id.action_format_background_preview)
   lateinit var backgroundButtonPreview: View
-
-  @BindView(R.id.action_format_clear)
   lateinit var clearButton: View
 
   private var listener: FormattingListener? = null
@@ -70,7 +49,16 @@ class RichToolbar : Toolbar {
 
   init {
     LayoutInflater.from(context).inflate(R.layout.widget_formatting, this, true)
-    ButterKnife.bind(this)
+    this.boldButton = this.findViewById(R.id.action_format_bold)
+    this.italicButton = this.findViewById(R.id.action_format_italic)
+    this.underlineButton = this.findViewById(R.id.action_format_underline)
+    this.strikethroughButton = this.findViewById(R.id.action_format_strikethrough)
+    this.monospaceButton = this.findViewById(R.id.action_format_monospace)
+    this.foregroundButton = this.findViewById(R.id.action_format_foreground)
+    this.foregroundButtonPreview = this.findViewById(R.id.action_format_foreground_preview)
+    this.backgroundButton = this.findViewById(R.id.action_format_background)
+    this.backgroundButtonPreview = this.findViewById(R.id.action_format_background_preview)
+    this.clearButton = this.findViewById(R.id.action_format_clear)
 
     boldButton.setTooltip()
     italicButton.setTooltip()
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 9b8d20995..1545b6ec3 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
@@ -33,8 +33,6 @@ import androidx.paging.PagedList
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.bumptech.glide.Glide
 import com.bumptech.glide.ListPreloader
 import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
@@ -48,7 +46,6 @@ import de.kuschku.libquassel.session.SessionManager
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.helper.*
 import de.kuschku.libquassel.util.irc.HostmaskHelper
-import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.dao.*
 import de.kuschku.quasseldroid.persistence.db.AccountDatabase
@@ -74,13 +71,8 @@ import javax.inject.Inject
 import kotlin.math.roundToInt
 
 class MessageListFragment : ServiceBoundFragment() {
-  @BindView(R.id.messages)
   lateinit var messageList: RecyclerView
-
-  @BindView(R.id.scrollDown)
   lateinit var scrollDown: FloatingActionButton
-
-  @BindView(R.id.swipeRefreshLayout)
   lateinit var swipeRefreshLayout: SwipeRefreshLayout
 
   @Inject
@@ -242,7 +234,9 @@ class MessageListFragment : ServiceBoundFragment() {
     savedInstanceState: Bundle?
   ): View? {
     val view = inflater.inflate(R.layout.chat_messages, container, false)
-    ButterKnife.bind(this, view)
+    this.messageList = view.findViewById(R.id.messages)
+    this.scrollDown = view.findViewById(R.id.scrollDown)
+    this.swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout)
 
     linearLayoutManager = LinearLayoutManager(context)
     linearLayoutManager.reverseLayout = true
@@ -501,7 +495,7 @@ class MessageListFragment : ServiceBoundFragment() {
       )
 
       override fun getPreloadRequestBuilder(item: List<Avatar>) =
-        GlideApp.with(this@MessageListFragment).loadWithFallbacks(item)?.override(avatarSize)
+        Glide.with(this@MessageListFragment).loadWithFallbacks(item)?.override(avatarSize)
     }
 
     val preloader = RecyclerViewPreloader(Glide.with(this), preloadModelProvider, sizeProvider, 10)
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 2bb55426f..0d0c11f0f 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
@@ -27,8 +27,6 @@ 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 com.bumptech.glide.Glide
 import com.bumptech.glide.ListPreloader
 import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
@@ -39,7 +37,6 @@ import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.util.helper.value
 import de.kuschku.libquassel.util.irc.IrcCaseMappers
 import de.kuschku.libquassel.util.irc.SenderColorUtil
-import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.MessageSettings
@@ -58,7 +55,6 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper.Companion.
 import javax.inject.Inject
 
 class NickListFragment : ServiceBoundFragment() {
-  @BindView(R.id.nickList)
   lateinit var nickList: RecyclerView
 
   @Inject
@@ -79,7 +75,7 @@ class NickListFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.chat_nicklist, container, false)
-    ButterKnife.bind(this, view)
+    this.nickList = view.findViewById(R.id.nickList)
 
     val nickListAdapter = NickListAdapter(messageSettings, clickListener)
     nickList.adapter = nickListAdapter
@@ -161,7 +157,7 @@ class NickListFragment : ServiceBoundFragment() {
       )
 
       override fun getPreloadRequestBuilder(item: List<Avatar>) =
-        GlideApp.with(this@NickListFragment).loadWithFallbacks(item)?.override(avatarSize)
+        Glide.with(this@NickListFragment).loadWithFallbacks(item)?.override(avatarSize)
     }
 
     val preloader = RecyclerViewPreloader(Glide.with(this), preloadModelProvider, sizeProvider, 10)
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 e7e3400d7..d90e0a8b6 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
@@ -27,8 +27,6 @@ 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 com.google.android.material.bottomsheet.BottomSheetBehavior
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.util.helper.invoke
@@ -48,13 +46,8 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class TopicFragment : ServiceBoundSettingsFragment(), Savable {
-  @BindView(R.id.chatline)
   lateinit var chatline: RichEditText
-
-  @BindView(R.id.formatting_toolbar)
   lateinit var toolbar: RichToolbar
-
-  @BindView(R.id.autocomplete_list)
   lateinit var autoCompleteList: RecyclerView
 
   @Inject
@@ -89,7 +82,9 @@ class TopicFragment : ServiceBoundSettingsFragment(), Savable {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_topic, container, false)
-    ButterKnife.bind(this, view)
+    this.chatline = view.findViewById(R.id.chatline)
+    this.toolbar = view.findViewById(R.id.formatting_toolbar)
+    this.autoCompleteList = view.findViewById(R.id.autocomplete_list)
 
     val autoCompleteHelper = AutoCompleteHelper(
       requireActivity(),
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 5b1451516..d8022265c 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
@@ -35,45 +35,33 @@ import androidx.core.view.ViewCompat
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import dagger.android.support.DaggerFragment
 import de.kuschku.quasseldroid.BuildConfig
 import de.kuschku.quasseldroid.R
 
 class AboutFragment : DaggerFragment() {
-
-  @BindView(R.id.version_container)
   lateinit var versionContainer: View
-
-  @BindView(R.id.version)
   lateinit var version: TextView
-
-  @BindView(R.id.action_website)
   lateinit var website: Button
-
-  @BindView(R.id.action_source)
   lateinit var source: Button
-
-  @BindView(R.id.action_privacy_policy)
   lateinit var privacyPolicy: Button
-
-  @BindView(R.id.authors)
   lateinit var authors: RecyclerView
-
-  @BindView(R.id.acknowledgements)
   lateinit var acknowledgements: RecyclerView
-
-  @BindView(R.id.translators)
   lateinit var translators: RecyclerView
-
-  @BindView(R.id.libraries)
   lateinit var libraries: RecyclerView
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.preferences_about, container, false)
-    ButterKnife.bind(this, view)
+    this.versionContainer = view.findViewById(R.id.version_container)
+    this.version = view.findViewById(R.id.version)
+    this.website = view.findViewById(R.id.action_website)
+    this.source = view.findViewById(R.id.action_source)
+    this.privacyPolicy = view.findViewById(R.id.action_privacy_policy)
+    this.authors = view.findViewById(R.id.authors)
+    this.acknowledgements = view.findViewById(R.id.acknowledgements)
+    this.translators = view.findViewById(R.id.translators)
+    this.libraries = view.findViewById(R.id.libraries)
 
     version.text = BuildConfig.VERSION_NAME
 
@@ -135,11 +123,6 @@ class AboutFragment : DaggerFragment() {
         license = apache2,
         url = "https://github.com/Saketme/Better-Link-Movement-Method"
       ),
-      Library(
-        name = "Butter Knife",
-        license = apache2,
-        url = "http://jakewharton.github.io/butterknife/"
-      ),
       Library(
         name = "Dagger 2",
         license = apache2,
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
index 58afeb033..427938813 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
@@ -93,8 +93,8 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(),
     super.onStop()
   }
 
-  override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) {
-    updateSummary(findPreference(key) as? ListPreference)
+  override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
+    updateSummary(findPreference(key!!) as? ListPreference)
     val appearanceSettings = Settings.appearance(requireContext())
     if (this.appearanceSettings.theme != appearanceSettings.theme ||
         this.appearanceSettings.language != appearanceSettings.language) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt
index 2e3f47d5e..4e2d2af83 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt
@@ -30,8 +30,6 @@ import androidx.core.view.ViewCompat
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.gson.Gson
 import com.google.gson.JsonSyntaxException
 import dagger.android.support.DaggerFragment
@@ -45,10 +43,7 @@ import java.io.File
 import javax.inject.Inject
 
 class CrashFragment : DaggerFragment() {
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
-
-  @BindView(R.id.crashes_empty)
   lateinit var crashesEmpty: TextView
 
   private lateinit var handlerThread: HandlerThread
@@ -102,7 +97,8 @@ class CrashFragment : DaggerFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.preferences_crash, container, false)
-    ButterKnife.bind(this, view)
+    this.list = view.findViewById(R.id.list)
+    this.crashesEmpty = view.findViewById(R.id.crashes_empty)
 
     setHasOptionsMenu(true)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseFragment.kt
index ffe751dfe..41db47800 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseFragment.kt
@@ -25,19 +25,16 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
-import butterknife.BindView
-import butterknife.ButterKnife
 import dagger.android.support.DaggerFragment
 import de.kuschku.quasseldroid.R
 
 class LicenseFragment : DaggerFragment() {
-  @BindView(R.id.text)
   lateinit var text: TextView
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.preferences_license, container, false)
-    ButterKnife.bind(this, view)
+    this.text = view.findViewById(R.id.text)
 
     val textResource = arguments?.getInt("license_text", 0) ?: 0
     if (textResource != 0) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistFragment.kt
index fa37fe40d..f310aced8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistFragment.kt
@@ -30,8 +30,6 @@ import androidx.core.view.ViewCompat
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.db.QuasselDatabase
 import de.kuschku.quasseldroid.util.helper.visibleIf
@@ -42,16 +40,9 @@ import javax.inject.Inject
 
 class WhitelistFragment : SettingsFragment(), Changeable,
                           Savable {
-  @BindView(R.id.certificate_whitelist)
   lateinit var certificateList: RecyclerView
-
-  @BindView(R.id.certificate_whitelist_empty)
   lateinit var certificateListEmpty: TextView
-
-  @BindView(R.id.hostname_whitelist)
   lateinit var hostnameList: RecyclerView
-
-  @BindView(R.id.hostname_whitelist_empty)
   lateinit var hostnameListEmpty: TextView
 
   @Inject
@@ -80,7 +71,10 @@ class WhitelistFragment : SettingsFragment(), Changeable,
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.preferences_whitelist, container, false)
-    ButterKnife.bind(this, view)
+    this.certificateList = view.findViewById(R.id.certificate_whitelist)
+    this.certificateListEmpty = view.findViewById(R.id.certificate_whitelist_empty)
+    this.hostnameList = view.findViewById(R.id.hostname_whitelist)
+    this.hostnameListEmpty = view.findViewById(R.id.hostname_whitelist_empty)
 
     setHasOptionsMenu(true)
 
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 274ca3feb..27f33b01c 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
@@ -29,8 +29,6 @@ import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
@@ -63,43 +61,18 @@ import io.reactivex.Observable
 import javax.inject.Inject
 
 class CoreSettingsFragment : ServiceBoundFragment() {
-  @BindView(R.id.feature_context_missing)
   lateinit var featureContextMissing: BannerView
-
-  @BindView(R.id.coreinfo)
   lateinit var coreinfo: View
-
-  @BindView(R.id.passwordchange)
   lateinit var passwordchange: View
-
-  @BindView(R.id.networks)
   lateinit var networks: RecyclerView
-
-  @BindView(R.id.new_network)
   lateinit var newNetwork: Button
-
-  @BindView(R.id.identities)
   lateinit var identities: RecyclerView
-
-  @BindView(R.id.new_identity)
   lateinit var newIdentity: Button
-
-  @BindView(R.id.chatlists)
   lateinit var chatlists: RecyclerView
-
-  @BindView(R.id.new_chatlist)
   lateinit var newChatlist: Button
-
-  @BindView(R.id.ignorelist)
   lateinit var ignorelist: View
-
-  @BindView(R.id.highlightlist)
   lateinit var highlightlist: View
-
-  @BindView(R.id.aliaslist)
   lateinit var aliaslist: View
-
-  @BindView(R.id.networkconfig)
   lateinit var networkconfig: View
 
   @Inject
@@ -108,7 +81,19 @@ class CoreSettingsFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_list, container, false)
-    ButterKnife.bind(this, view)
+    this.featureContextMissing = view.findViewById(R.id.feature_context_missing)
+    this.coreinfo = view.findViewById(R.id.coreinfo)
+    this.passwordchange = view.findViewById(R.id.passwordchange)
+    this.networks = view.findViewById(R.id.networks)
+    this.newNetwork = view.findViewById(R.id.new_network)
+    this.identities = view.findViewById(R.id.identities)
+    this.newIdentity = view.findViewById(R.id.new_identity)
+    this.chatlists = view.findViewById(R.id.chatlists)
+    this.newChatlist = view.findViewById(R.id.new_chatlist)
+    this.ignorelist = view.findViewById(R.id.ignorelist)
+    this.highlightlist = view.findViewById(R.id.highlightlist)
+    this.aliaslist = view.findViewById(R.id.aliaslist)
+    this.networkconfig = view.findViewById(R.id.networkconfig)
 
     val networkAdapter = SettingsItemAdapter<NetworkId> {
       NetworkEditActivity.launch(requireContext(), network = it)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt
index e0a1c3070..4c149a24a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt
@@ -29,8 +29,6 @@ import android.widget.EditText
 import androidx.recyclerview.widget.DefaultItemAnimator
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
 import de.kuschku.quasseldroid.R
@@ -49,16 +47,9 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class AliasItemFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
-  @BindView(R.id.name)
   lateinit var name: EditText
-
-  @BindView(R.id.expansion)
   lateinit var expansion: RichEditText
-
-  @BindView(R.id.formatting_toolbar)
   lateinit var toolbar: RichToolbar
-
-  @BindView(R.id.autocomplete_list)
   lateinit var autoCompleteList: RecyclerView
 
   @Inject
@@ -96,7 +87,10 @@ class AliasItemFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
                             savedInstanceState: Bundle?): View? {
 
     val view = inflater.inflate(R.layout.settings_aliasitem, container, false)
-    ButterKnife.bind(this, view)
+    this.name = view.findViewById(R.id.name)
+    this.expansion = view.findViewById(R.id.expansion)
+    this.toolbar = view.findViewById(R.id.formatting_toolbar)
+    this.autoCompleteList = view.findViewById(R.id.autocomplete_list)
 
     (arguments?.getSerializable("item") as? IAliasManager.Alias)?.let {
       rule = it
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListFragment.kt
index 650e7fe26..0b49fdfc8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListFragment.kt
@@ -27,8 +27,6 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.*
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.floatingactionbutton.FloatingActionButton
 import de.kuschku.libquassel.quassel.syncables.AliasManager
 import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
@@ -43,10 +41,7 @@ import de.kuschku.quasseldroid.viewmodel.helper.QuasselViewModelHelper
 import javax.inject.Inject
 
 class AliasListFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
-
-  @BindView(R.id.add)
   lateinit var add: FloatingActionButton
 
   @Inject
@@ -62,7 +57,8 @@ class AliasListFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_ignorelist, container, false)
-    ButterKnife.bind(this, view)
+    this.list = view.findViewById(R.id.list)
+    this.add = view.findViewById(R.id.add)
 
     adapter.setOnClickListener(::itemClick)
     adapter.setOnDragListener(::startDrag)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
index 5d3c46ea7..7715ba1b6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
@@ -28,8 +28,6 @@ import android.widget.EditText
 import android.widget.Spinner
 import androidx.appcompat.widget.SwitchCompat
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.Buffer_Activity
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.NetworkId
@@ -54,37 +52,16 @@ import javax.inject.Inject
 
 abstract class ChatListBaseFragment(private val initDefault: Boolean) :
   ServiceBoundSettingsFragment(), Savable, Changeable {
-  @BindView(R.id.buffer_view_name)
   lateinit var bufferViewName: EditText
-
-  @BindView(R.id.show_search)
   lateinit var showSearch: SwitchCompat
-
-  @BindView(R.id.sort_alphabetically)
   lateinit var sortAlphabetically: SwitchCompat
-
-  @BindView(R.id.add_new_buffers_automatically)
   lateinit var addNewBuffersAutomatically: SwitchCompat
-
-  @BindView(R.id.network_id)
   lateinit var networkId: Spinner
-
-  @BindView(R.id.show_status_buffer)
   lateinit var showStatusBuffer: SwitchCompat
-
-  @BindView(R.id.show_channels)
   lateinit var showChannels: SwitchCompat
-
-  @BindView(R.id.show_queries)
   lateinit var showQueries: SwitchCompat
-
-  @BindView(R.id.minimum_activity)
   lateinit var minimumActivity: Spinner
-
-  @BindView(R.id.hide_inactive_buffers)
   lateinit var hideInactiveBuffers: SwitchCompat
-
-  @BindView(R.id.hide_inactive_networks)
   lateinit var hideInactiveNetworks: SwitchCompat
 
   @Inject
@@ -95,7 +72,17 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) :
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_chatlist, container, false)
-    ButterKnife.bind(this, view)
+    this.bufferViewName = view.findViewById(R.id.buffer_view_name)
+    this.showSearch = view.findViewById(R.id.show_search)
+    this.sortAlphabetically = view.findViewById(R.id.sort_alphabetically)
+    this.addNewBuffersAutomatically = view.findViewById(R.id.add_new_buffers_automatically)
+    this.networkId = view.findViewById(R.id.network_id)
+    this.showStatusBuffer = view.findViewById(R.id.show_status_buffer)
+    this.showChannels = view.findViewById(R.id.show_channels)
+    this.showQueries = view.findViewById(R.id.show_queries)
+    this.minimumActivity = view.findViewById(R.id.minimum_activity)
+    this.hideInactiveBuffers = view.findViewById(R.id.hide_inactive_buffers)
+    this.hideInactiveNetworks = view.findViewById(R.id.hide_inactive_networks)
 
     val chatlistId = arguments?.getInt("chatlist", -1) ?: -1
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
index cd939ee03..f2b9f3c9c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightListFragment.kt
@@ -33,8 +33,6 @@ import androidx.recyclerview.widget.DefaultItemAnimator
 import androidx.recyclerview.widget.ItemTouchHelper
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.ExtendedFeature
 import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
 import de.kuschku.libquassel.quassel.syncables.interfaces.IHighlightRuleManager
@@ -50,25 +48,12 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class HighlightListFragment : ServiceBoundSettingsFragment(), Savable, Changeable {
-  @BindView(R.id.feature_context_coresidehighlights)
   lateinit var featureContextCoreSideHighlights: WarningBarView
-
-  @BindView(R.id.highlight_nick_type)
   lateinit var highlightNickType: Spinner
-
-  @BindView(R.id.is_case_sensitive)
   lateinit var isCaseSensitive: SwitchCompat
-
-  @BindView(R.id.highlight_rules)
   lateinit var rules: RecyclerView
-
-  @BindView(R.id.new_highlight_rule)
   lateinit var newHighlightRule: Button
-
-  @BindView(R.id.highlight_ignore_rules)
   lateinit var ignoreRules: RecyclerView
-
-  @BindView(R.id.new_highlight_ignore_rule)
   lateinit var newHighlightIgnoreRule: Button
 
   @Inject
@@ -87,7 +72,13 @@ class HighlightListFragment : ServiceBoundSettingsFragment(), Savable, Changeabl
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_highlightlist, container, false)
-    ButterKnife.bind(this, view)
+    this.featureContextCoreSideHighlights = view.findViewById(R.id.feature_context_coresidehighlights)
+    this.highlightNickType = view.findViewById(R.id.highlight_nick_type)
+    this.isCaseSensitive = view.findViewById(R.id.is_case_sensitive)
+    this.rules = view.findViewById(R.id.highlight_rules)
+    this.newHighlightRule = view.findViewById(R.id.new_highlight_rule)
+    this.ignoreRules = view.findViewById(R.id.highlight_ignore_rules)
+    this.newHighlightIgnoreRule = view.findViewById(R.id.new_highlight_ignore_rule)
 
     rules.adapter = rulesAdapter
     rules.layoutManager = LinearLayoutManager(requireContext())
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
index 3b974fe3f..795b4e184 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightrule/HighlightRuleFragment.kt
@@ -27,8 +27,6 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.settings.fragment.Changeable
@@ -37,22 +35,11 @@ import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFra
 
 class HighlightRuleFragment : ServiceBoundSettingsFragment(), Savable,
                               Changeable {
-  @BindView(R.id.enabled)
   lateinit var enabled: SwitchCompat
-
-  @BindView(R.id.name)
   lateinit var name: EditText
-
-  @BindView(R.id.is_regex)
   lateinit var isRegex: SwitchCompat
-
-  @BindView(R.id.is_case_sensitive)
   lateinit var isCaseSensitive: SwitchCompat
-
-  @BindView(R.id.sender)
   lateinit var sender: EditText
-
-  @BindView(R.id.channel)
   lateinit var channel: EditText
 
   private var rule: HighlightRuleManager.HighlightRule? = null
@@ -63,7 +50,12 @@ class HighlightRuleFragment : ServiceBoundSettingsFragment(), Savable,
                             savedInstanceState: Bundle?): View? {
 
     val view = inflater.inflate(R.layout.settings_highlightrule, container, false)
-    ButterKnife.bind(this, view)
+    this.enabled = view.findViewById(R.id.enabled)
+    this.name = view.findViewById(R.id.name)
+    this.isRegex = view.findViewById(R.id.is_regex)
+    this.isCaseSensitive = view.findViewById(R.id.is_case_sensitive)
+    this.sender = view.findViewById(R.id.sender)
+    this.channel = view.findViewById(R.id.channel)
 
     isInverse = arguments?.getBoolean("inverse")
     (arguments?.getSerializable("item") as? HighlightRuleManager.HighlightRule)?.let {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
index e9daf44c8..38763e5ba 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
@@ -31,8 +31,6 @@ import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.ItemTouchHelper
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.libquassel.quassel.syncables.Identity
@@ -50,41 +48,17 @@ import javax.inject.Inject
 
 abstract class IdentityBaseFragment(private val initDefault: Boolean) :
   ServiceBoundSettingsFragment(), Savable, Changeable {
-
-  @BindView(R.id.identity_name)
   lateinit var identityName: EditText
-
-  @BindView(R.id.real_name)
   lateinit var realName: EditText
-
-  @BindView(R.id.ident)
   lateinit var ident: EditText
-
-  @BindView(R.id.nicks)
   lateinit var nicks: RecyclerView
-
-  @BindView(R.id.new_nick)
   lateinit var newNick: Button
-
-  @BindView(R.id.kick_reason)
   lateinit var kickReason: EditText
-
-  @BindView(R.id.part_reason)
   lateinit var partReason: EditText
-
-  @BindView(R.id.quit_reason)
   lateinit var quitReason: EditText
-
-  @BindView(R.id.away_reason)
   lateinit var awayReason: EditText
-
-  @BindView(R.id.detach_away)
   lateinit var detachAway: SwitchCompat
-
-  @BindView(R.id.detach_away_group)
   lateinit var detachAwayGroup: ViewGroup
-
-  @BindView(R.id.detach_away_reason)
   lateinit var detachAwayReason: EditText
 
   @Inject
@@ -98,7 +72,18 @@ abstract class IdentityBaseFragment(private val initDefault: Boolean) :
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_identity, container, false)
-    ButterKnife.bind(this, view)
+    this.identityName = view.findViewById(R.id.identity_name)
+    this.realName = view.findViewById(R.id.real_name)
+    this.ident = view.findViewById(R.id.ident)
+    this.nicks = view.findViewById(R.id.nicks)
+    this.newNick = view.findViewById(R.id.new_nick)
+    this.kickReason = view.findViewById(R.id.kick_reason)
+    this.partReason = view.findViewById(R.id.part_reason)
+    this.quitReason = view.findViewById(R.id.quit_reason)
+    this.awayReason = view.findViewById(R.id.away_reason)
+    this.detachAway = view.findViewById(R.id.detach_away)
+    this.detachAwayGroup = view.findViewById(R.id.detach_away_group)
+    this.detachAwayReason = view.findViewById(R.id.detach_away_reason)
 
     val identityId = IdentityId(arguments?.getInt("identity", -1) ?: -1)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
index 2bb07c32b..bf842b4d9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
@@ -29,8 +29,6 @@ import android.widget.AdapterView
 import android.widget.EditText
 import android.widget.Spinner
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.IgnoreListManager
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.AnimationHelper
@@ -40,28 +38,13 @@ import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFra
 
 class IgnoreItemFragment : ServiceBoundSettingsFragment(), Savable,
                            Changeable {
-  @BindView(R.id.enabled)
   lateinit var enabled: SwitchCompat
-
-  @BindView(R.id.ignore_rule)
   lateinit var ignoreRule: EditText
-
-  @BindView(R.id.isregex)
   lateinit var isRegEx: SwitchCompat
-
-  @BindView(R.id.type)
   lateinit var type: Spinner
-
-  @BindView(R.id.strictness)
   lateinit var strictness: Spinner
-
-  @BindView(R.id.scope)
   lateinit var scope: Spinner
-
-  @BindView(R.id.scope_rule)
   lateinit var scopeRule: EditText
-
-  @BindView(R.id.scopegroup)
   lateinit var scopegroup: ViewGroup
 
   private var item: IgnoreListManager.IgnoreListItem? = null
@@ -69,7 +52,14 @@ class IgnoreItemFragment : ServiceBoundSettingsFragment(), Savable,
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_ignoreitem, container, false)
-    ButterKnife.bind(this, view)
+    this.enabled = view.findViewById(R.id.enabled)
+    this.ignoreRule = view.findViewById(R.id.ignore_rule)
+    this.isRegEx = view.findViewById(R.id.isregex)
+    this.type = view.findViewById(R.id.type)
+    this.strictness = view.findViewById(R.id.strictness)
+    this.scope = view.findViewById(R.id.scope)
+    this.scopeRule = view.findViewById(R.id.scope_rule)
+    this.scopegroup = view.findViewById(R.id.scopegroup)
 
     (arguments?.getSerializable("item") as? IgnoreListManager.IgnoreListItem)?.let {
       item = it
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
index bb4b03ba5..76b0c429b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
@@ -30,8 +30,6 @@ import androidx.recyclerview.widget.DefaultItemAnimator
 import androidx.recyclerview.widget.ItemTouchHelper
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.floatingactionbutton.FloatingActionButton
 import de.kuschku.libquassel.quassel.syncables.IgnoreListManager
 import de.kuschku.libquassel.util.Optional
@@ -47,10 +45,7 @@ import javax.inject.Inject
 
 class IgnoreListFragment : ServiceBoundSettingsFragment(), Savable,
                            Changeable {
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
-
-  @BindView(R.id.add)
   lateinit var add: FloatingActionButton
 
   @Inject
@@ -65,7 +60,8 @@ class IgnoreListFragment : ServiceBoundSettingsFragment(), Savable,
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_ignorelist, container, false)
-    ButterKnife.bind(this, view)
+    this.list = view.findViewById(R.id.list)
+    this.add = view.findViewById(R.id.add)
 
     list.adapter = adapter
     list.layoutManager = LinearLayoutManager(requireContext())
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt
index 2da6c9f38..39bd8cc55 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt
@@ -34,8 +34,6 @@ import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.ItemTouchHelper
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.syncables.Identity
@@ -63,79 +61,30 @@ import kotlin.math.roundToInt
 
 abstract class NetworkBaseFragment(private val initDefault: Boolean) :
   ServiceBoundSettingsFragment(), Savable, Changeable {
-  @BindView(R.id.network_name)
   lateinit var networkName: EditText
-
-  @BindView(R.id.identity)
   lateinit var identity: Spinner
-
-  @BindView(R.id.servers)
   lateinit var servers: RecyclerView
-
-  @BindView(R.id.new_server)
   lateinit var newServer: Button
-
-  @BindView(R.id.sasl_enabled)
   lateinit var saslEnabled: SwitchCompat
-
-  @BindView(R.id.sasl_group)
   lateinit var saslGroup: ViewGroup
-
-  @BindView(R.id.sasl_account)
   lateinit var saslAccount: EditText
-
-  @BindView(R.id.sasl_password)
   lateinit var saslPassword: EditText
-
-  @BindView(R.id.autoidentify_enabled)
   lateinit var autoidentifyEnabled: SwitchCompat
-
-  @BindView(R.id.autoidentify_group)
   lateinit var autoidentifyGroup: ViewGroup
-
-  @BindView(R.id.autoidentify_warning)
   lateinit var autoidentifyWarning: InlineSnackBar
-
-  @BindView(R.id.autoidentify_service)
   lateinit var autoidentifyService: EditText
-
-  @BindView(R.id.autoidentify_password)
   lateinit var autoidentifyPassword: EditText
-
-  @BindView(R.id.autoreconnect_enabled)
   lateinit var autoreconnectEnabled: SwitchCompat
-
-  @BindView(R.id.autoreconnect_group)
   lateinit var autoreconnectGroup: ViewGroup
-
-  @BindView(R.id.autoreconnect_interval)
   lateinit var autoreconnectInterval: EditText
-
-  @BindView(R.id.autoreconnect_attempts)
   lateinit var autoreconnectRetries: EditText
-
-  @BindView(R.id.autoreconnect_unlimited)
   lateinit var autoreconnectUnlimited: SwitchCompat
-
-  @BindView(R.id.perform)
   lateinit var perform: EditText
-
-  @BindView(R.id.rejoin_channels)
   lateinit var rejoinChannels: SwitchCompat
-
-  @BindView(R.id.customratelimits_enabled)
   lateinit var customratelimitsEnabled: SwitchCompat
-
-  @BindView(R.id.customratelimits_group)
   lateinit var customratelimitsGroup: ViewGroup
-
-  @BindView(R.id.customratelimits_burstsize)
   lateinit var customratelimitsBurstSize: EditText
-
-  @BindView(R.id.customratelimits_unlimited)
   lateinit var customratelimitsUnlimited: SwitchCompat
-
-  @BindView(R.id.customratelimits_delay)
   lateinit var customratelimitsDelay: EditText
 
   @Inject
@@ -149,7 +98,31 @@ abstract class NetworkBaseFragment(private val initDefault: Boolean) :
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_network, container, false)
-    ButterKnife.bind(this, view)
+    this.networkName = view.findViewById(R.id.network_name)
+    this.identity = view.findViewById(R.id.identity)
+    this.servers = view.findViewById(R.id.servers)
+    this.newServer = view.findViewById(R.id.new_server)
+    this.saslEnabled = view.findViewById(R.id.sasl_enabled)
+    this.saslGroup = view.findViewById(R.id.sasl_group)
+    this.saslAccount = view.findViewById(R.id.sasl_account)
+    this.saslPassword = view.findViewById(R.id.sasl_password)
+    this.autoidentifyEnabled = view.findViewById(R.id.autoidentify_enabled)
+    this.autoidentifyGroup = view.findViewById(R.id.autoidentify_group)
+    this.autoidentifyWarning = view.findViewById(R.id.autoidentify_warning)
+    this.autoidentifyService = view.findViewById(R.id.autoidentify_service)
+    this.autoidentifyPassword = view.findViewById(R.id.autoidentify_password)
+    this.autoreconnectEnabled = view.findViewById(R.id.autoreconnect_enabled)
+    this.autoreconnectGroup = view.findViewById(R.id.autoreconnect_group)
+    this.autoreconnectInterval = view.findViewById(R.id.autoreconnect_interval)
+    this.autoreconnectRetries = view.findViewById(R.id.autoreconnect_attempts)
+    this.autoreconnectUnlimited = view.findViewById(R.id.autoreconnect_unlimited)
+    this.perform = view.findViewById(R.id.perform)
+    this.rejoinChannels = view.findViewById(R.id.rejoin_channels)
+    this.customratelimitsEnabled = view.findViewById(R.id.customratelimits_enabled)
+    this.customratelimitsGroup = view.findViewById(R.id.customratelimits_group)
+    this.customratelimitsBurstSize = view.findViewById(R.id.customratelimits_burstsize)
+    this.customratelimitsUnlimited = view.findViewById(R.id.customratelimits_unlimited)
+    this.customratelimitsDelay = view.findViewById(R.id.customratelimits_delay)
 
     val networkId = NetworkId(arguments?.getInt("network", -1) ?: -1)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
index 28805a4ea..6de953ceb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
@@ -26,8 +26,6 @@ import android.view.ViewGroup
 import android.widget.EditText
 import androidx.appcompat.widget.SwitchCompat
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.NetworkConfig
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.quasseldroid.R
@@ -41,34 +39,15 @@ import javax.inject.Inject
 
 class NetworkConfigFragment : ServiceBoundSettingsFragment(), Savable,
                               Changeable {
-  @BindView(R.id.ping_timeout_enabled)
   lateinit var pingTimeoutEnabled: SwitchCompat
-
-  @BindView(R.id.ping_timeout_group)
   lateinit var pingTimeoutGroup: ViewGroup
-
-  @BindView(R.id.ping_interval)
   lateinit var pingInterval: EditText
-
-  @BindView(R.id.max_ping_count)
   lateinit var maxPingCount: EditText
-
-  @BindView(R.id.auto_who_enabled)
   lateinit var autoWhoEnabled: SwitchCompat
-
-  @BindView(R.id.auto_who_group)
   lateinit var autoWhoGroup: ViewGroup
-
-  @BindView(R.id.auto_who_interval)
   lateinit var autoWhoInterval: EditText
-
-  @BindView(R.id.auto_who_nick_limit)
   lateinit var autoWhoNickLimit: EditText
-
-  @BindView(R.id.auto_who_delay)
   lateinit var autoWhoDelay: EditText
-
-  @BindView(R.id.standard_ctcp)
   lateinit var standardCtcp: SwitchCompat
 
   @Inject
@@ -79,7 +58,16 @@ class NetworkConfigFragment : ServiceBoundSettingsFragment(), Savable,
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_networkconfig, container, false)
-    ButterKnife.bind(this, view)
+    this.pingTimeoutEnabled = view.findViewById(R.id.ping_timeout_enabled)
+    this.pingTimeoutGroup = view.findViewById(R.id.ping_timeout_group)
+    this.pingInterval = view.findViewById(R.id.ping_interval)
+    this.maxPingCount = view.findViewById(R.id.max_ping_count)
+    this.autoWhoEnabled = view.findViewById(R.id.auto_who_enabled)
+    this.autoWhoGroup = view.findViewById(R.id.auto_who_group)
+    this.autoWhoInterval = view.findViewById(R.id.auto_who_interval)
+    this.autoWhoNickLimit = view.findViewById(R.id.auto_who_nick_limit)
+    this.autoWhoDelay = view.findViewById(R.id.auto_who_delay)
+    this.standardCtcp = view.findViewById(R.id.standard_ctcp)
 
     modelHelper.networkConfig
       .filter(Optional<NetworkConfig>::isPresent)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerFragment.kt
index d038fe571..fcfb5cb6a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/NetworkServerFragment.kt
@@ -28,8 +28,6 @@ import android.view.ViewGroup
 import android.widget.EditText
 import android.widget.Spinner
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_PLAINTEXT
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_SSL
@@ -41,40 +39,17 @@ import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFra
 
 class NetworkServerFragment : ServiceBoundSettingsFragment(), Savable,
                               Changeable {
-  @BindView(R.id.host)
   lateinit var host: EditText
-
-  @BindView(R.id.port)
   lateinit var port: EditText
-
-  @BindView(R.id.ssl_enabled)
   lateinit var sslEnabled: SwitchCompat
-
-  @BindView(R.id.ssl_verify)
   lateinit var sslVerify: SwitchCompat
-
-  @BindView(R.id.password)
   lateinit var password: EditText
-
-  @BindView(R.id.proxy_enabled)
   lateinit var proxyEnabled: SwitchCompat
-
-  @BindView(R.id.proxy_group)
   lateinit var proxyGroup: ViewGroup
-
-  @BindView(R.id.proxy_type)
   lateinit var proxyType: Spinner
-
-  @BindView(R.id.proxy_host)
   lateinit var proxyHost: EditText
-
-  @BindView(R.id.proxy_port)
   lateinit var proxyPort: EditText
-
-  @BindView(R.id.proxy_user)
   lateinit var proxyUser: EditText
-
-  @BindView(R.id.proxy_pass)
   lateinit var proxyPass: EditText
 
   private var item: INetwork.Server? = null
@@ -82,7 +57,18 @@ class NetworkServerFragment : ServiceBoundSettingsFragment(), Savable,
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_networkserver, container, false)
-    ButterKnife.bind(this, view)
+    this.host = view.findViewById(R.id.host)
+    this.port = view.findViewById(R.id.port)
+    this.sslEnabled = view.findViewById(R.id.ssl_enabled)
+    this.sslVerify = view.findViewById(R.id.ssl_verify)
+    this.password = view.findViewById(R.id.password)
+    this.proxyEnabled = view.findViewById(R.id.proxy_enabled)
+    this.proxyGroup = view.findViewById(R.id.proxy_group)
+    this.proxyType = view.findViewById(R.id.proxy_type)
+    this.proxyHost = view.findViewById(R.id.proxy_host)
+    this.proxyPort = view.findViewById(R.id.proxy_port)
+    this.proxyUser = view.findViewById(R.id.proxy_user)
+    this.proxyPass = view.findViewById(R.id.proxy_pass)
 
     (arguments?.getSerializable("server") as? INetwork.Server)?.let {
       item = it
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
index 0f2a8df71..90eb2db3b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt
@@ -28,8 +28,6 @@ import android.widget.Button
 import android.widget.EditText
 import android.widget.TextView
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.libquassel.quassel.syncables.RpcHandler
 import de.kuschku.libquassel.session.ISession
@@ -49,31 +47,14 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar
 import javax.inject.Inject
 
 class PasswordChangeFragment : ServiceBoundFragment() {
-  @BindView(R.id.user)
   lateinit var user: EditText
-
-  @BindView(R.id.password_old_wrapper)
   lateinit var oldPasswordWrapper: TextInputLayout
-
-  @BindView(R.id.password_old)
   lateinit var oldPassword: EditText
-
-  @BindView(R.id.password_new)
   lateinit var newPassword: EditText
-
-  @BindView(R.id.password_repeat_wrapper)
   lateinit var repeatPasswordWrapper: TextInputLayout
-
-  @BindView(R.id.password_repeat)
   lateinit var repeatPassword: EditText
-
-  @BindView(R.id.error)
   lateinit var error: TextView
-
-  @BindView(R.id.save)
   lateinit var save: Button
-
-  @BindView(R.id.progress)
   lateinit var progress: MaterialProgressBar
 
   @Inject
@@ -87,7 +68,15 @@ class PasswordChangeFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.settings_passwordchange, container, false)
-    ButterKnife.bind(this, view)
+    this.user = view.findViewById(R.id.user)
+    this.oldPasswordWrapper = view.findViewById(R.id.password_old_wrapper)
+    this.oldPassword = view.findViewById(R.id.password_old)
+    this.newPassword = view.findViewById(R.id.password_new)
+    this.repeatPasswordWrapper = view.findViewById(R.id.password_repeat_wrapper)
+    this.repeatPassword = view.findViewById(R.id.password_repeat)
+    this.error = view.findViewById(R.id.error)
+    this.save = view.findViewById(R.id.save)
+    this.progress = view.findViewById(R.id.progress)
 
     val account = accountDatabase.accounts().findById(accountId)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/certificate/CertificateInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/certificate/CertificateInfoFragment.kt
index 78670aaa9..ca16bd675 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/certificate/CertificateInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/certificate/CertificateInfoFragment.kt
@@ -25,8 +25,6 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.ssl.X509Helper
 import de.kuschku.libquassel.ssl.commonName
 import de.kuschku.libquassel.ssl.organization
@@ -45,56 +43,25 @@ import org.threeten.bp.format.FormatStyle
 import javax.inject.Inject
 
 class CertificateInfoFragment : ServiceBoundSettingsFragment() {
-
-  @BindView(R.id.content)
   lateinit var content: View
-  @BindView(R.id.error)
   lateinit var error: View
-
-  @BindView(R.id.subject_common_name_wrapper)
   lateinit var subjectCommonNameWrapper: View
-  @BindView(R.id.subject_common_name)
   lateinit var subjectCommonName: TextView
-
-  @BindView(R.id.subject_hostnames_wrapper)
   lateinit var subjectHostnamesWrapper: View
-  @BindView(R.id.subject_hostnames)
   lateinit var subjectHostnames: TextView
-
-  @BindView(R.id.subject_organization_wrapper)
   lateinit var subjectOrganizationWrapper: View
-  @BindView(R.id.subject_organization)
   lateinit var subjectOrganization: TextView
-
-  @BindView(R.id.subject_organizational_unit_wrapper)
   lateinit var subjectOrganizationalUnitWrapper: View
-  @BindView(R.id.subject_organizational_unit)
   lateinit var subjectOrganizationalUnit: TextView
-
-  @BindView(R.id.issuer_common_name_wrapper)
   lateinit var issuerCommonNameWrapper: View
-  @BindView(R.id.issuer_common_name)
   lateinit var issuerCommonName: TextView
-
-  @BindView(R.id.issuer_organization_wrapper)
   lateinit var issuerOrganizationWrapper: View
-  @BindView(R.id.issuer_organization)
   lateinit var issuerOrganization: TextView
-
-  @BindView(R.id.issuer_organizational_unit_wrapper)
   lateinit var issuerOrganizationalUnitWrapper: View
-  @BindView(R.id.issuer_organizational_unit)
   lateinit var issuerOrganizationalUnit: TextView
-
-  @BindView(R.id.not_before)
   lateinit var notBefore: TextView
-  @BindView(R.id.not_after)
   lateinit var notAfter: TextView
-
-  @BindView(R.id.fingerprint_sha256)
   lateinit var fingerprintSha256: TextView
-
-  @BindView(R.id.fingerprint_sha1)
   lateinit var fingerprintSha1: TextView
 
   @Inject
@@ -103,7 +70,26 @@ class CertificateInfoFragment : ServiceBoundSettingsFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_certificate, container, false)
-    ButterKnife.bind(this, view)
+    this.content = view.findViewById(R.id.content)
+    this.error = view.findViewById(R.id.error)
+    this.subjectCommonNameWrapper = view.findViewById(R.id.subject_common_name_wrapper)
+    this.subjectCommonName = view.findViewById(R.id.subject_common_name)
+    this.subjectHostnamesWrapper = view.findViewById(R.id.subject_hostnames_wrapper)
+    this.subjectHostnames = view.findViewById(R.id.subject_hostnames)
+    this.subjectOrganizationWrapper = view.findViewById(R.id.subject_organization_wrapper)
+    this.subjectOrganization = view.findViewById(R.id.subject_organization)
+    this.subjectOrganizationalUnitWrapper = view.findViewById(R.id.subject_organizational_unit_wrapper)
+    this.subjectOrganizationalUnit = view.findViewById(R.id.subject_organizational_unit)
+    this.issuerCommonNameWrapper = view.findViewById(R.id.issuer_common_name_wrapper)
+    this.issuerCommonName = view.findViewById(R.id.issuer_common_name)
+    this.issuerOrganizationWrapper = view.findViewById(R.id.issuer_organization_wrapper)
+    this.issuerOrganization = view.findViewById(R.id.issuer_organization)
+    this.issuerOrganizationalUnitWrapper = view.findViewById(R.id.issuer_organizational_unit_wrapper)
+    this.issuerOrganizationalUnit = view.findViewById(R.id.issuer_organizational_unit)
+    this.notBefore = view.findViewById(R.id.not_before)
+    this.notAfter = view.findViewById(R.id.not_after)
+    this.fingerprintSha256 = view.findViewById(R.id.fingerprint_sha256)
+    this.fingerprintSha1 = view.findViewById(R.id.fingerprint_sha1)
 
     val dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
index 071de92ca..867d9b18a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt
@@ -27,8 +27,6 @@ import android.view.ViewGroup
 import android.widget.Button
 import android.widget.TextView
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.NetworkId
@@ -50,26 +48,12 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class ChannelInfoFragment : ServiceBoundFragment() {
-
-  @BindView(R.id.name)
   lateinit var name: TextView
-
-  @BindView(R.id.topic)
   lateinit var topic: TextView
-
-  @BindView(R.id.action_edit_topic)
   lateinit var actionEditTopic: Button
-
-  @BindView(R.id.action_who)
   lateinit var actionWho: Button
-
-  @BindView(R.id.action_part)
   lateinit var actionPart: Button
-
-  @BindView(R.id.action_join)
   lateinit var actionJoin: Button
-
-  @BindView(R.id.action_shortcut)
   lateinit var actionShortcut: Button
 
   @Inject
@@ -84,7 +68,13 @@ class ChannelInfoFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_channel, container, false)
-    ButterKnife.bind(this, view)
+    this.name = view.findViewById(R.id.name)
+    this.topic = view.findViewById(R.id.topic)
+    this.actionEditTopic = view.findViewById(R.id.action_edit_topic)
+    this.actionWho = view.findViewById(R.id.action_who)
+    this.actionPart = view.findViewById(R.id.action_part)
+    this.actionJoin = view.findViewById(R.id.action_join)
+    this.actionShortcut = view.findViewById(R.id.action_shortcut)
 
     val openBuffer = arguments?.getBoolean("openBuffer")
     val bufferId = BufferId(arguments?.getInt("bufferId") ?: -1)
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
index c6bb63cd1..e9352e809 100644
--- 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
@@ -51,7 +51,7 @@ class ChannelListAdapter @Inject constructor(
         oldItem == newItem
     }
   ) {
-  val colorAccent = context.theme.styledAttributes(R.attr.colorAccent) {
+  val colorAccent = context.theme.styledAttributes(androidx.appcompat.R.attr.colorAccent) {
     getColor(0, 0)
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
index 01555f395..8df314a05 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt
@@ -28,8 +28,6 @@ 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
@@ -49,19 +47,10 @@ 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
@@ -112,7 +101,11 @@ class ChannelListFragment : ServiceBoundSettingsFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_channellist, container, false)
-    ButterKnife.bind(this, view)
+    this.searchInput = view.findViewById(R.id.search_input)
+    this.searchButton = view.findViewById(R.id.search_button)
+    this.progress = view.findViewById(R.id.progress)
+    this.searchResults = view.findViewById(R.id.search_results)
+    this.errorDisplay = view.findViewById(R.id.error)
 
     val networkId = NetworkId(arguments?.getInt("network_id", -1) ?: -1)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
index a7fb681ef..e1ce42197 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt
@@ -30,8 +30,6 @@ import android.widget.TextView
 import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.ssl.X509Helper
 import de.kuschku.libquassel.ssl.commonName
@@ -56,41 +54,17 @@ import javax.inject.Inject
 import javax.net.ssl.SSLPeerUnverifiedException
 
 class CoreInfoFragment : ServiceBoundFragment() {
-
-  @BindView(R.id.version)
   lateinit var version: TextView
-
-  @BindView(R.id.version_date)
   lateinit var versionDate: TextView
-
-  @BindView(R.id.missing_features)
   lateinit var missingFeatures: Button
-
-  @BindView(R.id.uptime_container)
   lateinit var uptimeContainer: View
-
-  @BindView(R.id.uptime)
   lateinit var uptime: TextView
-
-  @BindView(R.id.secure_certificate)
   lateinit var secureCertificate: TextView
-
-  @BindView(R.id.secure_certificate_icon)
   lateinit var secureCertificateIcon: ImageView
-
-  @BindView(R.id.secure_connection_protocol)
   lateinit var secureConnectionProtocol: TextView
-
-  @BindView(R.id.secure_connection_ciphersuite)
   lateinit var secureConnectionCiphersuite: TextView
-
-  @BindView(R.id.secure_details)
   lateinit var secureDetails: Button
-
-  @BindView(R.id.clients_title)
   lateinit var clientsTitle: View
-
-  @BindView(R.id.clients)
   lateinit var clients: RecyclerView
 
   @Inject
@@ -111,7 +85,18 @@ class CoreInfoFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_core, container, false)
-    ButterKnife.bind(this, view)
+    this.version = view.findViewById(R.id.version)
+    this.versionDate = view.findViewById(R.id.version_date)
+    this.missingFeatures = view.findViewById(R.id.missing_features)
+    this.uptimeContainer = view.findViewById(R.id.uptime_container)
+    this.uptime = view.findViewById(R.id.uptime)
+    this.secureCertificate = view.findViewById(R.id.secure_certificate)
+    this.secureCertificateIcon = view.findViewById(R.id.secure_certificate_icon)
+    this.secureConnectionProtocol = view.findViewById(R.id.secure_connection_protocol)
+    this.secureConnectionCiphersuite = view.findViewById(R.id.secure_connection_ciphersuite)
+    this.secureDetails = view.findViewById(R.id.secure_details)
+    this.clientsTitle = view.findViewById(R.id.clients_title)
+    this.clients = view.findViewById(R.id.clients)
 
     var missingFeatureList: List<MissingFeature> = emptyList()
     combineLatest(modelHelper.coreInfo, modelHelper.coreFeatures).toLiveData()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
index b41846198..5dc6b3626 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
@@ -37,8 +37,6 @@ 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.BufferId
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.Message_Type
@@ -77,61 +75,24 @@ import java.util.*
 import javax.inject.Inject
 
 class UserInfoFragment : ServiceBoundFragment() {
-  @BindView(R.id.avatar)
   lateinit var avatar: ImageView
-
-  @BindView(R.id.nick)
   lateinit var nick: TextView
-
-  @BindView(R.id.real_name)
   lateinit var realName: TextView
-
-  @BindView(R.id.action_query)
   lateinit var actionQuery: Button
-
-  @BindView(R.id.action_ignore)
   lateinit var actionIgnore: Button
-
-  @BindView(R.id.action_whois)
   lateinit var actionWhois: Button
-
-  @BindView(R.id.action_mention)
   lateinit var actionMention: Button
-
-  @BindView(R.id.action_shortcut)
   lateinit var actionShortcut: Button
-
-  @BindView(R.id.away_container)
   lateinit var awayContainer: ViewGroup
-
-  @BindView(R.id.away_message)
   lateinit var awayMessage: TextView
-
-  @BindView(R.id.account_container)
   lateinit var accountContainer: ViewGroup
-
-  @BindView(R.id.account)
   lateinit var account: TextView
-
-  @BindView(R.id.ident_container)
   lateinit var identContainer: ViewGroup
-
-  @BindView(R.id.ident)
   lateinit var ident: TextView
-
-  @BindView(R.id.host_container)
   lateinit var hostContainer: ViewGroup
-
-  @BindView(R.id.host)
   lateinit var host: TextView
-
-  @BindView(R.id.server_container)
   lateinit var serverContainer: ViewGroup
-
-  @BindView(R.id.server)
   lateinit var server: TextView
-
-  @BindView(R.id.common_channels)
   lateinit var commonChannels: RecyclerView
 
   @Inject
@@ -154,7 +115,25 @@ class UserInfoFragment : ServiceBoundFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.info_user, container, false)
-    ButterKnife.bind(this, view)
+    this.avatar = view.findViewById(R.id.avatar)
+    this.nick = view.findViewById(R.id.nick)
+    this.realName = view.findViewById(R.id.real_name)
+    this.actionQuery = view.findViewById(R.id.action_query)
+    this.actionIgnore = view.findViewById(R.id.action_ignore)
+    this.actionWhois = view.findViewById(R.id.action_whois)
+    this.actionMention = view.findViewById(R.id.action_mention)
+    this.actionShortcut = view.findViewById(R.id.action_shortcut)
+    this.awayContainer = view.findViewById(R.id.away_container)
+    this.awayMessage = view.findViewById(R.id.away_message)
+    this.accountContainer = view.findViewById(R.id.account_container)
+    this.account = view.findViewById(R.id.account)
+    this.identContainer = view.findViewById(R.id.ident_container)
+    this.ident = view.findViewById(R.id.ident)
+    this.hostContainer = view.findViewById(R.id.host_container)
+    this.host = view.findViewById(R.id.host)
+    this.serverContainer = view.findViewById(R.id.server_container)
+    this.server = view.findViewById(R.id.server)
+    this.commonChannels = view.findViewById(R.id.common_channels)
 
     val openBuffer = arguments?.getBoolean("openBuffer")
 
@@ -173,7 +152,7 @@ class UserInfoFragment : ServiceBoundFragment() {
 
     val colorContext = ColorContext(requireContext(), messageSettings)
 
-    val colorAccent = requireContext().theme.styledAttributes(R.attr.colorAccent) {
+    val colorAccent = requireContext().theme.styledAttributes(androidx.appcompat.R.attr.colorAccent) {
       getColor(0, 0)
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
index 1c62eb25f..80251e675 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
@@ -30,8 +30,6 @@ import androidx.appcompat.widget.ActionMenuView
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.Observer
 import androidx.viewpager.widget.ViewPager
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.floatingactionbutton.FloatingActionButton
 import dagger.android.support.DaggerAppCompatActivity
 import de.kuschku.libquassel.util.Optional
@@ -55,13 +53,8 @@ import javax.inject.Inject
 
 abstract class ServiceBoundSetupActivity :
   DaggerAppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
-  @BindView(R.id.menu_view)
   lateinit var menuView: ActionMenuView
-
-  @BindView(R.id.view_pager)
   lateinit var viewPager: ViewPager
-
-  @BindView(R.id.next_button)
   lateinit var button: FloatingActionButton
 
   private lateinit var adapter: SlidePagerAdapter
@@ -155,7 +148,9 @@ abstract class ServiceBoundSetupActivity :
     packageManager.getActivityInfo(componentName, PackageManager.GET_META_DATA).labelRes
       .nullIf { it == 0 }?.let(this::setTitle)
     setContentView(R.layout.activity_setup)
-    ButterKnife.bind(this)
+    this.menuView = this.findViewById(R.id.menu_view)
+    this.viewPager = this.findViewById(R.id.view_pager)
+    this.button = this.findViewById(R.id.next_button)
 
     descriptionFinish = getString(R.string.label_finish)
     descriptionNext = getString(R.string.label_next)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
index 9c9cbaf08..775011983 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
@@ -27,8 +27,6 @@ import androidx.annotation.DrawableRes
 import androidx.appcompat.widget.ActionMenuView
 import androidx.lifecycle.MutableLiveData
 import androidx.viewpager.widget.ViewPager
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.floatingactionbutton.FloatingActionButton
 import dagger.android.support.DaggerAppCompatActivity
 import de.kuschku.libquassel.util.helper.nullIf
@@ -45,13 +43,8 @@ import de.kuschku.quasseldroid.util.helper.updateRecentsHeader
 import de.kuschku.quasseldroid.util.ui.LocaleHelper
 
 abstract class SetupActivity : DaggerAppCompatActivity() {
-  @BindView(R.id.menu_view)
   lateinit var menuView: ActionMenuView
-
-  @BindView(R.id.view_pager)
   lateinit var viewPager: ViewPager
-
-  @BindView(R.id.next_button)
   lateinit var button: FloatingActionButton
 
   private lateinit var adapter: SlidePagerAdapter
@@ -118,7 +111,9 @@ abstract class SetupActivity : DaggerAppCompatActivity() {
     packageManager.getActivityInfo(componentName, PackageManager.GET_META_DATA).labelRes
       .nullIf { it == 0 }?.let(this::setTitle)
     setContentView(R.layout.activity_setup)
-    ButterKnife.bind(this)
+    this.menuView = this.findViewById(R.id.menu_view)
+    this.viewPager = this.findViewById(R.id.view_pager)
+    this.button = this.findViewById(R.id.next_button)
 
     descriptionFinish = getString(R.string.label_finish)
     descriptionNext = getString(R.string.label_next)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SlideFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SlideFragment.kt
index 93a2bd3e3..29c25e6d2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SlideFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SlideFragment.kt
@@ -42,13 +42,13 @@ abstract class SlideFragment : DaggerFragment() {
 
   private var initialized = false
 
-  val valid = object : MutableLiveData<Boolean>() {
-    override fun observe(owner: LifecycleOwner, observer: Observer<in Boolean>) {
+  val valid = object : MutableLiveData<Boolean?>() {
+    override fun observe(owner: LifecycleOwner, observer: Observer<in Boolean?>) {
       super.observe(owner, observer)
       observer.onChanged(value)
     }
 
-    override fun observeForever(observer: Observer<in Boolean>) {
+    override fun observeForever(observer: Observer<in Boolean?>) {
       super.observeForever(observer)
       observer.onChanged(value)
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt
index 1b35c06b8..a49dcc335 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt
@@ -30,8 +30,6 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
@@ -49,32 +47,21 @@ import de.kuschku.quasseldroid.util.ui.settings.fragment.SettingsFragment
 import javax.inject.Inject
 
 class AccountEditFragment : SettingsFragment(), Changeable, Savable, Deletable {
-  @BindView(R.id.nameWrapper)
   lateinit var nameWrapper: TextInputLayout
-  @BindView(R.id.name)
   lateinit var name: EditText
 
-  @BindView(R.id.hostWrapper)
   lateinit var hostWrapper: TextInputLayout
-  @BindView(R.id.host)
   lateinit var host: EditText
 
-  @BindView(R.id.portWrapper)
   lateinit var portWrapper: TextInputLayout
-  @BindView(R.id.port)
   lateinit var port: EditText
 
-  @BindView(R.id.require_ssl)
   lateinit var requireSsl: SwitchCompat
 
-  @BindView(R.id.userWrapper)
   lateinit var userWrapper: TextInputLayout
-  @BindView(R.id.user)
   lateinit var user: EditText
 
-  @BindView(R.id.passWrapper)
   lateinit var passWrapper: TextInputLayout
-  @BindView(R.id.pass)
   lateinit var pass: EditText
 
   @Inject
@@ -101,7 +88,17 @@ class AccountEditFragment : SettingsFragment(), Changeable, Savable, Deletable {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.setup_account_edit, container, false)
-    ButterKnife.bind(this, view)
+    this.nameWrapper = view.findViewById(R.id.nameWrapper)
+    this.name = view.findViewById(R.id.name)
+    this.hostWrapper = view.findViewById(R.id.hostWrapper)
+    this.host = view.findViewById(R.id.host)
+    this.portWrapper = view.findViewById(R.id.portWrapper)
+    this.port = view.findViewById(R.id.port)
+    this.requireSsl = view.findViewById(R.id.require_ssl)
+    this.userWrapper = view.findViewById(R.id.userWrapper)
+    this.user = view.findViewById(R.id.user)
+    this.passWrapper = view.findViewById(R.id.passWrapper)
+    this.pass = view.findViewById(R.id.pass)
 
     setHasOptionsMenu(true)
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
index 943349079..34734f6b4 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
@@ -29,8 +29,6 @@ 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.BufferId
 import de.kuschku.libquassel.util.compatibility.LoggingHandler
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
@@ -49,7 +47,6 @@ import de.kuschku.quasseldroid.util.helper.zip
 import javax.inject.Inject
 
 class AccountSelectionSlide : SlideFragment() {
-  @BindView(R.id.account_list)
   lateinit var accountList: RecyclerView
 
   @Inject
@@ -76,7 +73,7 @@ class AccountSelectionSlide : SlideFragment() {
                                savedInstanceState: Bundle?): View {
     BufferId
     val view = inflater.inflate(R.layout.setup_select_account, container, false)
-    ButterKnife.bind(this, view)
+    this.accountList = view.findViewById(R.id.account_list)
     val firstObserver = object : Observer<List<Account>?> {
       override fun onChanged(t: List<Account>?) {
         if (t?.isEmpty() != false)
@@ -101,15 +98,15 @@ class AccountSelectionSlide : SlideFragment() {
     adapter.addClickListener {
       accountViewModel.selectedItem.postValue(it)
     }
-    accountViewModel.selectedItem.observeSticky(viewLifecycleOwner, Observer {
+    accountViewModel.selectedItem.observeSticky(viewLifecycleOwner) {
       updateValidity()
-    })
+    }
 
     accountViewModel.accounts.zip(accountViewModel.selectedItem).map { (accounts, selected) ->
       accounts.map { Pair(it, it.id == selected) }
-    }.observe(viewLifecycleOwner, Observer {
+    }.observe(viewLifecycleOwner) {
       adapter.submitList((it ?: emptyList()) + Pair(null, false))
-    })
+    }
 
     return view
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
index c6c03a4c8..a730e2f01 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
@@ -26,8 +26,6 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
@@ -35,19 +33,10 @@ import de.kuschku.quasseldroid.util.Patterns
 import de.kuschku.quasseldroid.util.TextValidator
 
 class AccountSetupConnectionSlide : SlideFragment() {
-  @BindView(R.id.hostWrapper)
   lateinit var hostWrapper: TextInputLayout
-
-  @BindView(R.id.host)
   lateinit var hostField: EditText
-
-  @BindView(R.id.portWrapper)
   lateinit var portWrapper: TextInputLayout
-
-  @BindView(R.id.port)
   lateinit var portField: EditText
-
-  @BindView(R.id.require_ssl)
   lateinit var requireSsl: SwitchCompat
 
   override fun isValid(): Boolean {
@@ -76,7 +65,11 @@ class AccountSetupConnectionSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_account_connection, container, false)
-    ButterKnife.bind(this, view)
+    this.hostWrapper = view.findViewById(R.id.hostWrapper)
+    this.hostField = view.findViewById(R.id.host)
+    this.portWrapper = view.findViewById(R.id.portWrapper)
+    this.portField = view.findViewById(R.id.port)
+    this.requireSsl = view.findViewById(R.id.require_ssl)
     hostValidator = object : TextValidator(
       requireActivity(), hostWrapper::setError, resources.getString(R.string.hint_invalid_host)
     ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
index 645e0a8d7..0bc6d43ae 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
@@ -25,17 +25,13 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 import de.kuschku.quasseldroid.util.TextValidator
 
 class AccountSetupNameSlide : SlideFragment() {
-  @BindView(R.id.nameWrapper)
   lateinit var nameWrapper: TextInputLayout
-  @BindView(R.id.name)
   lateinit var nameField: EditText
 
   override fun isValid(): Boolean {
@@ -58,7 +54,8 @@ class AccountSetupNameSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_account_name, container, false)
-    ButterKnife.bind(this, view)
+    this.nameWrapper = view.findViewById(R.id.nameWrapper)
+    this.nameField = view.findViewById(R.id.name)
     nameValidator = object : TextValidator(
       requireActivity(), nameWrapper::setError, resources.getString(R.string.hint_invalid_name)
     ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
index 84f8595b7..564558b37 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
@@ -25,24 +25,15 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 import de.kuschku.quasseldroid.util.TextValidator
 
 class AccountSetupUserSlide : SlideFragment() {
-  @BindView(R.id.userWrapper)
   lateinit var userWrapper: TextInputLayout
-
-  @BindView(R.id.user)
   lateinit var userField: EditText
-
-  @BindView(R.id.passWrapper)
   lateinit var passWrapper: TextInputLayout
-
-  @BindView(R.id.pass)
   lateinit var passField: EditText
 
   override fun isValid(): Boolean {
@@ -67,7 +58,10 @@ class AccountSetupUserSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_account_user, container, false)
-    ButterKnife.bind(this, view)
+    this.userWrapper = view.findViewById(R.id.userWrapper)
+    this.userField = view.findViewById(R.id.user)
+    this.passWrapper = view.findViewById(R.id.passWrapper)
+    this.passField = view.findViewById(R.id.pass)
     userValidator = object : TextValidator(
       requireActivity(), userWrapper::setError, resources.getString(R.string.hint_invalid_user)
     ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendChooseSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendChooseSlide.kt
index 725149aee..b8ab3f482 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendChooseSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendChooseSlide.kt
@@ -26,15 +26,12 @@ import android.view.ViewGroup
 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.coresetup.CoreSetupBackend
 import de.kuschku.libquassel.protocol.coresetup.CoreSetupData
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 
 abstract class CoreBackendChooseSlide : SlideFragment() {
-  @BindView(R.id.account_list)
   lateinit var backendList: RecyclerView
 
   override fun isValid() = adapter.selection() != null
@@ -60,7 +57,7 @@ abstract class CoreBackendChooseSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_select_account, container, false)
-    ButterKnife.bind(this, view)
+    this.backendList = view.findViewById(R.id.account_list)
 
     backendList.layoutManager = LinearLayoutManager(context)
     backendList.itemAnimator = DefaultItemAnimator()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendSetupSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendSetupSlide.kt
index 13144aa99..06e87c031 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendSetupSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendSetupSlide.kt
@@ -24,18 +24,13 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.QVariant_
 import de.kuschku.libquassel.protocol.coresetup.CoreSetupBackend
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 
 abstract class CoreBackendSetupSlide : SlideFragment() {
-  @BindView(R.id.frame)
   lateinit var frame: LinearLayout
-
-  @BindView(R.id.no_options_info)
   lateinit var noOptionsInfo: View
 
   override fun isValid() = true
@@ -73,7 +68,8 @@ abstract class CoreBackendSetupSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_core_backend_configure, container, false)
-    ButterKnife.bind(this, view)
+    this.frame = view.findViewById(R.id.frame)
+    this.noOptionsInfo = view.findViewById(R.id.no_options_info)
 
     return view
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/QuasselSetupEntry.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/QuasselSetupEntry.kt
index f976bbeef..6cceb6a30 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/QuasselSetupEntry.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/QuasselSetupEntry.kt
@@ -24,8 +24,6 @@ import android.text.InputType
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.widget.FrameLayout
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputEditText
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.libquassel.protocol.QVariant_
@@ -35,10 +33,7 @@ import de.kuschku.libquassel.protocol.value
 import de.kuschku.quasseldroid.R
 
 class QuasselSetupEntry : FrameLayout {
-  @BindView(R.id.wrapper)
   lateinit var wrapper: TextInputLayout
-
-  @BindView(R.id.field)
   lateinit var field: TextInputEditText
 
   private var data: CoreSetupBackendConfigElement? = null
@@ -57,7 +52,8 @@ class QuasselSetupEntry : FrameLayout {
   ) : super(context, attrs, defStyleAttr) {
 
     LayoutInflater.from(context).inflate(R.layout.widget_quassel_setup_entry, this, true)
-    ButterKnife.bind(this)
+    this.wrapper = this.findViewById(R.id.wrapper)
+    this.field = this.findViewById(R.id.field)
 
     if (data != null) {
       this.data = data
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupChannelsSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupChannelsSlide.kt
index c34dfdfd8..198907350 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupChannelsSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupChannelsSlide.kt
@@ -24,17 +24,12 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 
 class NetworkSetupChannelsSlide : SlideFragment() {
-  @BindView(R.id.channelsWrapper)
   lateinit var channelsWrapper: TextInputLayout
-
-  @BindView(R.id.channels)
   lateinit var channelsField: EditText
 
   override fun isValid() = true
@@ -61,7 +56,8 @@ class NetworkSetupChannelsSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_user_channels, container, false)
-    ButterKnife.bind(this, view)
+    this.channelsWrapper = view.findViewById(R.id.channelsWrapper)
+    this.channelsField = view.findViewById(R.id.channels)
     return view
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt
index c64653395..3acb9c93f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt
@@ -29,8 +29,6 @@ import android.widget.EditText
 import android.widget.Spinner
 import androidx.appcompat.widget.SwitchCompat
 import androidx.lifecycle.Observer
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.libquassel.protocol.NetworkId
@@ -54,34 +52,15 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
 import javax.inject.Inject
 
 class NetworkSetupNetworkSlide : ServiceBoundSlideFragment() {
-  @BindView(R.id.identity)
   lateinit var identity: Spinner
-
-  @BindView(R.id.network)
   lateinit var network: Spinner
-
-  @BindView(R.id.network_group)
   lateinit var networkGroup: ViewGroup
-
-  @BindView(R.id.nameWrapper)
   lateinit var nameWrapper: TextInputLayout
-
-  @BindView(R.id.name)
   lateinit var nameField: EditText
-
-  @BindView(R.id.hostWrapper)
   lateinit var hostWrapper: TextInputLayout
-
-  @BindView(R.id.host)
   lateinit var hostField: EditText
-
-  @BindView(R.id.portWrapper)
   lateinit var portWrapper: TextInputLayout
-
-  @BindView(R.id.port)
   lateinit var portField: EditText
-
-  @BindView(R.id.ssl_enabled)
   lateinit var sslEnabled: SwitchCompat
 
   @Inject
@@ -138,7 +117,16 @@ class NetworkSetupNetworkSlide : ServiceBoundSlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_network_network, container, false)
-    ButterKnife.bind(this, view)
+    this.identity = view.findViewById(R.id.identity)
+    this.network = view.findViewById(R.id.network)
+    this.networkGroup = view.findViewById(R.id.network_group)
+    this.nameWrapper = view.findViewById(R.id.nameWrapper)
+    this.nameField = view.findViewById(R.id.name)
+    this.hostWrapper = view.findViewById(R.id.hostWrapper)
+    this.hostField = view.findViewById(R.id.host)
+    this.portWrapper = view.findViewById(R.id.portWrapper)
+    this.portField = view.findViewById(R.id.port)
+    this.sslEnabled = view.findViewById(R.id.ssl_enabled)
     nameValidator = object : TextValidator(
       requireActivity(), nameWrapper::setError, resources.getString(R.string.hint_invalid_name)
     ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupChannelsSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupChannelsSlide.kt
index 5a90d0866..2751f1f3b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupChannelsSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupChannelsSlide.kt
@@ -24,18 +24,13 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.defaults.DefaultNetwork
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
 
 class UserSetupChannelsSlide : SlideFragment() {
-  @BindView(R.id.channelsWrapper)
   lateinit var channelsWrapper: TextInputLayout
-
-  @BindView(R.id.channels)
   lateinit var channelsField: EditText
 
   override fun isValid() = true
@@ -66,7 +61,8 @@ class UserSetupChannelsSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_user_channels, container, false)
-    ButterKnife.bind(this, view)
+    this.channelsWrapper = view.findViewById(R.id.channelsWrapper)
+    this.channelsField = view.findViewById(R.id.channels)
     return view
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupIdentitySlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupIdentitySlide.kt
index e3150505d..de98aa393 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupIdentitySlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupIdentitySlide.kt
@@ -25,8 +25,6 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
@@ -37,16 +35,9 @@ import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer
 import javax.inject.Inject
 
 class UserSetupIdentitySlide : SlideFragment() {
-  @BindView(R.id.nickWrapper)
   lateinit var nickWrapper: TextInputLayout
-
-  @BindView(R.id.nick)
   lateinit var nickField: EditText
-
-  @BindView(R.id.realnameWrapper)
   lateinit var realnameWrapper: TextInputLayout
-
-  @BindView(R.id.realname)
   lateinit var realnameField: EditText
 
   @Inject
@@ -78,7 +69,10 @@ class UserSetupIdentitySlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_user_identity, container, false)
-    ButterKnife.bind(this, view)
+    this.nickWrapper = view.findViewById(R.id.nickWrapper)
+    this.nickField = view.findViewById(R.id.nick)
+    this.realnameWrapper = view.findViewById(R.id.realnameWrapper)
+    this.realnameField = view.findViewById(R.id.realname)
     nickValidator = object : TextValidator(
       requireActivity(), nickWrapper::setError, resources.getString(R.string.hint_invalid_nick)
     ) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt
index 16a7c26fe..7157dfe16 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt
@@ -28,8 +28,6 @@ import android.widget.AdapterView
 import android.widget.EditText
 import android.widget.Spinner
 import androidx.appcompat.widget.SwitchCompat
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.google.android.material.textfield.TextInputLayout
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_PLAINTEXT
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_SSL
@@ -44,31 +42,14 @@ import de.kuschku.quasseldroid.util.ui.AnimationHelper
 import javax.inject.Inject
 
 class UserSetupNetworkSlide : SlideFragment() {
-  @BindView(R.id.network)
   lateinit var network: Spinner
-
-  @BindView(R.id.network_group)
   lateinit var networkGroup: ViewGroup
-
-  @BindView(R.id.nameWrapper)
   lateinit var nameWrapper: TextInputLayout
-
-  @BindView(R.id.name)
   lateinit var nameField: EditText
-
-  @BindView(R.id.hostWrapper)
   lateinit var hostWrapper: TextInputLayout
-
-  @BindView(R.id.host)
   lateinit var hostField: EditText
-
-  @BindView(R.id.portWrapper)
   lateinit var portWrapper: TextInputLayout
-
-  @BindView(R.id.port)
   lateinit var portField: EditText
-
-  @BindView(R.id.ssl_enabled)
   lateinit var sslEnabled: SwitchCompat
 
   @Inject
@@ -124,7 +105,15 @@ class UserSetupNetworkSlide : SlideFragment() {
   override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_user_network, container, false)
-    ButterKnife.bind(this, view)
+    this.network = view.findViewById(R.id.network)
+    this.networkGroup = view.findViewById(R.id.network_group)
+    this.nameWrapper = view.findViewById(R.id.nameWrapper)
+    this.nameField = view.findViewById(R.id.name)
+    this.hostWrapper = view.findViewById(R.id.hostWrapper)
+    this.hostField = view.findViewById(R.id.host)
+    this.portWrapper = view.findViewById(R.id.portWrapper)
+    this.portField = view.findViewById(R.id.port)
+    this.sslEnabled = view.findViewById(R.id.ssl_enabled)
     nameValidator = object : TextValidator(
       requireActivity(), nameWrapper::setError, resources.getString(R.string.hint_invalid_name)
     ) {
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 23748c043..2b7cd9e04 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ColorContext.kt
@@ -53,7 +53,7 @@ class ColorContext @Inject constructor(
     getColor(0, 0)
   }
 
-  val colorAccent = context.theme.styledAttributes(R.attr.colorAccent) {
+  val colorAccent = context.theme.styledAttributes(androidx.appcompat.R.attr.colorAccent) {
     getColor(0, 0)
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt
index e42f9d94b..2751de39d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt
@@ -27,6 +27,7 @@ import android.graphics.drawable.Drawable
 import androidx.core.content.pm.ShortcutInfoCompat
 import androidx.core.content.pm.ShortcutManagerCompat
 import androidx.core.graphics.drawable.IconCompat
+import com.bumptech.glide.Glide
 import com.bumptech.glide.request.target.CustomTarget
 import com.bumptech.glide.request.transition.Transition
 import de.kuschku.libquassel.protocol.Buffer_Type
@@ -34,7 +35,6 @@ import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.quassel.syncables.IrcUser
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.irc.SenderColorUtil
-import de.kuschku.quasseldroid.GlideApp
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.util.AccountId
 import de.kuschku.quasseldroid.settings.MessageSettings
@@ -112,7 +112,7 @@ object ShortcutCreationHelper {
       if (urls == null || urls.isEmpty()) {
         resultAvailable(fallback)
       } else {
-        GlideApp.with(context)
+        Glide.with(context)
           .loadWithFallbacks(urls)
           ?.placeholder(fallback)
           ?.into(object : CustomTarget<Drawable>(bitmapSize, bitmapSize) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt b/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt
index beed44af5..f56fd0910 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/deceptive_networks/DeceptiveNetworkDialog.kt
@@ -29,8 +29,6 @@ import androidx.annotation.StringRes
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.FragmentActivity
 import androidx.fragment.app.FragmentManager
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.BetterLinkMovementMethod
@@ -38,7 +36,6 @@ import de.kuschku.quasseldroid.util.ui.BetterLinkMovementMethod
 class DeceptiveNetworkDialog : DialogFragment() {
   private var builder: Builder? = null
 
-  @BindView(R.id.message)
   lateinit var message: TextView
 
   @SuppressLint("StringFormatInvalid")
@@ -48,7 +45,7 @@ class DeceptiveNetworkDialog : DialogFragment() {
       .title(R.string.deceptive_network)
       .negativeText(R.string.label_close)
       .build()
-    ButterKnife.bind(this, dialog.customView!!)
+    this.message = dialog.customView!!.findViewById(R.id.message)
     builder?.message?.let {
       message.text = Html.fromHtml(getString(it))
       message.movementMethod = BetterLinkMovementMethod.newInstance()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/GlideHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/GlideHelper.kt
index 103db6499..b1d136837 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/GlideHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/GlideHelper.kt
@@ -21,20 +21,19 @@ package de.kuschku.quasseldroid.util.helper
 
 import android.graphics.drawable.Drawable
 import android.widget.ImageView
+import com.bumptech.glide.Glide
 import com.bumptech.glide.RequestBuilder
+import com.bumptech.glide.RequestManager
 import com.bumptech.glide.load.DataSource
 import com.bumptech.glide.load.engine.GlideException
 import com.bumptech.glide.load.resource.bitmap.RoundedCorners
 import com.bumptech.glide.request.RequestListener
 import com.bumptech.glide.request.target.Target
-import de.kuschku.quasseldroid.GlideApp
-import de.kuschku.quasseldroid.GlideRequest
-import de.kuschku.quasseldroid.GlideRequests
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.viewmodel.data.Avatar
 
-fun GlideRequests.loadWithFallbacks(urls: List<Avatar>): GlideRequest<Drawable>? {
-  fun fold(url: Avatar, fallback: RequestBuilder<Drawable>?): GlideRequest<Drawable> {
+fun RequestManager.loadWithFallbacks(urls: List<Avatar>): RequestBuilder<Drawable>? {
+  fun fold(url: Avatar, fallback: RequestBuilder<Drawable>?): RequestBuilder<Drawable> {
     return when (url) {
       is Avatar.NativeAvatar   -> load(url.url)
       is Avatar.GravatarAvatar -> load(url.url)
@@ -51,7 +50,7 @@ fun GlideRequests.loadWithFallbacks(urls: List<Avatar>): GlideRequest<Drawable>?
 fun ImageView.loadAvatars(urls: List<Avatar>, fallback: Drawable? = null, crop: Boolean = true,
                           listener: ((Any?) -> Unit)? = null) {
   if (urls.isNotEmpty()) {
-    GlideApp.with(this)
+    Glide.with(this)
       .loadWithFallbacks(urls)
       ?.let {
         if (crop) {
@@ -63,20 +62,28 @@ fun ImageView.loadAvatars(urls: List<Avatar>, fallback: Drawable? = null, crop:
       ?.placeholder(fallback)
       ?.letIf(listener != null) {
         it.addListener(object : RequestListener<Drawable> {
-          override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?,
-                                    isFirstResource: Boolean) = false
+          override fun onLoadFailed(
+            e: GlideException?,
+            model: Any?,
+            target: Target<Drawable>,
+            isFirstResource: Boolean
+          ): Boolean = false
 
-          override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?,
-                                       dataSource: DataSource?, isFirstResource: Boolean): Boolean {
+          override fun onResourceReady(
+            resource: Drawable,
+            model: Any,
+            target: Target<Drawable>?,
+            dataSource: DataSource,
+            isFirstResource: Boolean
+          ): Boolean {
             listener?.invoke(model)
-
             return false
           }
         })
       }
       ?.into(this)
   } else {
-    GlideApp.with(this).clear(this)
+    Glide.with(this).clear(this)
     setImageDrawable(fallback)
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/MenuHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/MenuHelper.kt
index dd7b13a19..f162e040d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/MenuHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/MenuHelper.kt
@@ -25,7 +25,7 @@ import androidx.core.graphics.drawable.DrawableCompat
 import de.kuschku.quasseldroid.R
 
 fun Menu.retint(context: Context) {
-  context.theme.styledAttributes(R.attr.colorControlNormal) {
+  context.theme.styledAttributes(androidx.appcompat.R.attr.colorControlNormal) {
     val color = getColor(0, 0)
 
     for (item in (0 until size()).map { getItem(it) }) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/lists/AsyncListDiffer.kt b/app/src/main/java/de/kuschku/quasseldroid/util/lists/AsyncListDiffer.kt
index 0bd12a412..75f74691a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/lists/AsyncListDiffer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/lists/AsyncListDiffer.kt
@@ -113,7 +113,7 @@ import java.util.*
  *
  * @see AdapterListUpdateCallback
 </T> */
-class AsyncListDiffer<T> {
+class AsyncListDiffer<T : Any> {
   private val mUpdateCallback: ListUpdateCallback
   private val mUpdateFinishedCallback: ((List<T>) -> Unit)?
   private val mConfig: AsyncDifferConfig<T>
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/lists/ListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/util/lists/ListAdapter.kt
index 352edd0aa..0cdc209be 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/lists/ListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/lists/ListAdapter.kt
@@ -93,7 +93,7 @@ import androidx.recyclerview.widget.RecyclerView
  * @param <T> Type of the Lists this Adapter will receive.
  * @param <VH> A class that extends ViewHolder that will be used by the adapter.
 </VH></T> */
-abstract class ListAdapter<T, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH> {
+abstract class ListAdapter<T : Any, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH> {
   private val mHelper: AsyncListDiffer<T>
 
   protected constructor(diffCallback: DiffUtil.ItemCallback<T>) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesDialog.kt b/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesDialog.kt
index 4bd302c9b..ab797bb22 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesDialog.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesDialog.kt
@@ -30,8 +30,6 @@ import androidx.fragment.app.FragmentActivity
 import androidx.fragment.app.FragmentManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.BetterLinkMovementMethod
@@ -39,10 +37,7 @@ import de.kuschku.quasseldroid.util.ui.BetterLinkMovementMethod
 class MissingFeaturesDialog : DialogFragment() {
   private var builder: Builder? = null
 
-  @BindView(R.id.list)
   lateinit var list: RecyclerView
-
-  @BindView(R.id.message)
   lateinit var message: TextView
 
   @SuppressLint("StringFormatInvalid")
@@ -56,7 +51,8 @@ class MissingFeaturesDialog : DialogFragment() {
         builder?.positiveListener?.let(it::onPositive)
       }
       .build()
-    ButterKnife.bind(this, dialog.customView!!)
+    this.list = dialog.customView!!.findViewById(R.id.list)
+    this.message = dialog.customView!!.findViewById(R.id.message)
     val version = builder?.missingFeatures?.maxByOrNull(MissingFeature::minimumVersion)?.minimumVersion
                   ?: QuasselVersion.VERSION_0_13
     message.text = Html.fromHtml(getString(R.string.info_missing_features, version.humanName))
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ColorChooserDialog.java b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ColorChooserDialog.java
index a36c8b784..b51f3ec05 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ColorChooserDialog.java
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ColorChooserDialog.java
@@ -604,15 +604,15 @@ public class ColorChooserDialog extends DialogFragment
     @ColorInt
     int preselectColor;
     @StringRes
-    int doneBtn = R.string.md_done_label;
+    int doneBtn = R.string.label_done;
     @StringRes
-    int backBtn = R.string.md_back_label;
+    int backBtn = R.string.label_back;
     @StringRes
-    int cancelBtn = R.string.md_cancel_label;
+    int cancelBtn = R.string.label_cancel;
     @StringRes
-    int customBtn = R.string.md_custom_label;
+    int customBtn = R.string.label_colors_custom;
     @StringRes
-    int presetsBtn = R.string.md_presets_label;
+    int presetsBtn = R.string.label_colors_presets;
     @Nullable
     int[] colorsTop;
     @Nullable
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ContextThemeWrapper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ContextThemeWrapper.kt
index 98713df9d..7636a328b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ContextThemeWrapper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ContextThemeWrapper.kt
@@ -138,7 +138,7 @@ open class ContextThemeWrapper : ContextWrapper {
     }
 
     if (themeResId == 0) {
-      themeResId = R.style.Theme_AppCompat_Light
+      themeResId = androidx.appcompat.R.style.Theme_AppCompat_Light
     }
     initializeTheme()
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/DoubleClickHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/DoubleClickHelper.kt
index d4ffe4a93..09389d020 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/DoubleClickHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/DoubleClickHelper.kt
@@ -30,17 +30,17 @@ class DoubleClickHelper(view: View) : View.OnTouchListener {
   private val gestureDetector = GestureDetector(
     view.context,
     object : GestureDetector.SimpleOnGestureListener() {
-      override fun onDoubleTap(e: MotionEvent?): Boolean {
+      override fun onDoubleTap(e: MotionEvent): Boolean {
         doubleClickListener?.invoke()
         return true
       }
 
-      override fun onDoubleTapEvent(e: MotionEvent?): Boolean {
+      override fun onDoubleTapEvent(e: MotionEvent): Boolean {
         return true
       }
     }
   )
 
   @SuppressLint("ClickableViewAccessibility")
-  override fun onTouch(v: View?, event: MotionEvent?) = gestureDetector.onTouchEvent(event)
+  override fun onTouch(v: View?, event: MotionEvent) = gestureDetector.onTouchEvent(event)
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/FixedNestingScrollView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/FixedNestingScrollView.kt
index acd5bc1f8..37ac35e2e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/FixedNestingScrollView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/FixedNestingScrollView.kt
@@ -34,7 +34,7 @@ class FixedNestingScrollView : NestedScrollView {
   constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
     super(context, attrs, defStyleAttr)
 
-  override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+  override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
     if (!canScrollVertically(-1))
       return false
     return super.onInterceptTouchEvent(ev)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
index 814d2d160..1866421ee 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/drawable/DrawerToggleActivityDrawable.kt
@@ -39,7 +39,7 @@ class DrawerToggleActivityDrawable(context: Context, @ColorRes colorAttribute: I
   }
 
   private val togglePaint = Paint().apply {
-    color = context.theme.styledAttributes(R.attr.colorControlNormal) {
+    color = context.theme.styledAttributes(androidx.appcompat.R.attr.colorControlNormal) {
       getColor(0, 0)
     }
     style = Paint.Style.STROKE
@@ -100,7 +100,7 @@ class DrawerToggleActivityDrawable(context: Context, @ColorRes colorAttribute: I
     transformedTogglePath.transform(transformationMatrix)
   }
 
-  override fun onBoundsChange(bounds: Rect?) {
+  override fun onBoundsChange(bounds: Rect) {
     transformPaths()
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
index ad58e9b7d..93ae32691 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
@@ -24,8 +24,6 @@ import android.widget.TextView
 import androidx.appcompat.widget.AppCompatSeekBar
 import androidx.preference.Preference
 import androidx.preference.PreferenceViewHolder
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 
 class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener {
@@ -37,19 +35,12 @@ class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener {
   private var unitsLeftText = ""
   private var unitsRightText = ""
 
-  @BindView(R.id.seekBarPrefSeekBar)
   @JvmField
   var seekBar: AppCompatSeekBar? = null
-
-  @BindView(R.id.seekBarPrefValue)
   @JvmField
   var statusText: TextView? = null
-
-  @BindView(R.id.seekBarPrefUnitsLeft)
   @JvmField
   var unitsLeft: TextView? = null
-
-  @BindView(R.id.seekBarPrefUnitsRight)
   @JvmField
   var unitsRight: TextView? = null
 
@@ -94,7 +85,10 @@ class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener {
   override fun onBindViewHolder(holder: PreferenceViewHolder) {
     super.onBindViewHolder(holder)
     holder.itemView.let { view ->
-      ButterKnife.bind(this, view)
+      this.seekBar = view.findViewById(R.id.seekBarPrefSeekBar)
+      this.statusText = view.findViewById(R.id.seekBarPrefValue)
+      this.unitsLeft = view.findViewById(R.id.seekBarPrefUnitsLeft)
+      this.unitsRight = view.findViewById(R.id.seekBarPrefUnitsRight)
       seekBar?.max = maxValue - minValue
       seekBar?.setOnSeekBarChangeListener(this)
       statusText?.text = currentValue.toString()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
index 22a053124..8206d6e00 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/ServiceBoundSettingsActivity.kt
@@ -23,8 +23,6 @@ import android.os.Bundle
 import android.view.MenuItem
 import androidx.appcompat.widget.Toolbar
 import androidx.fragment.app.Fragment
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
@@ -37,14 +35,13 @@ abstract class ServiceBoundSettingsActivity(private val fragment: Fragment? = nu
   private var changeable: Changeable? = null
   protected var actualFragment: Fragment? = null
 
-  @BindView(R.id.toolbar)
   lateinit var toolbar: Toolbar
 
   override fun onCreate(savedInstanceState: Bundle?) {
     val arguments = intent.extras
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_settings)
-    ButterKnife.bind(this)
+    this.toolbar = this.findViewById(R.id.toolbar)
 
     setSupportActionBar(toolbar)
     supportActionBar?.setDisplayHomeAsUpEnabled(true)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
index 8475ba15a..fdf19c893 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SettingsActivity.kt
@@ -23,8 +23,6 @@ import android.os.Bundle
 import android.view.MenuItem
 import androidx.appcompat.widget.Toolbar
 import androidx.fragment.app.Fragment
-import butterknife.BindView
-import butterknife.ButterKnife
 import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.ui.ThemedActivity
@@ -36,14 +34,13 @@ abstract class SettingsActivity(protected val fragment: Fragment? = null) : Them
   private var changeable: Changeable? = null
   protected var actualFragment: Fragment? = null
 
-  @BindView(R.id.toolbar)
   lateinit var toolbar: Toolbar
 
   override fun onCreate(savedInstanceState: Bundle?) {
     val arguments = intent.extras
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_settings)
-    ButterKnife.bind(this)
+    this.toolbar = this.findViewById(R.id.toolbar)
 
     setSupportActionBar(toolbar)
     supportActionBar?.setDisplayHomeAsUpEnabled(true)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
index 8bb879911..30a74157c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/BannerView.kt
@@ -27,20 +27,13 @@ import android.widget.FrameLayout
 import android.widget.TextView
 import androidx.annotation.StringRes
 import androidx.appcompat.widget.AppCompatImageView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.styledAttributes
 import de.kuschku.quasseldroid.util.helper.use
 
 class BannerView : FrameLayout {
-  @BindView(R.id.icon)
   lateinit var icon: AppCompatImageView
-
-  @BindView(R.id.text)
   lateinit var text: TextView
-
-  @BindView(R.id.button)
   lateinit var button: TextView
 
   constructor(context: Context) :
@@ -53,10 +46,12 @@ class BannerView : FrameLayout {
     super(context, attrs, defStyleAttr) {
 
     val content = LayoutInflater.from(context).inflate(R.layout.widget_banner, this, true)
-    ButterKnife.bind(this)
+    this.icon = this.findViewById(R.id.icon)
+    this.text = this.findViewById(R.id.text)
+    this.button = this.findViewById(R.id.button)
 
     context.theme.styledAttributes(R.attr.colorBackgroundSnackbar,
-                                   R.attr.selectableItemBackground) {
+                                   androidx.appcompat.R.attr.selectableItemBackground) {
       content.background = LayerDrawable(arrayOf(
         getDrawable(0),
         getDrawable(1)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/InlineSnackBar.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/InlineSnackBar.kt
index d2dbc3151..c6d2a30b3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/InlineSnackBar.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/InlineSnackBar.kt
@@ -27,16 +27,11 @@ import android.widget.Button
 import android.widget.FrameLayout
 import android.widget.TextView
 import androidx.annotation.StringRes
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.use
 
 class InlineSnackBar : FrameLayout {
-  @BindView(R.id.text)
   lateinit var text: TextView
-
-  @BindView(R.id.button)
   lateinit var button: Button
 
   constructor(context: Context) :
@@ -49,7 +44,8 @@ class InlineSnackBar : FrameLayout {
     super(context, attrs, defStyleAttr) {
 
     LayoutInflater.from(context).inflate(R.layout.widget_inline_snackbar, this, true)
-    ButterKnife.bind(this)
+    this.text = this.findViewById(R.id.text)
+    this.button = this.findViewById(R.id.button)
 
     context.theme.obtainStyledAttributes(attrs, R.styleable.InlineSnackBar, 0, 0).use {
       if (it.hasValue(R.styleable.InlineSnackBar_text))
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
index 87ef92614..ec88ec2a9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/view/WarningBarView.kt
@@ -29,19 +29,12 @@ import android.widget.TextView
 import androidx.annotation.IntDef
 import androidx.annotation.StringRes
 import androidx.appcompat.widget.AppCompatImageView
-import butterknife.BindView
-import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.use
 
 class WarningBarView : FrameLayout {
-  @BindView(R.id.icon)
   lateinit var icon: AppCompatImageView
-
-  @BindView(R.id.progress)
   lateinit var progress: View
-
-  @BindView(R.id.text)
   lateinit var text: TextView
 
   constructor(context: Context) :
@@ -54,7 +47,9 @@ class WarningBarView : FrameLayout {
     super(context, attrs, defStyleAttr) {
 
     LayoutInflater.from(context).inflate(R.layout.widget_warning_bar, this, true)
-    ButterKnife.bind(this)
+    this.icon = this.findViewById(R.id.icon)
+    this.progress = this.findViewById(R.id.progress)
+    this.text = this.findViewById(R.id.text)
 
     context.theme.obtainStyledAttributes(attrs, R.styleable.WarningBarView, 0, 0).use {
       if (it.hasValue(R.styleable.WarningBarView_icon))
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d826045e4..99a7396e0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -48,6 +48,7 @@
   <string name="label_close">Close</string>
   <string name="label_colors_custom">Custom</string>
   <string name="label_colors_mirc">mIRC</string>
+  <string name="label_colors_presets">Presets</string>
   <string name="label_configure">Configure</string>
   <string name="label_connect">Connect</string>
   <string name="label_copy">Copy</string>
@@ -58,6 +59,7 @@
   <string name="label_delete_all">Delete All</string>
   <string name="label_descending">Descending</string>
   <string name="label_disconnect">Disconnect</string>
+  <string name="label_done">Done</string>
   <string name="label_edit_core">Edit Account</string>
   <string name="label_edit_nick">Edit Nickname</string>
   <string name="label_edit_topic">Edit Topic</string>
diff --git a/app/src/main/res/values/themes_daynight.xml b/app/src/main/res/values/themes_daynight.xml
deleted file mode 100644
index 0f7241f7a..000000000
--- a/app/src/main/res/values/themes_daynight.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Quasseldroid - Quassel client for Android
-
-  Copyright (c) 2020 Janne Mareike Koschinski
-  Copyright (c) 2020 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/>.
-  -->
-
-<resources>
-
-  <style name="Theme.ChatTheme.Material_DayNight" parent="Theme.ChatTheme.Material_Light" />
-
-  <style name="Theme.ChatTheme.Quassel_DayNight" parent="Theme.ChatTheme.Quassel_Light" />
-
-  <style name="Theme.ChatTheme.Solarized_DayNight" parent="Theme.ChatTheme.Solarized_Light" />
-
-  <style name="Theme.ChatTheme.Gruvbox_DayNight" parent="Theme.ChatTheme.Gruvbox_Light" />
-</resources>
diff --git a/build.gradle.kts b/build.gradle.kts
index a1699feb9..246daff18 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -18,3 +18,17 @@
  */
 
 group = "com.iskrembilen"
+
+buildscript {
+  repositories {
+    google()
+    mavenCentral()
+  }
+}
+
+plugins {
+  alias(libs.plugins.android.application) apply false
+  alias(libs.plugins.kotlin.jvm) apply false
+  alias(libs.plugins.kotlin.kapt) apply false
+  alias(libs.plugins.ksp) apply false
+}
diff --git a/gradle/convention/build.gradle.kts b/gradle/convention/build.gradle.kts
index 1d775337d..8b4b26985 100644
--- a/gradle/convention/build.gradle.kts
+++ b/gradle/convention/build.gradle.kts
@@ -9,13 +9,34 @@ repositories {
 }
 
 dependencies {
-  implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
-  implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:1.6.10-1.0.4")
-  implementation("com.android.tools.build:gradle:7.1.1")
+  compileOnly(libs.android.gradlePlugin)
+  compileOnly(libs.kotlin.gradlePlugin)
+  compileOnly(libs.ksp.gradlePlugin)
+}
+
+gradlePlugin {
+  plugins {
+    register("androidApplication") {
+      id = "justjanne.android.app"
+      implementationClass = "AndroidApplicationConvention"
+    }
+    register("androidLibrary") {
+      id = "justjanne.android.library"
+      implementationClass = "AndroidLibraryConvention"
+    }
+    register("kotlinAndroid") {
+      id = "justjanne.kotlin.android"
+      implementationClass = "KotlinAndroidConvention"
+    }
+    register("kotlin") {
+      id = "justjanne.kotlin"
+      implementationClass = "KotlinConvention"
+    }
+  }
 }
 
 configure<JavaPluginExtension> {
   toolchain {
-    languageVersion.set(JavaLanguageVersion.of(8))
+    languageVersion.set(JavaLanguageVersion.of(11))
   }
 }
diff --git a/gradle/convention/gradle/wrapper/gradle-wrapper.properties b/gradle/convention/gradle/wrapper/gradle-wrapper.properties
index a28e12c60..f3d05d947 100644
--- a/gradle/convention/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/convention/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
-distributionSha256Szm=e6d864e3b5bc05cc62041842b306383fc1fefcec359e70cebb1d470a6094ca82
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
+distributionSha256Szm=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradle/convention/settings.gradle.kts b/gradle/convention/settings.gradle.kts
index 6ef6296c7..5bdbcb21e 100644
--- a/gradle/convention/settings.gradle.kts
+++ b/gradle/convention/settings.gradle.kts
@@ -1 +1,15 @@
+@file:Suppress("UnstableApiUsage")
+
 rootProject.name = "convention"
+
+dependencyResolutionManagement {
+  repositories {
+    google()
+    mavenCentral()
+  }
+  versionCatalogs {
+    create("libs") {
+      from(files("../libs.versions.toml"))
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt b/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt
new file mode 100644
index 000000000..35de208b5
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt
@@ -0,0 +1,79 @@
+import com.android.build.api.dsl.ApplicationExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import util.git
+import util.properties
+import java.util.Locale
+
+class AndroidApplicationConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("com.android.application")
+        apply("justjanne.kotlin.android")
+      }
+
+      extensions.configure<ApplicationExtension> {
+        compileSdk = 34
+
+        defaultConfig {
+          minSdk = 21
+          targetSdk = 34
+
+          applicationId = "${rootProject.group}.${rootProject.name.lowercase(Locale.ROOT)}"
+
+          val commit = git("rev-parse", "HEAD")
+          val name = git("describe", "--always", "--tags", "HEAD")
+
+          versionCode = git("rev-list", "--count", "HEAD")?.toIntOrNull() ?: 1
+          versionName = git("describe", "--always", "--tags", "HEAD") ?: "1.0.0"
+
+          val fancyVersionName = if (commit == null || name == null) name
+          else "<a href=\\\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/$commit\\\">$name</a>"
+
+          buildConfigField("String", "GIT_HEAD", "\"${git("rev-parse", "HEAD") ?: ""}\"")
+          buildConfigField("String", "FANCY_VERSION_NAME", "\"${fancyVersionName ?: ""}\"")
+          buildConfigField("long", "GIT_COMMIT_DATE", "${git("show", "-s", "--format=%ct") ?: 0}L")
+
+          signingConfig = signingConfigs.findByName("default")
+
+          setProperty("archivesBaseName", "${rootProject.name}-$versionName")
+
+          // Disable test runner analytics
+          testInstrumentationRunnerArguments["disableAnalytics"] = "true"
+        }
+
+        buildFeatures {
+          buildConfig = true
+        }
+
+        signingConfigs {
+          SigningData.of(project.rootProject.properties("signing.properties"))?.let {
+            create("default") {
+              storeFile = file(it.storeFile)
+              storePassword = it.storePassword
+              keyAlias = it.keyAlias
+              keyPassword = it.keyPassword
+            }
+          }
+        }
+
+        compileOptions {
+          sourceCompatibility = JavaVersion.VERSION_11
+          targetCompatibility = JavaVersion.VERSION_11
+        }
+
+        testOptions {
+          unitTests.isIncludeAndroidResources = true
+        }
+
+        lint {
+          warningsAsErrors = true
+          lintConfig = file("../lint.xml")
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt b/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt
new file mode 100644
index 000000000..c048de784
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt
@@ -0,0 +1,34 @@
+import com.android.build.api.dsl.LibraryExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import java.util.*
+
+class AndroidLibraryConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("com.android.library")
+        apply("justjanne.kotlin.android")
+      }
+
+      extensions.configure<LibraryExtension> {
+        compileSdk = 34
+
+        defaultConfig {
+          minSdk = 21
+
+          consumerProguardFiles("proguard-rules.pro")
+
+          // Disable test runner analytics
+          testInstrumentationRunnerArguments["disableAnalytics"] = "true"
+        }
+
+        lint {
+          warningsAsErrors = true
+          lintConfig = file("../lint.xml")
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt b/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt
new file mode 100644
index 000000000..bb1e14e75
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt
@@ -0,0 +1,52 @@
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.provideDelegate
+import org.gradle.kotlin.dsl.withType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+class KotlinAndroidConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("org.jetbrains.kotlin.android")
+        apply("org.jetbrains.kotlin.kapt")
+        apply("com.google.devtools.ksp")
+      }
+
+      // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947
+      tasks.withType<KotlinCompile>().configureEach {
+        kotlinOptions {
+          // Set JVM target to 11
+          jvmTarget = JavaVersion.VERSION_11.toString()
+          // Treat all Kotlin warnings as errors (disabled by default)
+          // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
+          val warningsAsErrors: String? by target
+          allWarningsAsErrors = warningsAsErrors.toBoolean()
+          freeCompilerArgs = freeCompilerArgs + listOf(
+            "-opt-in=kotlin.ExperimentalUnsignedTypes"
+          )
+        }
+      }
+
+      tasks.withType<Test> {
+        useJUnitPlatform()
+      }
+
+      configure<JavaPluginExtension> {
+        // Up to Java 11 APIs are available through desugaring
+        // https://developer.android.com/studio/write/java11-minimal-support-table
+        sourceCompatibility = JavaVersion.VERSION_11
+        targetCompatibility = JavaVersion.VERSION_11
+
+        toolchain {
+          languageVersion.set(JavaLanguageVersion.of(11))
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/KotlinConvention.kt b/gradle/convention/src/main/kotlin/KotlinConvention.kt
new file mode 100644
index 000000000..291284f46
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/KotlinConvention.kt
@@ -0,0 +1,55 @@
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.kotlin
+import org.gradle.kotlin.dsl.provideDelegate
+import org.gradle.kotlin.dsl.withType
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+class KotlinConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("org.jetbrains.kotlin.jvm")
+        apply("org.jetbrains.kotlin.kapt")
+        apply("com.google.devtools.ksp")
+      }
+
+      // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947
+      tasks.withType<KotlinCompile>().configureEach {
+        kotlinOptions {
+          // Set JVM target to 11
+          jvmTarget = JavaVersion.VERSION_11.toString()
+          // Treat all Kotlin warnings as errors (disabled by default)
+          // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
+          val warningsAsErrors: String? by target
+          allWarningsAsErrors = warningsAsErrors.toBoolean()
+          freeCompilerArgs = freeCompilerArgs + listOf(
+            "-opt-in=kotlin.ExperimentalUnsignedTypes"
+          )
+        }
+      }
+
+      tasks.withType<Test> {
+        useJUnitPlatform()
+      }
+
+      configure<JavaPluginExtension> {
+        // Up to Java 11 APIs are available through desugaring
+        // https://developer.android.com/studio/write/java11-minimal-support-table
+        sourceCompatibility = JavaVersion.VERSION_11
+        targetCompatibility = JavaVersion.VERSION_11
+
+        toolchain {
+          languageVersion.set(JavaLanguageVersion.of(11))
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/justjanne.android.signing.gradle.kts b/gradle/convention/src/main/kotlin/SigningData.kt
similarity index 51%
rename from gradle/convention/src/main/kotlin/justjanne.android.signing.gradle.kts
rename to gradle/convention/src/main/kotlin/SigningData.kt
index deb2731f9..606738eec 100644
--- a/gradle/convention/src/main/kotlin/justjanne.android.signing.gradle.kts
+++ b/gradle/convention/src/main/kotlin/SigningData.kt
@@ -1,35 +1,5 @@
 import java.util.*
 
-plugins {
-  id("com.android.application")
-}
-
-android {
-  signingConfigs {
-    SigningData.of(project.rootProject.properties("signing.properties"))?.let {
-      create("default") {
-        storeFile = file(it.storeFile)
-        storePassword = it.storePassword
-        keyAlias = it.keyAlias
-        keyPassword = it.keyPassword
-      }
-    }
-  }
-
-  defaultConfig {
-    signingConfig = signingConfigs.findByName("default")
-  }
-}
-
-fun Project.properties(fileName: String): Properties? {
-  val file = file(fileName)
-  if (!file.exists())
-    return null
-  val props = Properties()
-  props.load(file.inputStream())
-  return props
-}
-
 data class SigningData(
   val storeFile: String,
   val storePassword: String,
diff --git a/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
deleted file mode 100644
index d165903d3..000000000
--- a/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
+++ /dev/null
@@ -1,94 +0,0 @@
-import java.io.ByteArrayOutputStream
-import java.util.*
-
-plugins {
-  id("com.android.application")
-  id("justjanne.kotlin.android")
-}
-
-android {
-  compileSdk = 32
-
-  defaultConfig {
-    minSdk = 21
-    targetSdk = 32
-
-    applicationId = "${rootProject.group}.${rootProject.name.toLowerCase(Locale.ROOT)}"
-    versionCode = cmd("git", "rev-list", "--count", "HEAD")?.toIntOrNull() ?: 1
-    versionName = cmd("git", "describe", "--always", "--tags", "HEAD") ?: "1.0.0"
-
-    buildConfigField("String", "GIT_HEAD", "\"${cmd("git", "rev-parse", "HEAD") ?: ""}\"")
-    buildConfigField("String", "FANCY_VERSION_NAME", "\"${fancyVersionName() ?: ""}\"")
-    buildConfigField("long", "GIT_COMMIT_DATE", "${cmd("git", "show", "-s", "--format=%ct") ?: 0}L")
-
-    signingConfig = signingConfigs.findByName("default")
-
-    setProperty("archivesBaseName", "${rootProject.name}-$versionName")
-
-    // Disable test runner analytics
-    testInstrumentationRunnerArguments["disableAnalytics"] = "true"
-  }
-
-  compileOptions {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
-  }
-
-  testOptions {
-    unitTests.isIncludeAndroidResources = true
-  }
-
-  lint {
-    warningsAsErrors = true
-    lintConfig = file("../lint.xml")
-  }
-}
-
-fun Project.fancyVersionName(): String? {
-  val commit = cmd("git", "rev-parse", "HEAD")
-  val name = cmd("git", "describe", "--always", "--tags", "HEAD")
-
-  return if (commit != null && name != null) "<a href=\\\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/$commit\\\">$name</a>"
-  else name
-}
-
-fun Project.cmd(vararg command: String) = try {
-  val stdOut = ByteArrayOutputStream()
-  exec {
-    commandLine(*command)
-    standardOutput = stdOut
-  }
-  stdOut.toString(Charsets.UTF_8.name()).trim()
-} catch (e: Throwable) {
-  e.printStackTrace()
-  null
-}
-
-fun Project.properties(fileName: String): Properties? {
-  val file = file(fileName)
-  if (!file.exists())
-    return null
-  val props = Properties()
-  props.load(file.inputStream())
-  return props
-}
-
-data class SigningData(
-  val storeFile: String,
-  val storePassword: String,
-  val keyAlias: String,
-  val keyPassword: String
-) {
-  companion object {
-    fun of(properties: Properties?): SigningData? {
-      if (properties == null) return null
-
-      val storeFile = properties.getProperty("storeFile") ?: return null
-      val storePassword = properties.getProperty("storePassword") ?: return null
-      val keyAlias = properties.getProperty("keyAlias") ?: return null
-      val keyPassword = properties.getProperty("keyPassword") ?: return null
-
-      return SigningData(storeFile, storePassword, keyAlias, keyPassword)
-    }
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
deleted file mode 100644
index 4a7f21050..000000000
--- a/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
+++ /dev/null
@@ -1,23 +0,0 @@
-plugins {
-  id("com.android.library")
-  id("justjanne.kotlin.android")
-}
-
-android {
-  compileSdk = 32
-
-  defaultConfig {
-    minSdk = 21
-    targetSdk = 32
-
-    consumerProguardFiles("proguard-rules.pro")
-
-    // Disable test runner analytics
-    testInstrumentationRunnerArguments["disableAnalytics"] = "true"
-  }
-
-  lint {
-    warningsAsErrors = true
-    lintConfig = file("../lint.xml")
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts
deleted file mode 100644
index ca33bb8d7..000000000
--- a/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts
+++ /dev/null
@@ -1,10 +0,0 @@
-plugins {
-  java
-  id("justjanne.repositories")
-}
-
-configure<JavaPluginExtension> {
-  toolchain {
-    languageVersion.set(JavaLanguageVersion.of(8))
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.kotlin.android.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.kotlin.android.gradle.kts
deleted file mode 100644
index 085a706c2..000000000
--- a/gradle/convention/src/main/kotlin/justjanne.kotlin.android.gradle.kts
+++ /dev/null
@@ -1,22 +0,0 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-plugins {
-  id("justjanne.repositories")
-  id("com.google.devtools.ksp")
-  kotlin("android")
-  kotlin("kapt")
-}
-
-dependencies {
-  "implementation"("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
-}
-
-tasks.withType<KotlinCompile> {
-  kotlinOptions {
-    freeCompilerArgs = listOf(
-      "-Xinline-classes",
-      "-Xopt-in=kotlin.ExperimentalUnsignedTypes"
-    )
-    jvmTarget = "1.8"
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts
deleted file mode 100644
index 2b18204e0..000000000
--- a/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts
+++ /dev/null
@@ -1,23 +0,0 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-plugins {
-  id("justjanne.java")
-  id("justjanne.repositories")
-  id("com.google.devtools.ksp")
-  kotlin("jvm")
-  kotlin("kapt")
-}
-
-dependencies {
-  implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
-}
-
-tasks.withType<KotlinCompile> {
-  kotlinOptions {
-    freeCompilerArgs = listOf(
-      "-Xinline-classes",
-      "-Xopt-in=kotlin.ExperimentalUnsignedTypes"
-    )
-    jvmTarget = "1.8"
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt b/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt
new file mode 100644
index 000000000..667f8dac0
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt
@@ -0,0 +1,8 @@
+package util
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.plugins.ExtensionAware
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+
+fun BaseExtension.kotlinOptions(configure: KotlinJvmOptions.() -> Unit): Unit =
+  (this as ExtensionAware).extensions.configure("kotlinOptions", configure)
diff --git a/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
new file mode 100644
index 000000000..d8a7feeca
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
@@ -0,0 +1,22 @@
+package util
+
+import org.gradle.api.Project
+import java.util.Properties
+
+@Suppress("UnstableApiUsage")
+fun Project.git(vararg command: String): String? = try {
+  providers.exec {
+    commandLine("git", *command)
+  }.standardOutput.asText.get().trim()
+} catch (t: Throwable) {
+  null
+}
+
+fun Project.properties(fileName: String): Properties? {
+  val file = file(fileName)
+  if (!file.exists())
+    return null
+  val props = Properties()
+  props.load(file.inputStream())
+  return props
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index d984396ee..7924f651a 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,52 +1,50 @@
 [versions]
-androidx-appcompat = "1.4.1"
-androidx-espresso = "3.4.0"
-androidx-lifecycle = "2.4.1"
-androidx-room = "2.4.2"
-androidx-test = "1.4.0"
-butterknife = "10.2.3"
-dagger = "2.40.5"
-glide = "4.13.0"
-kotlin = "1.6.10"
+android-gradle-plugin = "8.1.1"
+androidx-appcompat = "1.6.1"
+androidx-espresso = "3.5.1"
+androidx-lifecycle = "2.6.1"
+androidx-room = "2.5.2"
+androidx-test = "1.5.2"
+dagger = "2.47"
+glide = "4.16.0"
+kotlin = "1.9.10"
+ksp = "1.9.10-1.0.13"
 materialdialogs = "0.9.6.0"
 retrofit = "2.6.1"
 
 [libraries]
-androidx-annotation = { module = "androidx.annotation:annotation", version = "1.3.0" }
+androidx-annotation = { module = "androidx.annotation:annotation", version = "1.6.0" }
 androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
 androidx-appcompat-resorces = { module = "androidx.appcompat:appcompat-resources", version = "androidx-appcompat" }
-androidx-browser = { module = "androidx.browser:browser", version = "1.4.0" }
+androidx-browser = { module = "androidx.browser:browser", version = "1.6.0" }
 androidx-cardview = { module = "androidx.cardview:cardview", version = "1.0.0" }
-androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.3" }
+androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
 androidx-legacy = { module = "androidx.legacy:legacy-preference-v14", version = "1.0.0" }
 androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
 androidx-lifecycle-livedata = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidx-lifecycle" }
 androidx-lifecycle-reactivestreams = { module = "androidx.lifecycle:lifecycle-reactivestreams-ktx", version.ref = "androidx-lifecycle" }
 androidx-lifecycle-service = { module = "androidx.lifecycle:lifecycle-service", version.ref = "androidx-lifecycle" }
 androidx-multidex = { module = "androidx.multidex:multidex", version = "2.0.1" }
-androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version = "3.1.0" }
-androidx-preference = { module = "androidx.preference:preference", version = "1.2.0" }
-androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.2.1" }
+androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version = "3.2.0" }
+androidx-preference = { module = "androidx.preference:preference", version = "1.2.1" }
+androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.3.1" }
 androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" }
 androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "androidx-room" }
 androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidx-room" }
 androidx-room-rxjava = { module = "androidx.room:room-rxjava2", version.ref = "androidx-room" }
 androidx-room-testing = { module = "androidx.room:room-testing", version.ref = "androidx-room" }
-androidx-room-paging = { module = "androidx.room:room-paging", version = "2.5.0-alpha01" }
+androidx-room-paging = { module = "androidx.room:room-paging", version = "2.5.2" }
 androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
-androidx-test-core = { module = "androidx.arch.core:core-testing", version = "2.1.0" }
+androidx-test-core = { module = "androidx.arch.core:core-testing", version = "2.2.0" }
 androidx-test-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-espresso" }
 androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
-androidx-test-junit = { module = "androidx.test.ext:junit", version = "1.1.3" }
+androidx-test-junit = { module = "androidx.test.ext:junit", version = "1.1.5" }
 androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-test" }
 androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test" }
 
 annotations-inject = { module = "javax.inject:javax.inject", version = "1" }
 annotations-jetbrains = { module = "org.jetbrains:annotations", version = "23.0.0" }
 
-butterknife-compiler = { module = "com.jakewharton:butterknife-compiler", version.ref = "butterknife" }
-butterknife-core = { module = "com.jakewharton:butterknife", version.ref = "butterknife" }
-
 commons-codec = { module = "commons-codec:commons-codec", version = "1.15" }
 
 dagger-android-core = { module = "com.google.dagger:dagger-android", version.ref = "dagger" }
@@ -57,7 +55,7 @@ dagger-processor = { module = "com.google.dagger:dagger-android-processor", vers
 
 flexbox = { module = "com.google.android.flexbox:flexbox", version = "3.0.0" }
 
-google-material = { module = "com.google.android.material:material", version = "1.5.0" }
+google-material = { module = "com.google.android.material:material", version = "1.9.0" }
 
 glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" }
 glide-core = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
@@ -65,8 +63,8 @@ glide-recyclerview = { module = "com.github.bumptech.glide:recyclerview-integrat
 
 gson = { module = "com.google.code.gson:gson", version = "2.9.0" }
 junit = { module = "junit:junit", version = "4.13.2" }
-kotlinpoet = { module = "com.squareup:kotlinpoet", version = "1.10.2" }
-ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version = "1.6.10-1.0.4" }
+kotlinpoet = { module = "com.squareup:kotlinpoet", version = "1.11.0" }
+ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
 leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", version = "2.8.1" }
 
 materialdialogs-commons = { module = "com.afollestad.material-dialogs:commons", version.ref = "materialdialogs" }
@@ -85,3 +83,17 @@ rxjava-java = { module = "io.reactivex.rxjava2:rxjava", version = "2.2.21" }
 
 speeddial = { module = "com.leinardi.android:speed-dial", version = "3.2.0" }
 threetenbp = { module = "org.threeten:threetenbp", version = "1.5.2" }
+
+# Dependencies of the included build-logic
+android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "android-gradle-plugin" }
+kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
+ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "android-gradle-plugin" }
+android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" }
+android-test = { id = "com.android.test", version.ref = "android-gradle-plugin" }
+kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
+kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index a28e12c60..f3d05d947 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
-distributionSha256Szm=e6d864e3b5bc05cc62041842b306383fc1fefcec359e70cebb1d470a6094ca82
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
+distributionSha256Szm=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/invokergenerator/build.gradle.kts b/invokergenerator/build.gradle.kts
index 3339302ec..adfea2ee7 100644
--- a/invokergenerator/build.gradle.kts
+++ b/invokergenerator/build.gradle.kts
@@ -2,10 +2,6 @@ plugins {
   id("justjanne.kotlin")
 }
 
-repositories {
-  google()
-}
-
 dependencies {
   implementation(libs.ksp)
   implementation(libs.kotlinpoet)
diff --git a/malheur/build.gradle.kts b/malheur/build.gradle.kts
index 59b6ed965..4281aee5e 100644
--- a/malheur/build.gradle.kts
+++ b/malheur/build.gradle.kts
@@ -21,6 +21,10 @@ plugins {
   id("justjanne.android.library")
 }
 
+android {
+  namespace = "de.kuschku.malheur"
+}
+
 dependencies {
   implementation(libs.gson)
   implementation(libs.androidx.annotation)
diff --git a/malheur/src/main/AndroidManifest.xml b/malheur/src/main/AndroidManifest.xml
deleted file mode 100644
index 716184c65..000000000
--- a/malheur/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Quasseldroid - Quassel client for Android
-
-  Copyright (c) 2019 Janne Mareike 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/>.
-  -->
-
-<manifest package="de.kuschku.malheur" />
diff --git a/persistence/build.gradle.kts b/persistence/build.gradle.kts
index d680eafc2..bf5e69076 100644
--- a/persistence/build.gradle.kts
+++ b/persistence/build.gradle.kts
@@ -21,6 +21,10 @@ plugins {
   id("justjanne.android.library")
 }
 
+android {
+  namespace = "de.kuschku.quasseldroid.persistence"
+}
+
 dependencies {
   implementation(libs.androidx.appcompat)
 
diff --git a/persistence/src/main/AndroidManifest.xml b/persistence/src/main/AndroidManifest.xml
deleted file mode 100644
index 2072478a4..000000000
--- a/persistence/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Quasseldroid - Quassel client for Android
-
-  Copyright (c) 2019 Janne Mareike 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/>.
-  -->
-
-<manifest package="de.kuschku.quasseldroid.persistence" />
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 25471e8d3..254d6946e 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -16,10 +16,27 @@
  * You should have received a copy of the GNU General Public License along
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
+@file:Suppress("UnstableApiUsage")
+
 rootProject.name = "Quasseldroid"
 rootProject.buildFileName = "build.gradle.kts"
 
-includeBuild("gradle/convention")
+pluginManagement {
+  includeBuild("gradle/convention")
+  repositories {
+    google()
+    mavenCentral()
+    gradlePluginPortal()
+  }
+}
+
+dependencyResolutionManagement {
+  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+  repositories {
+    google()
+    mavenCentral()
+  }
+}
 
 include(
   ":app",
@@ -31,11 +48,3 @@ include(
   ":viewmodel",
   ":ui_spinner"
 )
-
-pluginManagement {
-  repositories {
-    gradlePluginPortal()
-    google()
-    mavenCentral()
-  }
-}
diff --git a/ui_spinner/build.gradle.kts b/ui_spinner/build.gradle.kts
index 831058ab5..4cd3114b2 100644
--- a/ui_spinner/build.gradle.kts
+++ b/ui_spinner/build.gradle.kts
@@ -21,6 +21,10 @@ plugins {
   id("justjanne.android.library")
 }
 
+android {
+  namespace = "de.kuschku.ui.spinner"
+}
+
 dependencies {
   implementation(libs.androidx.appcompat)
 }
diff --git a/ui_spinner/src/main/AndroidManifest.xml b/ui_spinner/src/main/AndroidManifest.xml
deleted file mode 100644
index 49b9c52a7..000000000
--- a/ui_spinner/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Quasseldroid - Quassel client for Android
-
-  Copyright (c) 2019 Janne Mareike 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/>.
-  -->
-
-<manifest package="de.kuschku.ui.spinner" />
diff --git a/ui_spinner/src/main/java/de/kuschku/ui/internal/ThemeEnforcement.java b/ui_spinner/src/main/java/de/kuschku/ui/internal/ThemeEnforcement.java
index b103278cd..8aac38289 100644
--- a/ui_spinner/src/main/java/de/kuschku/ui/internal/ThemeEnforcement.java
+++ b/ui_spinner/src/main/java/de/kuschku/ui/internal/ThemeEnforcement.java
@@ -32,7 +32,7 @@ import de.kuschku.ui.spinner.R;
 public final class ThemeEnforcement {
 
   private static final int[] ANDROID_THEME_OVERLAY_ATTRS =
-    new int[]{android.R.attr.theme, R.attr.theme};
+    new int[]{android.R.attr.theme, androidx.appcompat.R.attr.theme};
   private static final int[] MATERIAL_THEME_OVERLAY_ATTR = new int[]{R.attr.materialThemeOverlay};
 
   private ThemeEnforcement() {
diff --git a/ui_spinner/src/main/java/de/kuschku/ui/shape/MaterialShapeDrawable.java b/ui_spinner/src/main/java/de/kuschku/ui/shape/MaterialShapeDrawable.java
index 2eb333bce..f7ea61326 100644
--- a/ui_spinner/src/main/java/de/kuschku/ui/shape/MaterialShapeDrawable.java
+++ b/ui_spinner/src/main/java/de/kuschku/ui/shape/MaterialShapeDrawable.java
@@ -281,7 +281,7 @@ public class MaterialShapeDrawable extends Drawable
   }
 
   @Override
-  protected void onBoundsChange(Rect bounds) {
+  protected void onBoundsChange(@NonNull Rect bounds) {
     pathDirty = true;
     super.onBoundsChange(bounds);
   }
@@ -441,7 +441,7 @@ public class MaterialShapeDrawable extends Drawable
   }
 
   @Override
-  protected boolean onStateChange(int[] state) {
+  protected boolean onStateChange(@NonNull int[] state) {
     boolean paintColorChanged = updateColorsForState(state);
     boolean tintFilterChanged = updateTintFilter();
     boolean invalidateSelf = paintColorChanged || tintFilterChanged;
@@ -539,6 +539,7 @@ public class MaterialShapeDrawable extends Drawable
       paintStyle = orig.paintStyle;
     }
 
+    @NonNull
     @Override
     public Drawable newDrawable() {
       return new MaterialShapeDrawable(this);
diff --git a/ui_spinner/src/main/java/de/kuschku/ui/spinner/MaterialSpinnerLayout.java b/ui_spinner/src/main/java/de/kuschku/ui/spinner/MaterialSpinnerLayout.java
index 289f4bbac..c47a8f5cc 100644
--- a/ui_spinner/src/main/java/de/kuschku/ui/spinner/MaterialSpinnerLayout.java
+++ b/ui_spinner/src/main/java/de/kuschku/ui/spinner/MaterialSpinnerLayout.java
@@ -1013,7 +1013,7 @@ public class MaterialSpinnerLayout extends LinearLayout {
     if (useDefaultColor) {
       // Probably caused by our theme not extending from Theme.Design*. Instead
       // we manually set something appropriate
-      TextViewCompat.setTextAppearance(textView, R.style.TextAppearance_AppCompat_Caption);
+      TextViewCompat.setTextAppearance(textView, androidx.appcompat.R.style.TextAppearance_AppCompat_Caption);
       textView.setTextColor(ContextCompat.getColor(getContext(), R.color.md_design_error));
     }
   }
diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts
index f067ff727..112321477 100644
--- a/viewmodel/build.gradle.kts
+++ b/viewmodel/build.gradle.kts
@@ -21,6 +21,10 @@ plugins {
   id("justjanne.android.library")
 }
 
+android {
+  namespace = "de.kuschku.quasseldroid.viewmodel"
+}
+
 dependencies {
   implementation(libs.androidx.appcompat)
   implementation(libs.androidx.lifecycle.viewmodel)
diff --git a/viewmodel/src/main/AndroidManifest.xml b/viewmodel/src/main/AndroidManifest.xml
deleted file mode 100644
index 1fbf6cfbb..000000000
--- a/viewmodel/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  Quasseldroid - Quassel client for Android
-
-  Copyright (c) 2019 Janne Mareike 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/>.
-  -->
-
-<manifest package="de.kuschku.quasseldroid.viewmodel" />
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/LiveDataHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/LiveDataHelper.kt
index 2fa4491c8..811274270 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/LiveDataHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/LiveDataHelper.kt
@@ -62,7 +62,7 @@ inline fun <X, Y> LiveData<X>.switchMapNotNull(
     var mSource: LiveData<Y>? = null
 
     @SuppressLint("NullSafeMutableLiveData")
-    override fun onChanged(x: X?) {
+    override fun onChanged(x: X) {
       val newLiveData = if (x == null) null else func(x)
       if (mSource === newLiveData) {
         return
@@ -103,18 +103,18 @@ inline fun <X> LiveData<X?>.or(
   return result
 }
 
-inline fun <T> LiveData<T>.observeSticky(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
+inline fun <T> LiveData<T>.observeSticky(lifecycleOwner: LifecycleOwner, observer: Observer<T?>) {
   observe(lifecycleOwner, observer)
   observer.onChanged(value)
 }
 
-inline fun <T> LiveData<T>.observeForeverSticky(observer: Observer<T>) {
+inline fun <T> LiveData<T>.observeForeverSticky(observer: Observer<T?>) {
   observeForever(observer)
   observer.onChanged(value)
 }
 
 inline fun <T> LiveData<T>.toObservable(lifecycleOwner: LifecycleOwner): Observable<T> =
-  Observable.fromPublisher(LiveDataReactiveStreams.toPublisher(lifecycleOwner, this))
+  Observable.fromPublisher(toPublisher(lifecycleOwner))
 
 
 inline operator fun <T> LiveData<T>.invoke() = value
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
index 1969f1146..1148d56c0 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt
@@ -1,8 +1,8 @@
 /*
  * Quasseldroid - Quassel client for Android
  *
- * Copyright (c) 2020 Janne Mareike Koschinski
- * Copyright (c) 2020 The Quassel Project
+ * Copyright (c) 2023 Janne Mareike Koschinski
+ * Copyright (c) 2023 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
@@ -21,7 +21,7 @@
 package de.kuschku.quasseldroid.util.helper
 
 import androidx.lifecycle.LiveData
-import androidx.lifecycle.LiveDataReactiveStreams
+import androidx.lifecycle.toLiveData
 import de.kuschku.libquassel.util.compatibility.HandlerService
 import io.reactivex.*
 import io.reactivex.schedulers.Schedulers
@@ -31,15 +31,15 @@ inline fun <T> Observable<T>.toLiveData(
   handlerService: HandlerService? = null,
   scheduler: Scheduler = handlerService?.scheduler ?: Schedulers.computation()
 ): LiveData<T> =
-  LiveDataReactiveStreams.fromPublisher(subscribeOn(scheduler).toFlowable(strategy))
+  subscribeOn(scheduler).toFlowable(strategy).toLiveData()
 
 inline fun <T> Maybe<T>.toLiveData(
   handlerService: HandlerService? = null,
   scheduler: Scheduler = handlerService?.scheduler ?: Schedulers.computation()
 ): LiveData<T> =
-  LiveDataReactiveStreams.fromPublisher(subscribeOn(scheduler).toFlowable())
+  subscribeOn(scheduler).toFlowable().toLiveData()
 
 inline fun <T> Flowable<T>.toLiveData(
   handlerService: HandlerService? = null,
   scheduler: Scheduler = handlerService?.scheduler ?: Schedulers.computation()
-): LiveData<T> = LiveDataReactiveStreams.fromPublisher(subscribeOn(scheduler))
+): LiveData<T> = subscribeOn(scheduler).toLiveData()
-- 
GitLab