Эх сурвалжийг харах

WIP. Replace Controller with Activity for ConversationList

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 1 жил өмнө
parent
commit
aa1e93db05

+ 4 - 0
app/src/main/AndroidManifest.xml

@@ -224,6 +224,10 @@
             android:launchMode="singleInstance"
             android:screenOrientation="portrait" />
 
+        <activity
+            android:name=".conversationlist.ConversationsListActivity"
+            android:theme="@style/AppTheme" />
+
         <receiver android:name=".receivers.PackageReplacedReceiver"
             android:exported="false">
             <intent-filter>

+ 7 - 0
app/src/main/java/com/nextcloud/talk/activities/BaseActivity.kt

@@ -48,6 +48,10 @@ import javax.inject.Inject
 @AutoInjector(NextcloudTalkApplication::class)
 open class BaseActivity : AppCompatActivity() {
 
+    enum class AppBarLayoutType {
+        TOOLBAR, SEARCH_BAR, EMPTY
+    }
+
     @Inject
     lateinit var eventBus: EventBus
 
@@ -60,6 +64,9 @@ open class BaseActivity : AppCompatActivity() {
     @Inject
     lateinit var context: Context
 
+    open val appBarLayoutType: AppBarLayoutType
+        get() = AppBarLayoutType.TOOLBAR
+
     override fun onCreate(savedInstanceState: Bundle?) {
         NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
         super.onCreate(savedInstanceState)

+ 5 - 12
app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt

@@ -40,15 +40,14 @@ import com.nextcloud.talk.R
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.chat.ChatActivity
-import com.nextcloud.talk.controllers.ConversationsListController
 import com.nextcloud.talk.controllers.LockedController
 import com.nextcloud.talk.controllers.ServerSelectionController
 import com.nextcloud.talk.controllers.WebViewLoginController
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
+import com.nextcloud.talk.conversationlist.ConversationsListActivity
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ActivityMainBinding
 import com.nextcloud.talk.models.json.conversations.RoomOverall
-import com.nextcloud.talk.settings.SettingsActivity
 import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.SecurityUtils
@@ -165,11 +164,10 @@ class MainActivity : BaseActivity(), ActionBarProvider {
     }
 
     private fun setDefaultRootController() {
-        router!!.setRoot(
-            RouterTransaction.with(ConversationsListController(Bundle()))
-                .pushChangeHandler(HorizontalChangeHandler())
-                .popChangeHandler(HorizontalChangeHandler())
-        )
+        val intent = Intent(this, ConversationsListActivity::class.java)
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+        intent.putExtras(Bundle())
+        startActivity(intent)
     }
 
     fun resetConversationsList() {
@@ -192,11 +190,6 @@ class MainActivity : BaseActivity(), ActionBarProvider {
         })
     }
 
-    fun openSettings() {
-        val intent = Intent(this, SettingsActivity::class.java)
-        startActivity(intent)
-    }
-
     fun addAccount() {
         router!!.pushController(
             RouterTransaction.with(ServerSelectionController())

+ 5 - 8
app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt

@@ -121,8 +121,8 @@ import com.nextcloud.talk.adapters.messages.VoiceMessageInterface
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
-import com.nextcloud.talk.controllers.ConversationsListController
 import com.nextcloud.talk.conversation.info.ConversationInfoActivity
+import com.nextcloud.talk.conversationlist.ConversationsListActivity
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerChatBinding
 import com.nextcloud.talk.events.UserMentionClickEvent
@@ -1763,7 +1763,7 @@ class ChatActivity :
         super.onRequestPermissionsResult(requestCode, permissions, grantResults)
         if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION) {
             if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-                Log.d(ConversationsListController.TAG, "upload starting after permissions were granted")
+                Log.d(ConversationsListActivity.TAG, "upload starting after permissions were granted")
                 if (filesToUpload.isNotEmpty()) {
                     uploadFiles(filesToUpload)
                 }
@@ -3154,12 +3154,9 @@ class ChatActivity :
         bundle.putString(BundleKeys.KEY_FORWARD_MSG_TEXT, message?.text)
         bundle.putString(BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM, roomId)
 
-        // TODO
-        // router.pushController(
-        //     RouterTransaction.with(ConversationsListController(bundle))
-        //         .pushChangeHandler(HorizontalChangeHandler())
-        //         .popChangeHandler(HorizontalChangeHandler())
-        // )
+        val intent = Intent(this, ConversationsListActivity::class.java)
+        intent.putExtras(bundle)
+        startActivity(intent)
     }
 
     fun markAsUnread(message: IMessage?) {

+ 6 - 10
app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt

@@ -22,6 +22,7 @@
 package com.nextcloud.talk.controllers
 
 import android.annotation.SuppressLint
+import android.content.Intent
 import android.content.pm.ActivityInfo
 import android.os.Bundle
 import android.os.Handler
@@ -42,6 +43,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.controllers.base.BaseController
 import com.nextcloud.talk.controllers.util.viewBinding
+import com.nextcloud.talk.conversationlist.ConversationsListActivity
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerAccountVerificationBinding
 import com.nextcloud.talk.events.EventStatus
@@ -457,11 +459,8 @@ class AccountVerificationController(args: Bundle? = null) :
             if (activity != null) {
                 activity!!.runOnUiThread {
                     if (userManager.users.blockingGet().size == 1) {
-                        router.setRoot(
-                            RouterTransaction.with(ConversationsListController(Bundle()))
-                                .pushChangeHandler(HorizontalChangeHandler())
-                                .popChangeHandler(HorizontalChangeHandler())
-                        )
+                        val intent = Intent(context, ConversationsListActivity::class.java)
+                        startActivity(intent)
                     } else {
                         if (isAccountImport) {
                             ApplicationWideMessageHolder.getInstance().messageType =
@@ -517,11 +516,8 @@ class AccountVerificationController(args: Bundle? = null) :
                         }
                     } else {
                         if (userManager.users.blockingGet().isNotEmpty()) {
-                            router.setRoot(
-                                RouterTransaction.with(ConversationsListController(Bundle()))
-                                    .pushChangeHandler(HorizontalChangeHandler())
-                                    .popChangeHandler(HorizontalChangeHandler())
-                            )
+                            val intent = Intent(context, ConversationsListActivity::class.java)
+                            startActivity(intent)
                         } else {
                             router.setRoot(
                                 RouterTransaction.with(ServerSelectionController())

+ 94 - 101
app/src/main/java/com/nextcloud/talk/controllers/base/BaseController.kt

@@ -22,10 +22,7 @@
  */
 package com.nextcloud.talk.controllers.base
 
-import android.animation.AnimatorInflater
-import android.app.Activity
 import android.content.Context
-import android.content.res.Resources
 import android.os.Build
 import android.os.Bundle
 import android.util.Log
@@ -39,12 +36,10 @@ import android.widget.EditText
 import androidx.annotation.LayoutRes
 import androidx.annotation.RequiresApi
 import androidx.appcompat.app.ActionBar
-import androidx.core.content.res.ResourcesCompat
 import autodagger.AutoInjector
 import com.bluelinelabs.conductor.Controller
 import com.bluelinelabs.conductor.ControllerChangeHandler
 import com.bluelinelabs.conductor.ControllerChangeType
-import com.google.android.material.appbar.AppBarLayout
 import com.nextcloud.talk.R
 import com.nextcloud.talk.activities.MainActivity
 import com.nextcloud.talk.application.NextcloudTalkApplication
@@ -54,9 +49,7 @@ import com.nextcloud.talk.controllers.ServerSelectionController
 import com.nextcloud.talk.controllers.SwitchAccountController
 import com.nextcloud.talk.controllers.WebViewLoginController
 import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
-import com.nextcloud.talk.databinding.ActivityMainBinding
 import com.nextcloud.talk.ui.theme.ViewThemeUtils
-import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import javax.inject.Inject
 import kotlin.jvm.internal.Intrinsics
@@ -120,12 +113,12 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
     protected open fun onViewBound(view: View) {
         var activity: MainActivity? = null
 
-        if (getActivity() != null && getActivity() is MainActivity) {
-            activity = getActivity() as MainActivity?
-            viewThemeUtils.material.themeCardView(activity!!.binding.searchToolbar)
-            viewThemeUtils.material.themeToolbar(activity.binding.toolbar)
-            viewThemeUtils.material.themeSearchBarText(activity.binding.searchText)
-        }
+        // if (getActivity() != null && getActivity() is MainActivity) {
+        //     activity = getActivity() as MainActivity?
+        //     viewThemeUtils.material.themeCardView(activity!!.binding.searchToolbar)
+        //     viewThemeUtils.material.themeToolbar(activity.binding.toolbar)
+        //     viewThemeUtils.material.themeSearchBarText(activity.binding.searchText)
+        // }
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.isKeyboardIncognito) {
             disableKeyboardPersonalisedLearning((view as ViewGroup))
@@ -136,7 +129,7 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
     }
 
     override fun onAttach(view: View) {
-        showSearchOrToolbar()
+        // showSearchOrToolbar()
         setTitle()
         if (actionBar != null) {
             actionBar!!.setDisplayHomeAsUpEnabled(parentController != null || router.backstackSize >= 1)
@@ -144,93 +137,93 @@ abstract class BaseController(@LayoutRes var layoutRes: Int, args: Bundle? = nul
         super.onAttach(view)
     }
 
-    open fun showSearchOrToolbar() {
-        if (isValidActivity(activity)) {
-            val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
-            val activity = activity as MainActivity
-
-            if (appBarLayoutType == AppBarLayoutType.EMPTY) {
-                hideBars(activity.binding)
-            } else {
-                if (showSearchBar) {
-                    showSearchBar(activity.binding)
-                } else {
-                    showToolbar(activity.binding)
-                }
-                colorizeStatusBar(showSearchBar, activity, resources)
-            }
-
-            colorizeNavigationBar(activity, resources)
-        }
-    }
-
-    private fun isValidActivity(activity: Activity?): Boolean {
-        return activity != null && activity is MainActivity
-    }
-
-    private fun showSearchBar(binding: ActivityMainBinding) {
-        val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
-        binding.searchToolbar.visibility = View.VISIBLE
-        binding.searchText.hint = searchHint
-        binding.toolbar.visibility = View.GONE
-        // layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
-        // .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
-        layoutParams.scrollFlags = 0
-        binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
-            binding.appBar.context,
-            R.animator.appbar_elevation_off
-        )
-        binding.searchToolbar.layoutParams = layoutParams
-    }
-
-    private fun showToolbar(binding: ActivityMainBinding) {
-        val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
-        binding.searchToolbar.visibility = View.GONE
-        binding.toolbar.visibility = View.VISIBLE
-        viewThemeUtils.material.colorToolbarOverflowIcon(binding.toolbar)
-        layoutParams.scrollFlags = 0
-        binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
-            binding.appBar.context,
-            R.animator.appbar_elevation_on
-        )
-        binding.searchToolbar.layoutParams = layoutParams
-    }
-
-    private fun hideBars(binding: ActivityMainBinding) {
-        binding.toolbar.visibility = View.GONE
-        binding.searchToolbar.visibility = View.GONE
-    }
-
-    fun hideSearchBar() {
-        val activity = activity as MainActivity?
-        val layoutParams = activity!!.binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
-        activity.binding.searchToolbar.visibility = View.GONE
-        activity.binding.toolbar.visibility = View.VISIBLE
-        layoutParams.scrollFlags = 0
-        activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
-            activity.binding.appBar.context,
-            R.animator.appbar_elevation_on
-        )
-    }
-
-    private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
-        if (activity != null && resources != null) {
-            if (showSearchBar) {
-                view?.let { viewThemeUtils.platform.resetStatusBar(activity) }
-            } else {
-                view?.let { viewThemeUtils.platform.themeStatusBar(activity, it) }
-            }
-        }
-    }
-
-    private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
-        if (activity != null && resources != null) {
-            DisplayUtils.applyColorToNavigationBar(
-                activity.window,
-                ResourcesCompat.getColor(resources, R.color.bg_default, null)
-            )
-        }
-    }
+    // open fun showSearchOrToolbar() {
+    //     if (isValidActivity(activity)) {
+    //         val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
+    //         val activity = activity as MainActivity
+    //
+    //         if (appBarLayoutType == AppBarLayoutType.EMPTY) {
+    //             hideBars(activity.binding)
+    //         } else {
+    //             if (showSearchBar) {
+    //                 showSearchBar(activity.binding)
+    //             } else {
+    //                 showToolbar(activity.binding)
+    //             }
+    //             colorizeStatusBar(showSearchBar, activity, resources)
+    //         }
+    //
+    //         colorizeNavigationBar(activity, resources)
+    //     }
+    // }
+    //
+    // private fun isValidActivity(activity: Activity?): Boolean {
+    //     return activity != null && activity is MainActivity
+    // }
+    //
+    // private fun showSearchBar(binding: ActivityMainBinding) {
+    //     val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+    //     binding.searchToolbar.visibility = View.VISIBLE
+    //     binding.searchText.hint = searchHint
+    //     binding.toolbar.visibility = View.GONE
+    //     // layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
+    //     // .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
+    //     layoutParams.scrollFlags = 0
+    //     binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+    //         binding.appBar.context,
+    //         R.animator.appbar_elevation_off
+    //     )
+    //     binding.searchToolbar.layoutParams = layoutParams
+    // }
+    //
+    // private fun showToolbar(binding: ActivityMainBinding) {
+    //     val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+    //     binding.searchToolbar.visibility = View.GONE
+    //     binding.toolbar.visibility = View.VISIBLE
+    //     viewThemeUtils.material.colorToolbarOverflowIcon(binding.toolbar)
+    //     layoutParams.scrollFlags = 0
+    //     binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+    //         binding.appBar.context,
+    //         R.animator.appbar_elevation_on
+    //     )
+    //     binding.searchToolbar.layoutParams = layoutParams
+    // }
+    //
+    // private fun hideBars(binding: ActivityMainBinding) {
+    //     binding.toolbar.visibility = View.GONE
+    //     binding.searchToolbar.visibility = View.GONE
+    // }
+    //
+    // fun hideSearchBar() {
+    //     val activity = activity as MainActivity?
+    //     val layoutParams = activity!!.binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+    //     activity.binding.searchToolbar.visibility = View.GONE
+    //     activity.binding.toolbar.visibility = View.VISIBLE
+    //     layoutParams.scrollFlags = 0
+    //     activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+    //         activity.binding.appBar.context,
+    //         R.animator.appbar_elevation_on
+    //     )
+    // }
+    //
+    // private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
+    //     if (activity != null && resources != null) {
+    //         if (showSearchBar) {
+    //             view?.let { viewThemeUtils.platform.resetStatusBar(activity) }
+    //         } else {
+    //             view?.let { viewThemeUtils.platform.themeStatusBar(activity, it) }
+    //         }
+    //     }
+    // }
+    //
+    // private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
+    //     if (activity != null && resources != null) {
+    //         DisplayUtils.applyColorToNavigationBar(
+    //             activity.window,
+    //             ResourcesCompat.getColor(resources, R.color.bg_default, null)
+    //         )
+    //     }
+    // }
 
     override fun onDetach(view: View) {
         super.onDetach(view)

+ 361 - 309
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.kt → app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt

@@ -23,14 +23,17 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-package com.nextcloud.talk.controllers
+package com.nextcloud.talk.conversationlist
 
 import android.animation.AnimatorInflater
 import android.annotation.SuppressLint
+import android.app.Activity
 import android.app.SearchManager
 import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.graphics.drawable.ColorDrawable
 import android.graphics.drawable.Drawable
 import android.net.Uri
 import android.os.Build
@@ -40,7 +43,6 @@ import android.text.InputType
 import android.text.TextUtils
 import android.util.Log
 import android.view.Menu
-import android.view.MenuInflater
 import android.view.MenuItem
 import android.view.MotionEvent
 import android.view.View
@@ -49,6 +51,7 @@ import android.view.inputmethod.InputMethodManager
 import android.widget.Toast
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.widget.SearchView
+import androidx.core.content.res.ResourcesCompat
 import androidx.core.view.MenuItemCompat
 import androidx.fragment.app.DialogFragment
 import androidx.recyclerview.widget.RecyclerView
@@ -60,13 +63,12 @@ import coil.imageLoader
 import coil.request.ImageRequest
 import coil.target.Target
 import coil.transform.CircleCropTransformation
-import com.bluelinelabs.conductor.RouterTransaction
-import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
+import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.button.MaterialButton
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.nextcloud.talk.R
+import com.nextcloud.talk.activities.BaseActivity
 import com.nextcloud.talk.activities.CallActivity
-import com.nextcloud.talk.activities.MainActivity
 import com.nextcloud.talk.adapters.items.ConversationItem
 import com.nextcloud.talk.adapters.items.GenericTextHeaderItem
 import com.nextcloud.talk.adapters.items.LoadMoreResultsItem
@@ -74,11 +76,8 @@ import com.nextcloud.talk.adapters.items.MessageResultItem
 import com.nextcloud.talk.adapters.items.MessagesTextHeaderItem
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
-import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.chat.ChatActivity
 import com.nextcloud.talk.contacts.ContactsActivity
-import com.nextcloud.talk.controllers.base.BaseController
-import com.nextcloud.talk.controllers.util.viewBinding
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerConversationsRvBinding
 import com.nextcloud.talk.events.ConversationsListFetchDataEvent
@@ -100,6 +99,7 @@ import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog
 import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ClosedInterfaceImpl
+import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.FileUtils
 import com.nextcloud.talk.utils.Mimetype
 import com.nextcloud.talk.utils.ParticipantPermissions
@@ -130,7 +130,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
 import org.apache.commons.lang3.builder.CompareToBuilder
-import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import org.parceler.Parcels
@@ -140,18 +139,16 @@ import java.util.concurrent.TimeUnit
 import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
-class ConversationsListController(bundle: Bundle) :
-    BaseController(R.layout.controller_conversations_rv, bundle),
+class ConversationsListActivity :
+    BaseActivity(),
     FlexibleAdapter.OnItemClickListener,
     FlexibleAdapter.OnItemLongClickListener,
     ConversationMenuInterface {
-    private val bundle: Bundle
 
-    @Inject
-    lateinit var userManager: UserManager
+    private lateinit var binding: ControllerConversationsRvBinding
 
     @Inject
-    lateinit var eventBus: EventBus
+    lateinit var userManager: UserManager
 
     @Inject
     lateinit var ncApi: NcApi
@@ -162,11 +159,6 @@ class ConversationsListController(bundle: Bundle) :
     @Inject
     lateinit var platformPermissionUtil: PlatformPermissionUtil
 
-    private val binding: ControllerConversationsRvBinding? by viewBinding(ControllerConversationsRvBinding::bind)
-
-    override val title: String
-        get() = resources!!.getString(R.string.nc_app_product_name)
-
     override val appBarLayoutType: AppBarLayoutType
         get() = AppBarLayoutType.SEARCH_BAR
 
@@ -190,7 +182,7 @@ class ConversationsListController(bundle: Bundle) :
     private var selectedConversation: Conversation? = null
     private var textToPaste: String? = ""
     private var selectedMessageId: String? = null
-    private var forwardMessage: Boolean
+    private var forwardMessage: Boolean = false
     private var nextUnreadConversationScrollPosition = 0
     private var layoutManager: SmoothScrollLinearLayoutManager? = null
     private val callHeaderItems = HashMap<String, GenericTextHeaderItem>()
@@ -198,46 +190,110 @@ class ConversationsListController(bundle: Bundle) :
     private var searchHelper: MessageSearchHelper? = null
     private var searchViewDisposable: Disposable? = null
 
-    override fun onViewBound(view: View) {
-        super.onViewBound(view)
-        sharedApplication!!.componentApplication.inject(this)
-        actionBar?.show()
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
+
+        binding = ControllerConversationsRvBinding.inflate(layoutInflater)
+        setupActionBar()
+        setupSystemColors()
+        setContentView(binding.root)
+
+        forwardMessage = intent.getBooleanExtra(KEY_FORWARD_MSG_FLAG, false)
+    }
+
+    override fun onResume() {
+        super.onResume()
+
+        // actionBar?.show()
         if (adapter == null) {
-            adapter = FlexibleAdapter(conversationItems, activity, true)
+            adapter = FlexibleAdapter(conversationItems, this, true)
         } else {
             binding?.loadingContent?.visibility = View.GONE
         }
         adapter!!.addListener(this)
         prepareViews()
+
+        showShareToScreen = hasActivityActionSendIntent()
+
+        ClosedInterfaceImpl().setUpPushTokenRegistration()
+        if (!eventBus.isRegistered(this)) {
+            eventBus.register(this)
+        }
+        currentUser = userManager.currentUser.blockingGet()
+        if (currentUser != null) {
+            if (isServerEOL(currentUser!!)) {
+                showServerEOLDialog()
+                return
+            }
+            if (isUnifiedSearchAvailable(currentUser!!)) {
+                searchHelper = MessageSearchHelper(unifiedSearchRepository)
+            }
+            credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
+
+            loadUserAvatar(binding.switchAccountButton)
+            viewThemeUtils.material.colorMaterialTextButton(binding.switchAccountButton)
+
+            fetchRooms()
+        } else {
+            Log.e(TAG, "userManager.currentUser.blockingGet() returned null")
+            Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
+        }
+
+        showSearchOrToolbar()
+    }
+
+    private fun setupActionBar() {
+        setSupportActionBar(binding.conversationListToolbar)
+        binding.conversationListToolbar.setNavigationOnClickListener {
+            onBackPressed()
+        }
+        supportActionBar?.setDisplayHomeAsUpEnabled(true)
+        supportActionBar?.setDisplayShowHomeEnabled(true)
+        supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent)))
+        supportActionBar?.title = resources!!.getString(R.string.nc_app_product_name)
+    }
+
+    private fun setupSystemColors() {
+        DisplayUtils.applyColorToStatusBar(
+            this,
+            ResourcesCompat.getColor(
+                resources,
+                R.color.appbar,
+                null
+            )
+        )
+        DisplayUtils.applyColorToNavigationBar(
+            this.window,
+            ResourcesCompat.getColor(resources, R.color.bg_default, null)
+        )
     }
 
     private fun loadUserAvatar(
         target: Target
     ) {
-        if (activity != null) {
-            if (currentUser != null) {
-                val url = ApiUtils.getUrlForAvatar(
-                    currentUser!!.baseUrl,
-                    currentUser!!.userId,
-                    true
-                )
+        if (currentUser != null) {
+            val url = ApiUtils.getUrlForAvatar(
+                currentUser!!.baseUrl,
+                currentUser!!.userId,
+                true
+            )
 
-                val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
-
-                context.imageLoader.enqueue(
-                    ImageRequest.Builder(context)
-                        .data(url)
-                        .addHeader("Authorization", credentials)
-                        .placeholder(R.drawable.ic_user)
-                        .transformations(CircleCropTransformation())
-                        .crossfade(true)
-                        .target(target)
-                        .build()
-                )
-            } else {
-                Log.e(TAG, "currentUser was null in loadUserAvatar")
-                Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
-            }
+            val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
+
+            context.imageLoader.enqueue(
+                ImageRequest.Builder(context)
+                    .data(url)
+                    .addHeader("Authorization", credentials)
+                    .placeholder(R.drawable.ic_user)
+                    .transformations(CircleCropTransformation())
+                    .crossfade(true)
+                    .target(target)
+                    .build()
+            )
+        } else {
+            Log.e(TAG, "currentUser was null in loadUserAvatar")
+            Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
         }
     }
 
@@ -268,92 +324,44 @@ class ConversationsListController(bundle: Bundle) :
         loadUserAvatar(target)
     }
 
-    override fun onAttach(view: View) {
-        Log.d(
-            TAG,
-            "onAttach: Controller: " + System.identityHashCode(this) +
-                " Activity: " + System.identityHashCode(activity)
-        )
-        super.onAttach(view)
-
-        showShareToScreen = hasActivityActionSendIntent()
-
-        ClosedInterfaceImpl().setUpPushTokenRegistration()
-        if (!eventBus.isRegistered(this)) {
-            eventBus.register(this)
-        }
-        currentUser = userManager.currentUser.blockingGet()
-        if (currentUser != null) {
-            if (isServerEOL(currentUser!!)) {
-                showServerEOLDialog()
-                return
-            }
-            if (isUnifiedSearchAvailable(currentUser!!)) {
-                searchHelper = MessageSearchHelper(unifiedSearchRepository)
+    private fun initSearchView() {
+        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager?
+        if (searchItem != null) {
+            searchView = MenuItemCompat.getActionView(searchItem) as SearchView
+            viewThemeUtils.talk.themeSearchView(searchView!!)
+            searchView!!.maxWidth = Int.MAX_VALUE
+            searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
+            var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.isKeyboardIncognito) {
+                imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
             }
-            credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
-            if (activity != null && activity is MainActivity) {
-                loadUserAvatar((activity as MainActivity?)!!.binding.switchAccountButton)
-                viewThemeUtils.material
-                    .colorMaterialTextButton((activity as MainActivity?)!!.binding.switchAccountButton)
+            searchView!!.imeOptions = imeOptions
+            searchView!!.queryHint = getString(R.string.appbar_search_in, getString(R.string.nc_app_product_name))
+            if (searchManager != null) {
+                searchView!!.setSearchableInfo(searchManager.getSearchableInfo(componentName))
             }
-            fetchRooms()
-        } else {
-            Log.e(TAG, "userManager.currentUser.blockingGet() returned null")
-            Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
-        }
-    }
-
-    override fun onDetach(view: View) {
-        Log.d(
-            TAG,
-            "onDetach: Controller: " + System.identityHashCode(this) +
-                " Activity: " + System.identityHashCode(activity)
-        )
-        super.onDetach(view)
-        eventBus.unregister(this)
-    }
-
-    private fun initSearchView() {
-        if (activity != null) {
-            val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
-            if (searchItem != null) {
-                searchView = MenuItemCompat.getActionView(searchItem) as SearchView
-                viewThemeUtils.talk.themeSearchView(searchView!!)
-                searchView!!.maxWidth = Int.MAX_VALUE
-                searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
-                var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences.isKeyboardIncognito) {
-                    imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
-                }
-                searchView!!.imeOptions = imeOptions
-                searchView!!.queryHint = searchHint
-                if (searchManager != null) {
-                    searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
-                }
-                searchViewDisposable = observeSearchView(searchView!!)
-                    .debounce { query: String? ->
-                        if (TextUtils.isEmpty(query)) {
-                            return@debounce Observable.empty<Long>()
-                        } else {
-                            return@debounce Observable.timer(
-                                SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
-                                TimeUnit.MILLISECONDS
-                            )
-                        }
+            searchViewDisposable = observeSearchView(searchView!!)
+                .debounce { query: String? ->
+                    if (TextUtils.isEmpty(query)) {
+                        return@debounce Observable.empty<Long>()
+                    } else {
+                        return@debounce Observable.timer(
+                            SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
+                            TimeUnit.MILLISECONDS
+                        )
                     }
-                    .distinctUntilChanged()
-                    .subscribeOn(Schedulers.io())
-                    .observeOn(AndroidSchedulers.mainThread())
-                    .subscribe { newText: String? -> onQueryTextChange(newText) }
-            }
+                }
+                .distinctUntilChanged()
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe { newText: String? -> onQueryTextChange(newText) }
         }
     }
 
-    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
-        super.onCreateOptionsMenu(menu, inflater)
+    override fun onCreateOptionsMenu(menu: Menu): Boolean {
+        super.onCreateOptionsMenu(menu)
 
-        inflater.inflate(R.menu.menu_conversation_plus_filter, menu)
+        menuInflater.inflate(R.menu.menu_conversation_plus_filter, menu)
         searchItem = menu.findItem(R.id.action_search)
         chooseAccountItem = menu.findItem(R.id.action_choose_account)
         loadUserAvatar(chooseAccountItem!!)
@@ -362,17 +370,19 @@ class ConversationsListController(bundle: Bundle) :
             if (resources != null && resources!!.getBoolean(R.bool.multiaccount_support)) {
                 val newFragment: DialogFragment = ChooseAccountShareToDialogFragment.newInstance()
                 newFragment.show(
-                    (activity as MainActivity?)!!.supportFragmentManager,
+                    supportFragmentManager,
                     ChooseAccountShareToDialogFragment.TAG
                 )
             }
             true
         }
         initSearchView()
+        return true
     }
 
-    override fun onPrepareOptionsMenu(menu: Menu) {
+    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
         super.onPrepareOptionsMenu(menu)
+
         searchView = MenuItemCompat.getActionView(searchItem) as SearchView
 
         val moreAccountsAvailable = userManager.users.blockingGet().size > 1
@@ -385,24 +395,19 @@ class ConversationsListController(bundle: Bundle) :
             hideSearchBar()
             actionBar?.setTitle(R.string.nc_forward_to_three_dots)
         } else {
-            val activity = activity as MainActivity?
             searchItem!!.isVisible = conversationItems.size > 0
-            if (activity != null) {
-                if (adapter!!.hasFilter()) {
-                    showSearchView(activity, searchView, searchItem)
-                    searchView!!.setQuery(adapter!!.getFilter(String::class.java), false)
-                }
-                activity.binding.searchText.setOnClickListener {
-                    showSearchView(activity, searchView, searchItem)
-                    viewThemeUtils.platform.themeStatusBar(activity, searchView!!)
-                }
+            if (adapter!!.hasFilter()) {
+                showSearchView(searchView, searchItem)
+                searchView!!.setQuery(adapter!!.getFilter(String::class.java), false)
+            }
+            binding.searchText.setOnClickListener {
+                showSearchView(searchView, searchItem)
+                viewThemeUtils.platform.themeStatusBar(this, searchView!!)
             }
             searchView!!.setOnCloseListener {
                 if (TextUtils.isEmpty(searchView!!.query.toString())) {
                     searchView!!.onActionViewCollapsed()
-                    if (activity != null) {
-                        viewThemeUtils.platform.resetStatusBar(activity)
-                    }
+                    viewThemeUtils.platform.resetStatusBar(this)
                 } else {
                     searchView!!.post { searchView!!.setQuery(TAG, true) }
                 }
@@ -428,48 +433,118 @@ class ConversationsListController(bundle: Bundle) :
                     }
                     binding?.swipeRefreshLayoutView?.isEnabled = true
                     searchView!!.onActionViewCollapsed()
-                    val mainActivity = getActivity() as MainActivity?
-                    if (mainActivity != null) {
-                        mainActivity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
-                            mainActivity.binding.appBar.context,
-                            R.animator.appbar_elevation_off
-                        )
-                        mainActivity.binding.toolbar.visibility = View.GONE
-                        mainActivity.binding.searchToolbar.visibility = View.VISIBLE
-                        if (resources != null) {
-                            viewThemeUtils.platform
-                                .resetStatusBar(mainActivity)
-                        }
+
+                    binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+                        binding.conversationListAppbar.context,
+                        R.animator.appbar_elevation_off
+                    )
+                    binding.conversationListToolbar.visibility = View.GONE
+                    binding.searchToolbar.visibility = View.VISIBLE
+                    if (resources != null) {
+                        viewThemeUtils.platform.resetStatusBar(this@ConversationsListActivity)
                     }
+
                     val layoutManager = binding?.recyclerView?.layoutManager as SmoothScrollLinearLayoutManager?
                     layoutManager?.scrollToPositionWithOffset(0, 0)
                     return true
                 }
             })
         }
+        return true
     }
 
-    private fun hasActivityActionSendIntent(): Boolean {
-        return if (activity != null) {
-            Intent.ACTION_SEND == activity!!.intent.action || Intent.ACTION_SEND_MULTIPLE == activity!!.intent.action
-        } else {
-            false
+    private fun showSearchOrToolbar() {
+        if (TextUtils.isEmpty(searchQuery)) {
+            val showSearchBar = appBarLayoutType == AppBarLayoutType.SEARCH_BAR
+
+            if (appBarLayoutType == AppBarLayoutType.EMPTY) {
+                hideBars()
+            } else {
+                if (showSearchBar) {
+                    showSearchBar()
+                } else {
+                    showToolbar()
+                }
+                colorizeStatusBar(showSearchBar, this, resources)
+            }
+            colorizeNavigationBar(this, resources)
         }
     }
 
-    override fun showSearchOrToolbar() {
-        if (TextUtils.isEmpty(searchQuery)) {
-            super.showSearchOrToolbar()
+    private fun showSearchBar() {
+        val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+        binding.searchToolbar.visibility = View.VISIBLE
+        binding.searchText.hint = getString(R.string.appbar_search_in, getString(R.string.nc_app_product_name))
+        binding.conversationListToolbar.visibility = View.GONE
+        // layoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout
+        // .LayoutParams.SCROLL_FLAG_SNAP | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
+        layoutParams.scrollFlags = 0
+        binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+            binding.conversationListAppbar.context,
+            R.animator.appbar_elevation_off
+        )
+        binding.searchToolbar.layoutParams = layoutParams
+    }
+
+    private fun showToolbar() {
+        val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+        binding.searchToolbar.visibility = View.GONE
+        binding.searchToolbar.visibility = View.VISIBLE
+        viewThemeUtils.material.colorToolbarOverflowIcon(binding.conversationListToolbar)
+        layoutParams.scrollFlags = 0
+        binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+            binding.conversationListAppbar.context,
+            R.animator.appbar_elevation_on
+        )
+        binding.conversationListToolbar.layoutParams = layoutParams
+    }
+
+    private fun hideBars() {
+        binding.conversationListToolbar.visibility = View.GONE
+        binding.searchToolbar.visibility = View.GONE
+    }
+
+    private fun hideSearchBar() {
+        val layoutParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
+        binding.searchToolbar.visibility = View.GONE
+        binding.conversationListToolbar.visibility = View.VISIBLE
+        layoutParams.scrollFlags = 0
+        binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+            binding.conversationListAppbar.context,
+            R.animator.appbar_elevation_on
+        )
+    }
+
+    private fun colorizeStatusBar(showSearchBar: Boolean, activity: Activity?, resources: Resources?) {
+        if (activity != null && resources != null) {
+            if (showSearchBar) {
+                viewThemeUtils.platform.resetStatusBar(activity)
+            } else {
+                viewThemeUtils.platform.themeStatusBar(activity, binding.root)
+            }
         }
     }
 
-    private fun showSearchView(activity: MainActivity, searchView: SearchView?, searchItem: MenuItem?) {
-        activity.binding.appBar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
-            activity.binding.appBar.context,
+    private fun colorizeNavigationBar(activity: Activity?, resources: Resources?) {
+        if (activity != null && resources != null) {
+            DisplayUtils.applyColorToNavigationBar(
+                activity.window,
+                ResourcesCompat.getColor(resources, R.color.bg_default, null)
+            )
+        }
+    }
+
+    private fun hasActivityActionSendIntent(): Boolean {
+        return Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action
+    }
+
+    private fun showSearchView(searchView: SearchView?, searchItem: MenuItem?) {
+        binding.conversationListAppbar.stateListAnimator = AnimatorInflater.loadStateListAnimator(
+            binding.conversationListAppbar.context,
             R.animator.appbar_elevation_on
         )
-        activity.binding.toolbar.visibility = View.VISIBLE
-        activity.binding.searchToolbar.visibility = View.GONE
+        binding.conversationListToolbar.visibility = View.VISIBLE
+        binding.searchToolbar.visibility = View.GONE
         searchItem!!.expandActionView()
     }
 
@@ -499,10 +574,11 @@ class ConversationsListController(bundle: Bundle) :
                 // This is invoked asynchronously, when server returns a response the view might have been
                 // unbound in the meantime. Check if the view is still there.
                 // FIXME - does it make sense to update internal data structures even when view has been unbound?
-                if (view == null) {
-                    Log.d(TAG, "fetchData - getRooms - view is not bound: $startNanoTime")
-                    return@subscribe
-                }
+                // if (view == null) {
+                //     Log.d(TAG, "fetchData - getRooms - view is not bound: $startNanoTime")
+                //     return@subscribe
+                // }
+
                 if (adapterWasNull) {
                     adapterWasNull = false
                     binding?.loadingContent?.visibility = View.GONE
@@ -548,8 +624,8 @@ class ConversationsListController(bundle: Bundle) :
     }
 
     private fun addToConversationItems(conversation: Conversation) {
-        if (bundle.containsKey(KEY_FORWARD_HIDE_SOURCE_ROOM) && conversation.roomId ==
-            bundle.getString(KEY_FORWARD_HIDE_SOURCE_ROOM)
+        if (intent.getStringExtra(KEY_FORWARD_HIDE_SOURCE_ROOM) != null &&
+            intent.getStringExtra(KEY_FORWARD_HIDE_SOURCE_ROOM) == conversation.roomId
         ) {
             return
         }
@@ -566,23 +642,22 @@ class ConversationsListController(bundle: Bundle) :
             genericTextHeaderItem = GenericTextHeaderItem(headerTitle, viewThemeUtils)
             callHeaderItems[headerTitle] = genericTextHeaderItem
         }
-        if (activity != null) {
-            val conversationItem = ConversationItem(
-                conversation,
-                currentUser!!,
-                activity!!,
-                viewThemeUtils
-            )
-            conversationItems.add(conversationItem)
-            val conversationItemWithHeader = ConversationItem(
-                conversation,
-                currentUser!!,
-                activity!!,
-                callHeaderItems[headerTitle],
-                viewThemeUtils
-            )
-            conversationItemsWithHeader.add(conversationItemWithHeader)
-        }
+
+        val conversationItem = ConversationItem(
+            conversation,
+            currentUser!!,
+            this,
+            viewThemeUtils
+        )
+        conversationItems.add(conversationItem)
+        val conversationItemWithHeader = ConversationItem(
+            conversation,
+            currentUser!!,
+            this,
+            callHeaderItems[headerTitle],
+            viewThemeUtils
+        )
+        conversationItemsWithHeader.add(conversationItemWithHeader)
     }
 
     private fun showErrorDialog() {
@@ -639,7 +714,7 @@ class ConversationsListController(bundle: Bundle) :
                         val conversationItem = ConversationItem(
                             conversation,
                             currentUser!!,
-                            activity!!,
+                            this,
                             callHeaderItems[headerTitle],
                             viewThemeUtils
                         )
@@ -659,30 +734,18 @@ class ConversationsListController(bundle: Bundle) :
     private fun handleHttpExceptions(throwable: Throwable) {
         if (throwable is HttpException) {
             when (throwable.code()) {
-                HTTP_UNAUTHORIZED -> if (parentController != null && parentController!!.router != null) {
-                    Log.d(TAG, "Starting reauth webview via getParentController()")
-                    parentController!!.router.pushController(
-                        RouterTransaction.with(
-                            WebViewLoginController(
-                                currentUser!!.baseUrl,
-                                true
-                            )
-                        )
-                            .pushChangeHandler(VerticalChangeHandler())
-                            .popChangeHandler(VerticalChangeHandler())
-                    )
-                } else {
-                    Log.d(TAG, "Starting reauth webview via ConversationsListController")
-                    showUnauthorizedDialog()
+                HTTP_UNAUTHORIZED -> showUnauthorizedDialog()
+                else -> {
+                    Log.e(TAG, "Http exception in ConversationListActivity", throwable)
+                    Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
                 }
-                else -> {}
             }
         }
     }
 
     @SuppressLint("ClickableViewAccessibility")
     private fun prepareViews() {
-        layoutManager = SmoothScrollLinearLayoutManager(Objects.requireNonNull(activity))
+        layoutManager = SmoothScrollLinearLayoutManager(this)
         binding?.recyclerView?.layoutManager = layoutManager
         binding?.recyclerView?.setHasFixedSize(true)
         binding?.recyclerView?.adapter = adapter
@@ -695,8 +758,8 @@ class ConversationsListController(bundle: Bundle) :
             }
         })
         binding?.recyclerView?.setOnTouchListener { v: View, _: MotionEvent? ->
-            if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
-                val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+            if (!isDestroyed) {
+                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                 imm.hideSoftInputFromWindow(v.windowToken, 0)
             }
             false
@@ -709,21 +772,17 @@ class ConversationsListController(bundle: Bundle) :
             showNewConversationsScreen()
         }
         binding?.floatingActionButton?.let { viewThemeUtils.material.themeFAB(it) }
-        if (activity != null && activity is MainActivity) {
-            val activity = activity as MainActivity?
-            activity!!.binding.switchAccountButton.setOnClickListener {
-                if (resources != null && resources!!.getBoolean(R.bool.multiaccount_support)) {
-                    val newFragment: DialogFragment = ChooseAccountDialogFragment.newInstance()
-                    newFragment.show(
-                        (getActivity() as MainActivity?)!!.supportFragmentManager,
-                        ChooseAccountDialogFragment.TAG
-                    )
-                } else {
-                    val intent = Intent(context, SettingsActivity::class.java)
-                    startActivity(intent)
-                }
+
+        binding.switchAccountButton.setOnClickListener {
+            if (resources != null && resources!!.getBoolean(R.bool.multiaccount_support)) {
+                val newFragment: DialogFragment = ChooseAccountDialogFragment.newInstance()
+                newFragment.show(supportFragmentManager, ChooseAccountDialogFragment.TAG)
+            } else {
+                val intent = Intent(context, SettingsActivity::class.java)
+                startActivity(intent)
             }
         }
+
         binding?.newMentionPopupBubble?.hide()
         binding?.newMentionPopupBubble?.setPopupBubbleListener {
             binding?.recyclerView?.smoothScrollToPosition(
@@ -786,17 +845,19 @@ class ConversationsListController(bundle: Bundle) :
         }
     }
 
-    public override fun onSaveViewState(view: View, outState: Bundle) {
+    override fun onSaveInstanceState(bundle: Bundle) {
+        super.onSaveInstanceState(bundle)
+
         if (searchView != null && !TextUtils.isEmpty(searchView!!.query)) {
-            outState.putString(KEY_SEARCH_QUERY, searchView!!.query.toString())
+            bundle.putString(KEY_SEARCH_QUERY, searchView!!.query.toString())
         }
-        super.onSaveViewState(view, outState)
     }
 
-    public override fun onRestoreViewState(view: View, savedViewState: Bundle) {
-        super.onRestoreViewState(view, savedViewState)
-        if (savedViewState.containsKey(KEY_SEARCH_QUERY)) {
-            searchQuery = savedViewState.getString(KEY_SEARCH_QUERY, "")
+    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
+        super.onRestoreInstanceState(savedInstanceState)
+
+        if (savedInstanceState.containsKey(KEY_SEARCH_QUERY)) {
+            searchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY, "")
         }
     }
 
@@ -906,7 +967,7 @@ class ConversationsListController(bundle: Bundle) :
     @Suppress("Detekt.ComplexMethod")
     private fun handleConversation(conversation: Conversation?) {
         selectedConversation = conversation
-        if (selectedConversation != null && activity != null) {
+        if (selectedConversation != null) {
             val hasChatPermission = ParticipantPermissions(currentUser!!, selectedConversation!!).hasChatPermission()
             if (showShareToScreen) {
                 if (hasChatPermission &&
@@ -919,7 +980,7 @@ class ConversationsListController(bundle: Bundle) :
                 }
             } else if (forwardMessage) {
                 if (hasChatPermission && !isReadOnlyConversation(selectedConversation!!)) {
-                    openConversation(bundle.getString(KEY_FORWARD_MSG_TEXT))
+                    openConversation(intent.getStringExtra(KEY_FORWARD_MSG_TEXT))
                     forwardMessage = false
                 } else {
                     Toast.makeText(context, R.string.send_to_forbidden, Toast.LENGTH_LONG).show()
@@ -1001,7 +1062,7 @@ class ConversationsListController(bundle: Bundle) :
     }
 
     private fun clearIntentAction() {
-        activity!!.intent.action = ""
+        intent.action = ""
     }
 
     override fun onItemLongClick(position: Int) {
@@ -1012,7 +1073,7 @@ class ConversationsListController(bundle: Bundle) :
             if (clickedItem != null) {
                 val conversation = (clickedItem as ConversationItem).model
                 conversationsListBottomDialog = ConversationsListBottomDialog(
-                    activity!!,
+                    this,
                     this,
                     userManager.currentUser.blockingGet(),
                     conversation
@@ -1025,8 +1086,7 @@ class ConversationsListController(bundle: Bundle) :
     @Suppress("Detekt.TooGenericExceptionCaught")
     private fun collectDataFromIntent() {
         filesToShare = ArrayList()
-        if (activity != null && activity!!.intent != null) {
-            val intent = activity!!.intent
+        if (intent != null) {
             if (Intent.ACTION_SEND == intent.action || Intent.ACTION_SEND_MULTIPLE == intent.action) {
                 try {
                     val mimeType = intent.type
@@ -1099,6 +1159,7 @@ class ConversationsListController(bundle: Bundle) :
     }
 
     override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
         if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION &&
             grantResults.isNotEmpty() &&
             grantResults[0] == PackageManager.PERMISSION_GRANTED
@@ -1132,13 +1193,6 @@ class ConversationsListController(bundle: Bundle) :
             bundle.putString(BundleKeys.KEY_MESSAGE_ID, selectedMessageId)
             selectedMessageId = null
         }
-        // remapChatController(
-        //     router,
-        //     currentUser!!.id!!,
-        //     selectedConversation!!.token!!,
-        //     bundle,
-        //     false
-        // )
 
         val intent = Intent(context, ChatActivity::class.java)
         intent.putExtras(bundle)
@@ -1171,8 +1225,7 @@ class ConversationsListController(bundle: Bundle) :
 
     override fun showDeleteConversationDialog(bundle: Bundle) {
         conversationMenuBundle = bundle
-        if (activity != null &&
-            conversationMenuBundle != null &&
+        if (conversationMenuBundle != null &&
             isInternalUserEqualsCurrentUser(currentUser, conversationMenuBundle)
         ) {
             val conversation = Parcels.unwrap<Conversation>(conversationMenuBundle!!.getParcelable(KEY_ROOM))
@@ -1216,53 +1269,47 @@ class ConversationsListController(bundle: Bundle) :
     }
 
     private fun showUnauthorizedDialog() {
-        if (activity != null) {
-            binding?.floatingActionButton?.let {
-                val dialogBuilder = MaterialAlertDialogBuilder(it.context)
-                    .setIcon(
-                        viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
-                            context,
-                            R.drawable.ic_delete_black_24dp
-                        )
+        binding?.floatingActionButton?.let {
+            val dialogBuilder = MaterialAlertDialogBuilder(it.context)
+                .setIcon(
+                    viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
+                        context,
+                        R.drawable.ic_delete_black_24dp
                     )
-                    .setTitle(R.string.nc_dialog_invalid_password)
-                    .setMessage(R.string.nc_dialog_reauth_or_delete)
-                    .setCancelable(false)
-                    .setPositiveButton(R.string.nc_delete) { _, _ ->
-                        val otherUserExists = userManager
-                            .scheduleUserForDeletionWithId(currentUser!!.id!!)
-                            .blockingGet()
-                        val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
-                        WorkManager.getInstance().enqueue(accountRemovalWork)
-                        if (otherUserExists && view != null) {
-                            onViewBound(view!!)
-                            onAttach(view!!)
-                        } else if (!otherUserExists) {
-                            router.setRoot(
-                                RouterTransaction.with(ServerSelectionController())
-                                    .pushChangeHandler(VerticalChangeHandler())
-                                    .popChangeHandler(VerticalChangeHandler())
-                            )
-                        }
-                    }
-                    .setNegativeButton(R.string.nc_settings_reauthorize) { _, _ ->
-                        router.pushController(
-                            RouterTransaction.with(
-                                WebViewLoginController(currentUser!!.baseUrl, true)
-                            )
-                                .pushChangeHandler(VerticalChangeHandler())
-                                .popChangeHandler(VerticalChangeHandler())
-                        )
+                )
+                .setTitle(R.string.nc_dialog_invalid_password)
+                .setMessage(R.string.nc_dialog_reauth_or_delete)
+                .setCancelable(false)
+                .setPositiveButton(R.string.nc_delete) { _, _ ->
+                    val otherUserExists = userManager
+                        .scheduleUserForDeletionWithId(currentUser!!.id!!)
+                        .blockingGet()
+                    val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
+                    WorkManager.getInstance().enqueue(accountRemovalWork)
+                    if (otherUserExists) {
+                        finish()
+                        startActivity(intent)
+                    } else if (!otherUserExists) {
+                        Log.d(TAG, "No other users found. AccountRemovalWorker will restart the app.")
                     }
+                }
+                .setNegativeButton(R.string.nc_settings_reauthorize) { _, _ ->
+                    // TODO
+                    // router.pushController(
+                    //     RouterTransaction.with(
+                    //         WebViewLoginController(currentUser!!.baseUrl, true)
+                    //     )
+                    //         .pushChangeHandler(VerticalChangeHandler())
+                    //         .popChangeHandler(VerticalChangeHandler())
+                    // )
+                }
 
-                viewThemeUtils.dialog
-                    .colorMaterialAlertDialogBackground(it.context, dialogBuilder)
-                val dialog = dialogBuilder.show()
-                viewThemeUtils.platform.colorTextButtons(
-                    dialog.getButton(AlertDialog.BUTTON_POSITIVE),
-                    dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
-                )
-            }
+            viewThemeUtils.dialog.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
+            val dialog = dialogBuilder.show()
+            viewThemeUtils.platform.colorTextButtons(
+                dialog.getButton(AlertDialog.BUTTON_POSITIVE),
+                dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+            )
         }
     }
 
@@ -1279,25 +1326,20 @@ class ConversationsListController(bundle: Bundle) :
                         .blockingGet()
                     val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
                     WorkManager.getInstance().enqueue(accountRemovalWork)
-                    if (otherUserExists && view != null) {
-                        onViewBound(view!!)
-                        onAttach(view!!)
+                    if (otherUserExists) {
+                        finish()
+                        startActivity(intent)
                     } else if (!otherUserExists) {
-                        router.setRoot(
-                            RouterTransaction.with(
-                                ServerSelectionController()
-                            )
-                                .pushChangeHandler(VerticalChangeHandler())
-                                .popChangeHandler(VerticalChangeHandler())
-                        )
+                        restartApp(this)
                     }
                 }
                 .setNegativeButton(R.string.nc_cancel) { _, _ ->
                     if (userManager.users.blockingGet().isNotEmpty()) {
-                        router.pushController(RouterTransaction.with(SwitchAccountController()))
+                        // TODO
+                        // router.pushController(RouterTransaction.with(SwitchAccountController()))
                     } else {
-                        activity!!.finishAffinity()
-                        activity!!.finish()
+                        finishAffinity()
+                        finish()
                     }
                 }
 
@@ -1310,6 +1352,15 @@ class ConversationsListController(bundle: Bundle) :
         }
     }
 
+    fun restartApp(context: Context) {
+        val packageManager = context.packageManager
+        val intent = packageManager.getLaunchIntentForPackage(context.packageName)
+        val componentName = intent!!.component
+        val mainIntent = Intent.makeRestartActivityTask(componentName)
+        context.startActivity(mainIntent)
+        Runtime.getRuntime().exit(0)
+    }
+
     private fun deleteConversation(data: Data) {
         val deleteConversationWorker =
             OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data).build()
@@ -1351,6 +1402,13 @@ class ConversationsListController(bundle: Bundle) :
         showErrorDialog()
     }
 
+    override fun onBackPressed() {
+        super.onBackPressed()
+
+        // TODO: replace this when conductor is removed. For now it avoids to load the MainActiviy which has no UI.
+        finishAffinity()
+    }
+
     companion object {
         const val TAG = "ConvListController"
         const val UNREAD_BUBBLE_DELAY = 2500
@@ -1360,10 +1418,4 @@ class ConversationsListController(bundle: Bundle) :
         const val SEARCH_MIN_CHARS = 2
         const val HTTP_UNAUTHORIZED = 401
     }
-
-    init {
-        setHasOptionsMenu(true)
-        forwardMessage = bundle.getBoolean(KEY_FORWARD_MSG_FLAG)
-        this.bundle = bundle
-    }
 }

+ 2 - 2
app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt

@@ -38,7 +38,7 @@ import com.nextcloud.talk.activities.BaseActivity
 import com.nextcloud.talk.adapters.items.LoadMoreResultsItem
 import com.nextcloud.talk.adapters.items.MessageResultItem
 import com.nextcloud.talk.application.NextcloudTalkApplication
-import com.nextcloud.talk.controllers.ConversationsListController
+import com.nextcloud.talk.conversationlist.ConversationsListActivity
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ActivityMessageSearchBinding
 import com.nextcloud.talk.utils.DisplayUtils
@@ -241,7 +241,7 @@ class MessageSearchActivity : BaseActivity() {
                 when {
                     TextUtils.isEmpty(query) -> Observable.empty()
                     else -> Observable.timer(
-                        ConversationsListController.SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
+                        ConversationsListActivity.SEARCH_DEBOUNCE_INTERVAL_MS.toLong(),
                         TimeUnit.MILLISECONDS
                     )
                 }

+ 23 - 15
app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java

@@ -26,6 +26,7 @@ package com.nextcloud.talk.ui.dialog;
 
 import android.annotation.SuppressLint;
 import android.app.Dialog;
+import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
@@ -34,16 +35,17 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.nextcloud.talk.activities.MainActivity;
 import com.nextcloud.talk.adapters.items.AdvancedUserItem;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.conversationlist.ConversationsListActivity;
 import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.databinding.DialogChooseAccountBinding;
 import com.nextcloud.talk.extensions.ImageViewExtensionsKt;
 import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.models.json.status.Status;
 import com.nextcloud.talk.models.json.status.StatusOverall;
+import com.nextcloud.talk.settings.SettingsActivity;
 import com.nextcloud.talk.ui.StatusDrawable;
 import com.nextcloud.talk.ui.theme.ViewThemeUtils;
 import com.nextcloud.talk.users.UserManager;
@@ -178,16 +180,18 @@ public class ChooseAccountDialogFragment extends DialogFragment {
         // Creating listeners for quick-actions
         binding.currentAccount.getRoot().setOnClickListener(v -> dismiss());
 
-        if (getActivity() instanceof MainActivity) {
-            binding.addAccount.setOnClickListener(v -> {
-                dismiss();
-                ((MainActivity) getActivity()).addAccount();
-            });
-            binding.manageSettings.setOnClickListener(v -> {
-                dismiss();
-                ((MainActivity) getActivity()).openSettings();
-            });
-        }
+
+        binding.addAccount.setOnClickListener(v -> {
+            dismiss();
+            // TODO
+//            ((MainActivity) getActivity()).addAccount();
+        });
+        binding.manageSettings.setOnClickListener(v -> {
+            Intent intent = new Intent(getContext(), SettingsActivity.class);
+            startActivity(intent);
+            dismiss();
+        });
+
 
         binding.setStatus.setOnClickListener(v -> {
             dismiss();
@@ -294,10 +298,14 @@ public class ChooseAccountDialogFragment extends DialogFragment {
 
                     if (userManager.setUserAsActive(user).blockingGet()) {
                         cookieManager.getCookieStore().removeAll();
-                        if (getActivity() != null) {
-                            getActivity().runOnUiThread(
-                                () -> ((MainActivity) getActivity()).resetConversationsList());
-                        }
+
+                        Intent intent = new Intent(getContext(), ConversationsListActivity.class);
+                        // TODO: might be better with FLAG_ACTIVITY_SINGLE_TOP instead than FLAG_ACTIVITY_CLEAR_TOP to
+                        // have a smoother transition. However the handling in onNewIntent() in
+                        // ConversationListActivity must be improved for this.
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                        startActivity(intent);
+
                         dismiss();
                     }
                 }

+ 2 - 2
app/src/main/java/com/nextcloud/talk/ui/dialog/ConversationsListBottomDialog.kt

@@ -38,7 +38,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
 import com.nextcloud.talk.R
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
-import com.nextcloud.talk.controllers.ConversationsListController
 import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum
 import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_ADD_FAVORITE
 import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_MARK_AS_READ
@@ -47,6 +46,7 @@ import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_
 import com.nextcloud.talk.controllers.bottomsheet.ConversationOperationEnum.OPS_CODE_RENAME_ROOM
 import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
 import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController
+import com.nextcloud.talk.conversationlist.ConversationsListActivity
 import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.DialogConversationOperationsBinding
 import com.nextcloud.talk.jobs.LeaveConversationWorker
@@ -64,7 +64,7 @@ import javax.inject.Inject
 @AutoInjector(NextcloudTalkApplication::class)
 class ConversationsListBottomDialog(
     val activity: Activity,
-    val controller: ConversationsListController,
+    val controller: ConversationsListActivity,
     val currentUser: User,
     val conversation: Conversation
 ) : BottomSheetDialog(activity) {

+ 0 - 80
app/src/main/res/layout/activity_main.xml

@@ -40,87 +40,7 @@
         android:windowContentOverlay="@null"
         app:elevation="0dp">
 
-        <com.google.android.material.card.MaterialCardView
-            android:id="@+id/search_toolbar"
-            android:layout_width="match_parent"
-            android:layout_height="50dp"
-            android:layout_marginStart="16dp"
-            android:layout_marginTop="5dp"
-            android:layout_marginEnd="16dp"
-            android:layout_marginBottom="1dp"
-            android:visibility="gone"
-            app:cardCornerRadius="25dp"
-            app:cardElevation="2dp"
-            app:strokeWidth="0dp"
-            tools:visibility="visible">
-
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/menu_button"
-                    style="@style/Widget.AppTheme.Button.IconButton"
-                    android:layout_width="3dp"
-                    android:layout_height="1dp"
-                    android:layout_marginStart="5dp"
-                    android:contentDescription="@string/nc_action_open_main_menu"
-                    android:visibility="gone"
-                    app:cornerRadius="@dimen/button_corner_radius"
-                    app:icon="@drawable/ic_menu"
-                    app:iconTint="@color/fontAppbar"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-
-                <com.google.android.material.textview.MaterialTextView
-                    android:id="@+id/search_text"
-                    android:layout_width="0dp"
-                    android:layout_height="48dp"
-                    android:layout_marginStart="20dp"
-                    android:layout_marginEnd="18dp"
-                    android:ellipsize="end"
-                    android:gravity="start|center_vertical"
-                    android:lines="1"
-                    android:textAlignment="viewStart"
-                    android:textColor="@color/fontSecondaryAppbar"
-                    android:textSize="16sp"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintStart_toEndOf="@id/menu_button"
-                    app:layout_constraintEnd_toStartOf="@id/rightContainer"
-                    app:layout_constraintTop_toTopOf="parent"
-                    tools:text="Search in Nextcloud" />
-
-                <FrameLayout
-                    android:id="@+id/rightContainer"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:layout_alignParentEnd="true"
-                    android:minWidth="48dp"
-                    android:layout_centerVertical="true"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintTop_toTopOf="parent">
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/switch_account_button"
-                        style="@style/Widget.AppTheme.Button.IconButton"
-                        android:layout_width="48dp"
-                        android:layout_height="48dp"
-                        android:layout_gravity="center"
-                        android:contentDescription="@string/nc_settings"
-                        android:scaleType="fitCenter"
-                        android:transitionName="userAvatar.transitionTag"
-                        app:cornerRadius="@dimen/button_corner_radius"
-                        app:iconSize="@dimen/avatar_size_app_bar"
-                        app:iconTint="@null"
-                        tools:icon="@drawable/ic_user" />
-
-                </FrameLayout>
-
-            </androidx.constraintlayout.widget.ConstraintLayout>
 
-        </com.google.android.material.card.MaterialCardView>
 
         <com.google.android.material.appbar.MaterialToolbar
             android:id="@+id/toolbar"

+ 108 - 1
app/src/main/res/layout/controller_conversations_rv.xml

@@ -25,11 +25,118 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/conversation_list_appbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/bg_default"
+        android:elevation="0dp"
+        android:clipChildren="true"
+        android:clipToPadding="false"
+        android:windowContentOverlay="@null"
+        app:elevation="0dp">
+
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/search_toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="5dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginBottom="1dp"
+            android:visibility="gone"
+            app:cardCornerRadius="25dp"
+            app:cardElevation="2dp"
+            app:strokeWidth="0dp"
+            tools:visibility="visible">
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <com.google.android.material.button.MaterialButton
+                    android:id="@+id/menu_button"
+                    style="@style/Widget.AppTheme.Button.IconButton"
+                    android:layout_width="3dp"
+                    android:layout_height="1dp"
+                    android:layout_marginStart="5dp"
+                    android:contentDescription="@string/nc_action_open_main_menu"
+                    android:visibility="gone"
+                    app:cornerRadius="@dimen/button_corner_radius"
+                    app:icon="@drawable/ic_menu"
+                    app:iconTint="@color/fontAppbar"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+                <com.google.android.material.textview.MaterialTextView
+                    android:id="@+id/search_text"
+                    android:layout_width="0dp"
+                    android:layout_height="48dp"
+                    android:layout_marginStart="20dp"
+                    android:layout_marginEnd="18dp"
+                    android:ellipsize="end"
+                    android:gravity="start|center_vertical"
+                    android:lines="1"
+                    android:textAlignment="viewStart"
+                    android:textColor="@color/fontSecondaryAppbar"
+                    android:textSize="16sp"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintStart_toEndOf="@id/menu_button"
+                    app:layout_constraintEnd_toStartOf="@id/rightContainer"
+                    app:layout_constraintTop_toTopOf="parent"
+                    tools:text="Search in Nextcloud" />
+
+                <FrameLayout
+                    android:id="@+id/rightContainer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_alignParentEnd="true"
+                    android:minWidth="48dp"
+                    android:layout_centerVertical="true"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintTop_toTopOf="parent">
+
+                    <com.google.android.material.button.MaterialButton
+                        android:id="@+id/switch_account_button"
+                        style="@style/Widget.AppTheme.Button.IconButton"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:layout_gravity="center"
+                        android:contentDescription="@string/nc_settings"
+                        android:scaleType="fitCenter"
+                        android:transitionName="userAvatar.transitionTag"
+                        app:cornerRadius="@dimen/button_corner_radius"
+                        app:iconSize="@dimen/avatar_size_app_bar"
+                        app:iconTint="@null"
+                        tools:icon="@drawable/ic_user" />
+
+                </FrameLayout>
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+        </com.google.android.material.card.MaterialCardView>
+
+        <com.google.android.material.appbar.MaterialToolbar
+            android:id="@+id/conversation_list_toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"
+            android:background="@color/appbar"
+            android:theme="?attr/actionBarPopupTheme"
+            app:layout_scrollFlags="enterAlwaysCollapsed|noScroll"
+            app:navigationIconTint="@color/fontAppbar"
+            app:popupTheme="@style/appActionBarPopupMenu"
+            app:titleTextColor="@color/fontAppbar"
+            tools:title="@string/nc_app_product_name" />
+    </com.google.android.material.appbar.AppBarLayout>
+
     <LinearLayout
         android:id="@+id/loading_content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical">
+        android:orientation="vertical"
+        android:layout_marginTop="50dp">
 
         <include layout="@layout/rv_item_conversation_with_last_message_shimmer" />