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 9e971b1d99603fd9209fe8227b6052e0a0328a15..1f1d95830cd5b64dcf5ccaa095f452ba6527b25f 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
@@ -28,7 +28,6 @@ import android.content.SharedPreferences
 import android.content.pm.PackageManager
 import android.os.Build
 import android.os.Bundle
-import android.os.PersistableBundle
 import android.system.ErrnoException
 import android.text.Html
 import android.view.ActionMode
@@ -42,6 +41,7 @@ import androidx.appcompat.app.ActionBarDrawerToggle
 import androidx.core.app.ActivityCompat
 import androidx.core.view.GravityCompat
 import androidx.drawerlayout.widget.DrawerLayout
+import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.Observer
 import androidx.recyclerview.widget.DefaultItemAnimator
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -94,6 +94,7 @@ import de.kuschku.quasseldroid.util.backport.OsConstants
 import de.kuschku.quasseldroid.util.deceptive_networks.DeceptiveNetworkDialog
 import de.kuschku.quasseldroid.util.helper.*
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
+import de.kuschku.quasseldroid.util.missingfeatures.MissingFeature
 import de.kuschku.quasseldroid.util.missingfeatures.MissingFeaturesDialog
 import de.kuschku.quasseldroid.util.missingfeatures.RequiredFeatures
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
@@ -106,6 +107,9 @@ import de.kuschku.quasseldroid.viewmodel.ChatViewModel
 import de.kuschku.quasseldroid.viewmodel.data.BufferData
 import de.kuschku.quasseldroid.viewmodel.helper.ChatViewModelHelper
 import io.reactivex.BackpressureStrategy
+import io.reactivex.Observable
+import io.reactivex.subjects.BehaviorSubject
+import io.reactivex.subjects.PublishSubject
 import org.threeten.bp.Instant
 import org.threeten.bp.ZoneId
 import org.threeten.bp.format.DateTimeFormatter
@@ -162,6 +166,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
   private var restoredDrawerState = false
 
+  private val permissionGranted = BehaviorSubject.createDefault(false)
+
   fun processIntent(intent: Intent) {
     when {
       intent.type == "text/plain" -> {
@@ -309,6 +315,20 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     binding = ActivityMainBinding.inflate(layoutInflater)
     setContentView(binding.root)
 
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+      permissionGranted.onNext(
+        PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
+          applicationContext,
+          Manifest.permission.POST_NOTIFICATIONS
+        )
+      )
+    } else {
+      permissionGranted.onNext(true)
+    }
+    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
+      permissionGranted.onNext(isGranted)
+    }
+
     chatlineFragment =
       supportFragmentManager.findFragmentById(R.id.fragment_chatline) as? ChatlineFragment
 
@@ -782,12 +802,71 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       }
     })
 
-    // After initial connect, open the drawer
-    modelHelper.connectionProgress
-      .filter { (it, _, _) -> it == ConnectionState.CONNECTED }
-      .firstElement()
-      .toLiveData()
-      .observe(this, Observer {
+    val isConnected: Observable<Boolean> = modelHelper.connectionProgress.map { (state, _, _) ->
+      state == ConnectionState.CONNECTED
+    }.filter { it }
+
+    val missingIdentity: Observable<Boolean> = modelHelper.connectedSession.map { session ->
+      session.orNull()?.identities.isNullOrEmpty()
+    }
+
+    val missingFeatures: Observable<List<MissingFeature>> =
+      modelHelper.connectedSession.mapMap { session ->
+        RequiredFeatures.features.filter {
+          it.feature !in session.features.core.enabledFeatures
+        }
+      }.mapOrElse(emptyList())
+
+    val postConnectionState = combineLatest(
+      isConnected,
+      missingIdentity,
+      missingFeatures,
+      permissionGranted
+    ).map { (connected, missingIdentity, missingFeatures, permissionGranted) ->
+      when {
+        !connected -> PostConnectionState.Connecting
+        missingIdentity -> PostConnectionState.SetupIdentity
+        missingFeatures.isNotEmpty() -> PostConnectionState.MissingFeatures(missingFeatures)
+        !permissionGranted -> PostConnectionState.RequestingPermissions
+        else -> PostConnectionState.Done
+      }
+    }
+
+    postConnectionState.toLiveData().observe(this) { state ->
+      if (state == PostConnectionState.SetupIdentity) {
+        UserSetupActivity.launch(this)
+      } else if (state is PostConnectionState.MissingFeatures) {
+        runInBackground {
+          val accounts = accountDatabase.accounts()
+          val account = accounts.findById(accountId)
+          if (account?.acceptedMissingFeatures == false) {
+            val dialog = MissingFeaturesDialog.Builder(this)
+              .missingFeatures(state.features)
+              .positiveListener(MaterialDialog.SingleButtonCallback { _, _ ->
+                runInBackground {
+                  accounts.save(account.copy(acceptedMissingFeatures = true))
+                }
+              })
+            runOnUiThread {
+              dialog.show()
+            }
+          }
+        }
+      } else if (state == PostConnectionState.RequestingPermissions &&
+        Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
+      ) {
+        if (ActivityCompat.checkSelfPermission(
+            applicationContext,
+            Manifest.permission.POST_NOTIFICATIONS
+          ) != PackageManager.PERMISSION_GRANTED
+        ) {
+          ActivityCompat.requestPermissions(
+            this,
+            arrayOf(Manifest.permission.POST_NOTIFICATIONS),
+            1
+          )
+        }
+      } else {
         if (connectedAccount != accountId) {
           if (resources.getBoolean(R.bool.buffer_drawer_exists) &&
             chatViewModel.bufferId.safeValue == BufferId.MAX_VALUE &&
@@ -796,34 +875,9 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
             binding.drawerLayout.openDrawer(GravityCompat.START)
           }
           connectedAccount = accountId
-          modelHelper.connectedSession.value?.orNull()?.let { session ->
-            if (session.identities.isEmpty()) {
-              UserSetupActivity.launch(this)
-            }
-            val missingFeatures = RequiredFeatures.features.filter {
-              it.feature !in session.features.core.enabledFeatures
-            }
-            if (missingFeatures.isNotEmpty()) {
-              runInBackground {
-                val accounts = accountDatabase.accounts()
-                val account = accounts.findById(accountId)
-                if (account?.acceptedMissingFeatures == false) {
-                  val dialog = MissingFeaturesDialog.Builder(this)
-                    .missingFeatures(missingFeatures)
-                    .positiveListener(MaterialDialog.SingleButtonCallback { _, _ ->
-                      runInBackground {
-                        accounts.save(account.copy(acceptedMissingFeatures = true))
-                      }
-                    })
-                  runOnUiThread {
-                    dialog.show()
-                  }
-                }
-              }
-            }
-          }
         }
-      })
+      }
+    }
 
     binding.layoutMain.connectionStatus.setOnClickListener {
       if (modelHelper.connectionProgress.value?.first == ConnectionState.CONNECTED
@@ -950,28 +1004,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
         launch(this, bufferId = info.bufferId)
       }
     }
-
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
-      registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
-        if (isGranted) {
-          if (modelHelper.connectionProgress.value?.first == ConnectionState.CONNECTED) {
-            notificationBackend.showConnectedNotifications()
-          }
-        }
-      }
-
-      if (ActivityCompat.checkSelfPermission(
-          applicationContext,
-          Manifest.permission.POST_NOTIFICATIONS
-        ) != PackageManager.PERMISSION_GRANTED
-      ) {
-        ActivityCompat.requestPermissions(
-          this,
-          arrayOf(Manifest.permission.POST_NOTIFICATIONS),
-          1
-        )
-      }
-    }
   }
 
   override fun onNewIntent(intent: Intent?) {
@@ -1316,4 +1348,12 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       }
     }
   }
+
+  sealed class PostConnectionState {
+    object Connecting : PostConnectionState()
+    object SetupIdentity : PostConnectionState()
+    data class MissingFeatures(val features: List<MissingFeature>) : PostConnectionState()
+    object RequestingPermissions : PostConnectionState()
+    object Done : PostConnectionState()
+  }
 }