From 06002bb7f982accf33086af6f0b5b2081f6cc3d8 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 29 Mar 2018 00:00:05 +0200
Subject: [PATCH] Improved info UI

---
 app/src/main/AndroidManifest.xml              |  2 +-
 .../quasseldroid/dagger/ActivityModule.kt     |  5 +-
 .../quasseldroid/ui/chat/ChatActivity.kt      |  7 --
 .../quasseldroid/ui/chat/ToolbarFragment.kt   | 16 +----
 .../chat/buffers/BufferViewConfigFragment.kt  | 10 ---
 .../quasseldroid/ui/chat/info/InfoActivity.kt |  5 ++
 .../ui/chat/{detailinfo => info}/InfoData.kt  |  2 +-
 .../{detailinfo => info}/InfoDescriptor.kt    |  2 +-
 .../InfoActivity.kt => info/InfoFragment.kt}  | 45 +++++-------
 .../ui/chat/info/InfoFragmentProvider.kt      | 10 +++
 .../{detailinfo => info}/InfoGroupAdapter.kt  | 12 ++--
 .../InfoPropertyAdapter.kt                    | 11 +--
 .../ui/chat/{detailinfo => info}/InfoType.kt  |  2 +-
 .../ui/chat/messages/MessageListFragment.kt   |  9 ---
 .../ui/chat/nicks/NickListFragment.kt         | 16 +----
 .../ui/settings/SettingsActivity.kt           |  2 +
 .../license/LicenseSettingsActivity.kt        | 16 +----
 .../selection/AccountSelectionSlide.kt        |  4 +-
 .../util/service/ServiceBoundActivity.kt      |  7 ++
 .../util/service/ServiceBoundFragment.kt      |  9 +++
 app/src/main/res/layout/activity_info.xml     | 38 ----------
 app/src/main/res/layout/fragment_info.xml     |  8 +++
 app/src/main/res/layout/widget_userinfo.xml   | 71 ++++++++++++-------
 .../main/res/layout/widget_userinfo_group.xml | 66 ++++++-----------
 .../quasseldroid/viewmodel/data/InfoGroup.kt  |  2 +-
 25 files changed, 155 insertions(+), 222 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo => info}/InfoData.kt (88%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo => info}/InfoDescriptor.kt (77%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo/InfoActivity.kt => info/InfoFragment.kt} (72%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo => info}/InfoGroupAdapter.kt (88%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo => info}/InfoPropertyAdapter.kt (88%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/chat/{detailinfo => info}/InfoType.kt (50%)
 delete mode 100644 app/src/main/res/layout/activity_info.xml
 create mode 100644 app/src/main/res/layout/fragment_info.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 25f0a27b9..f4689def0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,7 +34,7 @@
       </intent-filter>
     </activity>
     <activity
-      android:name=".ui.chat.detailinfo.InfoActivity"
+      android:name=".ui.chat.info.InfoActivity"
       android:exported="false"
       android:label="@string/label_details"
       android:parentActivityName=".ui.chat.ChatActivity"
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
index 5725f88fb..e85d1de4a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
@@ -6,7 +6,8 @@ import de.kuschku.quasseldroid.service.QuasselService
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.ui.chat.ChatActivityModule
 import de.kuschku.quasseldroid.ui.chat.ChatFragmentProvider
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoActivity
+import de.kuschku.quasseldroid.ui.chat.info.InfoActivity
+import de.kuschku.quasseldroid.ui.chat.info.InfoFragmentProvider
 import de.kuschku.quasseldroid.ui.settings.about.AboutSettingsActivity
 import de.kuschku.quasseldroid.ui.settings.about.AboutSettingsFragmentProvider
 import de.kuschku.quasseldroid.ui.settings.app.AppSettingsActivity
@@ -26,7 +27,7 @@ abstract class ActivityModule {
   @ContributesAndroidInjector(modules = [ChatActivityModule::class, ChatFragmentProvider::class])
   abstract fun bindChatActivity(): ChatActivity
 
-  @ContributesAndroidInjector
+  @ContributesAndroidInjector(modules = [InfoFragmentProvider::class])
   abstract fun bindInfoActivity(): InfoActivity
 
   @ContributesAndroidInjector(modules = [AppSettingsFragmentProvider::class])
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 c4d4496ac..9a7e2e178 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
@@ -2,7 +2,6 @@ package de.kuschku.quasseldroid.ui.chat
 
 import android.annotation.TargetApi
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
 import android.content.Context
 import android.content.Intent
 import android.content.SharedPreferences
@@ -42,7 +41,6 @@ import de.kuschku.quasseldroid.util.helper.retint
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
 import de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import de.kuschku.quasseldroid.viewmodel.data.AutoCompleteItem
 import javax.inject.Inject
 
@@ -67,8 +65,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
   private lateinit var drawerToggle: ActionBarDrawerToggle
 
-  private lateinit var viewModel: QuasselViewModel
-
   @Inject
   lateinit var database: QuasselDatabase
 
@@ -101,9 +97,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     setContentView(R.layout.activity_main)
     ButterKnife.bind(this)
 
-    viewModel = ViewModelProviders.of(this)[QuasselViewModel::class.java]
-    viewModel.backendWrapper.onNext(this.backend)
-
     editor = Editor(
       this,
       viewModel.autoCompleteData.toLiveData(),
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 f1fc56ed5..02770ad6d 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
@@ -1,8 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat
 
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
-import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import android.view.LayoutInflater
@@ -17,16 +15,15 @@ import de.kuschku.libquassel.util.hasFlag
 import de.kuschku.libquassel.util.helpers.value
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoActivity
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoDescriptor
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoType
+import de.kuschku.quasseldroid.ui.chat.info.InfoActivity
+import de.kuschku.quasseldroid.ui.chat.info.InfoDescriptor
+import de.kuschku.quasseldroid.ui.chat.info.InfoType
 import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.helper.visibleIf
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.util.ui.SpanFormatter
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import javax.inject.Inject
 
 class ToolbarFragment : ServiceBoundFragment() {
@@ -45,8 +42,6 @@ class ToolbarFragment : ServiceBoundFragment() {
   @Inject
   lateinit var appearanceSettings: AppearanceSettings
 
-  private lateinit var viewModel: QuasselViewModel
-
   var title: CharSequence?
     get() = toolbarTitle.text
     set(value) {
@@ -63,11 +58,6 @@ class ToolbarFragment : ServiceBoundFragment() {
       toolbarSubtitle.visibleIf(value?.isNotEmpty() == true)
     }
 
-  override fun onAttach(context: Context?) {
-    super.onAttach(context)
-    viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-  }
-
   override fun onCreateView(
     inflater: LayoutInflater,
     container: ViewGroup?,
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 879f3f25f..6e4aaf735 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
@@ -1,8 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.buffers
 
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
-import android.content.Context
 import android.os.Bundle
 import android.support.v7.widget.*
 import android.view.*
@@ -26,7 +24,6 @@ import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.helper.zip
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import de.kuschku.quasseldroid.viewmodel.data.BufferHiddenState
 import javax.inject.Inject
 
@@ -49,8 +46,6 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
   @Inject
   lateinit var ircFormatDeserializer: IrcFormatDeserializer
 
-  private lateinit var viewModel: QuasselViewModel
-
   private var actionMode: ActionMode? = null
 
   private val actionModeCallback = object : ActionMode.Callback {
@@ -162,11 +157,6 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
 
   private lateinit var listAdapter: BufferListAdapter
 
-  override fun onAttach(context: Context?) {
-    super.onAttach(context)
-    viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-  }
-
   override fun onCreateView(
     inflater: LayoutInflater, container: ViewGroup?,
     savedInstanceState: Bundle?
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt
new file mode 100644
index 000000000..b8bc0e93a
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt
@@ -0,0 +1,5 @@
+package de.kuschku.quasseldroid.ui.chat.info
+
+import de.kuschku.quasseldroid.ui.settings.SettingsActivity
+
+class InfoActivity : SettingsActivity(InfoFragment())
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoData.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoData.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt
index 814e0359b..9781851c6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoData.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 import de.kuschku.libquassel.quassel.syncables.IrcChannel
 import de.kuschku.libquassel.quassel.syncables.IrcUser
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoDescriptor.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt
similarity index 77%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoDescriptor.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt
index 51ac87860..ad5328320 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoDescriptor.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 import java.io.Serializable
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt
similarity index 72%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt
index 60f6ec8a2..38988bc37 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt
@@ -1,54 +1,42 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
 import android.os.Bundle
 import android.support.v7.widget.LinearLayoutManager
 import android.support.v7.widget.RecyclerView
-import android.support.v7.widget.Toolbar
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
 import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.compatibility.LoggingHandler
-import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.irc.format.ContentFormatter
-import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
+import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.viewmodel.data.InfoGroup
 import de.kuschku.quasseldroid.viewmodel.data.InfoProperty
 import io.reactivex.Observable
 import javax.inject.Inject
 
-class InfoActivity : ServiceBoundActivity() {
-  @BindView(R.id.toolbar)
-  lateinit var toolbar: Toolbar
-
+class InfoFragment : ServiceBoundFragment() {
   @BindView(R.id.groups)
   lateinit var groups: RecyclerView
 
   @Inject
   lateinit var contentFormatter: ContentFormatter
 
-  private lateinit var viewModel: QuasselViewModel
-
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-    setContentView(R.layout.activity_info)
-    ButterKnife.bind(this)
-
-    setSupportActionBar(toolbar)
-    supportActionBar?.setDisplayHomeAsUpEnabled(true)
-
-    viewModel = ViewModelProviders.of(this)[QuasselViewModel::class.java]
-    viewModel.backendWrapper.onNext(this.backend)
+  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                            savedInstanceState: Bundle?): View? {
+    val view = inflater.inflate(R.layout.fragment_info, container, false)
+    ButterKnife.bind(this, view)
 
     val adapter = InfoGroupAdapter()
-    groups.layoutManager = LinearLayoutManager(this)
+    groups.layoutManager = LinearLayoutManager(requireContext())
     groups.adapter = adapter
 
-    val info = intent.getSerializableExtra("info") as? InfoDescriptor
+    val info = arguments?.getSerializable("info") as? InfoDescriptor
     viewModel.session.switchMap { sessionOptional ->
       val network = sessionOptional.orNull()?.networks?.get(info?.network)
       if (info == null || network == null) {
@@ -80,7 +68,7 @@ class InfoActivity : ServiceBoundActivity() {
                         ),
                         InfoProperty(
                           name = "Real Name",
-                          value = contentFormatter.format(this, user.realName())
+                          value = contentFormatter.format(requireContext(), user.realName())
                         ),
                         InfoProperty(
                           name = "Account",
@@ -101,10 +89,11 @@ class InfoActivity : ServiceBoundActivity() {
                 network = network,
                 properties = listOf(
                   InfoGroup(
+                    name = "Channel",
                     properties = listOf(
                       InfoProperty(
                         name = "Topic",
-                        value = contentFormatter.format(this, channel.topic())
+                        value = contentFormatter.format(requireContext(), channel.topic())
                       )
                     )
                   )
@@ -123,10 +112,10 @@ class InfoActivity : ServiceBoundActivity() {
         }
       }
     }.toLiveData().observe(this, Observer {
-      log(LoggingHandler.LogLevel.ERROR, "DEBUG", "data: $it")
+      LoggingHandler.log(LoggingHandler.LogLevel.ERROR, "DEBUG", "data: $it")
       adapter.submitList(it?.orNull()?.properties.orEmpty())
     })
 
-    viewModel.buffer.onNext(intent.getIntExtra("buffer", -1))
+    return view
   }
 }
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt
new file mode 100644
index 000000000..898bd179e
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt
@@ -0,0 +1,10 @@
+package de.kuschku.quasseldroid.ui.chat.info
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class InfoFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindInfoFragment(): InfoFragment
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoGroupAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoGroupAdapter.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt
index 3b56300d9..3bf3418e3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoGroupAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt
@@ -1,7 +1,8 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 import android.support.v7.recyclerview.extensions.ListAdapter
 import android.support.v7.util.DiffUtil
+import android.support.v7.widget.DividerItemDecoration
 import android.support.v7.widget.LinearLayoutManager
 import android.support.v7.widget.RecyclerView
 import android.view.LayoutInflater
@@ -11,7 +12,6 @@ import android.widget.TextView
 import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
-import de.kuschku.quasseldroid.util.helper.visibleIf
 import de.kuschku.quasseldroid.viewmodel.data.InfoGroup
 
 class InfoGroupAdapter :
@@ -33,9 +33,6 @@ class InfoGroupAdapter :
     holder.bind(getItem(position))
 
   class InfoGroupViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-    @BindView(R.id.title_container)
-    lateinit var titleContainer: View
-
     @BindView(R.id.title)
     lateinit var title: TextView
 
@@ -51,12 +48,13 @@ class InfoGroupAdapter :
 
       properties.layoutManager = LinearLayoutManager(itemView.context)
       properties.adapter = adapter
+      properties.addItemDecoration(
+        DividerItemDecoration(itemView.context, DividerItemDecoration.VERTICAL)
+      )
     }
 
     fun bind(item: InfoGroup) {
       title.text = item.name
-      titleContainer.visibleIf(item.name != null)
-
       adapter.submitList(item.properties)
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoPropertyAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoPropertyAdapter.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt
index 1a5900f84..42d66b33b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoPropertyAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt
@@ -1,12 +1,12 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 import android.support.v7.recyclerview.extensions.ListAdapter
 import android.support.v7.util.DiffUtil
-import android.support.v7.widget.AppCompatImageView
 import android.support.v7.widget.RecyclerView
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.ImageView
 import android.widget.TextView
 import butterknife.BindView
 import butterknife.ButterKnife
@@ -33,8 +33,11 @@ class InfoPropertyAdapter :
     holder.bind(getItem(position))
 
   class InfoPropertyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+    @BindView(R.id.icon_frame)
+    lateinit var iconFrame: View
+
     @BindView(R.id.icon)
-    lateinit var icon: AppCompatImageView
+    lateinit var icon: ImageView
 
     @BindView(R.id.name)
     lateinit var name: TextView
@@ -52,7 +55,7 @@ class InfoPropertyAdapter :
       name.text = item.name
       value.text = item.value
 
-      icon.visibleIf(item.icon != null)
+      iconFrame.visibleIf(item.icon != null)
     }
   }
 }
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoType.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt
similarity index 50%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoType.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt
index a998f7743..dbff4d723 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/detailinfo/InfoType.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.chat.detailinfo
+package de.kuschku.quasseldroid.ui.chat.info
 
 enum class InfoType {
   User,
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 3d836f317..0764b7984 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
@@ -1,7 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.messages
 
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
 import android.arch.paging.LivePagedListBuilder
 import android.arch.paging.PagedList
 import android.content.ClipData
@@ -27,7 +26,6 @@ import de.kuschku.quasseldroid.settings.BacklogSettings
 import de.kuschku.quasseldroid.util.helper.*
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.util.ui.SpanFormatter
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import io.reactivex.BackpressureStrategy
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
@@ -54,8 +52,6 @@ class MessageListFragment : ServiceBoundFragment() {
   @Inject
   lateinit var messageRenderer: QuasselMessageRenderer
 
-  private lateinit var viewModel: QuasselViewModel
-
   private lateinit var linearLayoutManager: LinearLayoutManager
   private lateinit var adapter: MessageAdapter
 
@@ -125,11 +121,6 @@ class MessageListFragment : ServiceBoundFragment() {
     }
   }
 
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-    viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-  }
-
   private val boundaryCallback = object :
     PagedList.BoundaryCallback<DisplayMessage>() {
     override fun onItemAtFrontLoaded(itemAtFront: DisplayMessage) = Unit
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 8b3071232..03d7c06ef 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
@@ -1,7 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.nicks
 
 import android.arch.lifecycle.Observer
-import android.arch.lifecycle.ViewModelProviders
 import android.content.Intent
 import android.os.Bundle
 import android.support.v7.widget.DefaultItemAnimator
@@ -17,18 +16,15 @@ import de.kuschku.libquassel.util.helpers.value
 import de.kuschku.libquassel.util.irc.IrcCaseMappers
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoActivity
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoDescriptor
-import de.kuschku.quasseldroid.ui.chat.detailinfo.InfoType
+import de.kuschku.quasseldroid.ui.chat.info.InfoActivity
+import de.kuschku.quasseldroid.ui.chat.info.InfoDescriptor
+import de.kuschku.quasseldroid.ui.chat.info.InfoType
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
-import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import javax.inject.Inject
 
 class NickListFragment : ServiceBoundFragment() {
-  private lateinit var viewModel: QuasselViewModel
-
   @BindView(R.id.nickList)
   lateinit var nickList: RecyclerView
 
@@ -38,12 +34,6 @@ class NickListFragment : ServiceBoundFragment() {
   @Inject
   lateinit var ircFormatDeserializer: IrcFormatDeserializer
 
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-
-    viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-  }
-
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {
     val view = inflater.inflate(R.layout.fragment_nick_list, container, false)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsActivity.kt
index 6f26b2b27..f64b961f1 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsActivity.kt
@@ -15,6 +15,7 @@ abstract class SettingsActivity(private val fragment: Fragment? = null) : Servic
   lateinit var toolbar: Toolbar
 
   override fun onCreate(savedInstanceState: Bundle?) {
+    val arguments = intent.extras
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_settings)
     ButterKnife.bind(this)
@@ -26,6 +27,7 @@ abstract class SettingsActivity(private val fragment: Fragment? = null) : Servic
 
     if (fragment != null) {
       val transaction = supportFragmentManager.beginTransaction()
+      fragment.arguments = arguments
       transaction.replace(R.id.fragment_container, fragment)
       transaction.commit()
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/license/LicenseSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/license/LicenseSettingsActivity.kt
index aa455d511..01947a640 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/license/LicenseSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/license/LicenseSettingsActivity.kt
@@ -1,19 +1,5 @@
 package de.kuschku.quasseldroid.ui.settings.license
 
-import android.os.Bundle
 import de.kuschku.quasseldroid.ui.settings.SettingsActivity
 
-class LicenseSettingsActivity : SettingsActivity() {
-  private lateinit var arguments: Bundle
-
-  override fun onCreate(savedInstanceState: Bundle?) {
-    arguments = intent.extras
-    super.onCreate(savedInstanceState)
-  }
-
-  override fun fragment(): LicenseSettingsFragment {
-    val fragment = LicenseSettingsFragment()
-    fragment.arguments = arguments
-    return fragment
-  }
-}
\ No newline at end of file
+class LicenseSettingsActivity : SettingsActivity()
\ No newline at end of file
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 3a1224b61..741a3aaa5 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
@@ -44,9 +44,7 @@ class AccountSelectionSlide : SlideFragment() {
                                savedInstanceState: Bundle?): View {
     val view = inflater.inflate(R.layout.setup_select_account, container, false)
     ButterKnife.bind(this, view)
-    val accountViewModel = ViewModelProviders.of(this).get(
-      AccountViewModel::class.java
-    )
+    val accountViewModel = ViewModelProviders.of(this).get(AccountViewModel::class.java)
     val firstObserver = object : Observer<List<AccountDatabase.Account>?> {
       override fun onChanged(t: List<AccountDatabase.Account>?) {
         if (t?.isEmpty() != false)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
index e620847e6..69299285f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
@@ -1,6 +1,7 @@
 package de.kuschku.quasseldroid.util.service
 
 import android.app.Activity
+import android.arch.lifecycle.ViewModelProviders
 import android.content.Context
 import android.content.Intent
 import android.content.SharedPreferences
@@ -25,6 +26,7 @@ import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
 import de.kuschku.quasseldroid.util.helper.updateRecentsHeaderIfExisting
+import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import io.reactivex.subjects.BehaviorSubject
 import javax.inject.Inject
 
@@ -77,6 +79,8 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
   @Inject
   lateinit var connectionSettings: ConnectionSettings
 
+  protected lateinit var viewModel: QuasselViewModel
+
   protected var accountId: Long = -1
 
   private var startedSelection = false
@@ -88,6 +92,9 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
 
     checkConnection()
 
+    viewModel = ViewModelProviders.of(this)[QuasselViewModel::class.java]
+    viewModel.backendWrapper.onNext(this.backend)
+
     setTheme(appearanceSettings.theme.style)
     super.onCreate(savedInstanceState)
     updateRecentsHeader()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
index bb01640e5..17ad17f90 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
@@ -1,11 +1,13 @@
 package de.kuschku.quasseldroid.util.service
 
+import android.arch.lifecycle.ViewModelProviders
 import android.content.Context
 import android.os.Bundle
 import dagger.android.support.DaggerFragment
 import de.kuschku.libquassel.session.Backend
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.quasseldroid.Keys
+import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import io.reactivex.subjects.BehaviorSubject
 
 abstract class ServiceBoundFragment : DaggerFragment() {
@@ -13,6 +15,8 @@ abstract class ServiceBoundFragment : DaggerFragment() {
   protected val backend: BehaviorSubject<Optional<Backend>>
     get() = connection.backend
 
+  protected lateinit var viewModel: QuasselViewModel
+
   protected fun runInBackground(f: () -> Unit) {
     connection.backend.value.ifPresent {
       it.sessionManager().handlerService.backend(f)
@@ -27,6 +31,11 @@ abstract class ServiceBoundFragment : DaggerFragment() {
 
   protected var accountId: Long = -1
 
+  override fun onAttach(context: Context?) {
+    super.onAttach(context)
+    viewModel = ViewModelProviders.of(requireActivity())[QuasselViewModel::class.java]
+  }
+
   override fun onCreate(savedInstanceState: Bundle?) {
     accountId = context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE)
       ?.getLong(Keys.Status.selectedAccount, -1) ?: -1
diff --git a/app/src/main/res/layout/activity_info.xml b/app/src/main/res/layout/activity_info.xml
deleted file mode 100644
index d8e3e75f0..000000000
--- a/app/src/main/res/layout/activity_info.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:app="http://schemas.android.com/apk/res-auto"
-  xmlns:tools="http://schemas.android.com/tools"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent"
-  android:fitsSystemWindows="true">
-
-  <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:fitsSystemWindows="true"
-    android:orientation="vertical">
-
-    <android.support.design.widget.AppBarLayout
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:theme="?attr/actionBarTheme">
-
-      <android.support.v7.widget.Toolbar
-        android:id="@+id/toolbar"
-        android:layout_width="match_parent"
-        android:layout_height="?attr/actionBarSize"
-        app:contentInsetStartWithNavigation="0dp"
-        app:popupTheme="?attr/actionBarPopupTheme" />
-
-    </android.support.design.widget.AppBarLayout>
-
-    <android.support.v7.widget.RecyclerView
-      android:id="@+id/groups"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      android:paddingTop="12dp"
-      app:layout_behavior="@string/appbar_scrolling_view_behavior"
-      tools:listitem="@layout/widget_userinfo_group" />
-
-  </LinearLayout>
-</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_info.xml b/app/src/main/res/layout/fragment_info.xml
new file mode 100644
index 000000000..1425be77a
--- /dev/null
+++ b/app/src/main/res/layout/fragment_info.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:tools="http://schemas.android.com/tools"
+  android:id="@+id/groups"
+  android:layout_width="match_parent"
+  android:layout_height="match_parent"
+  android:paddingTop="12dp"
+  tools:listitem="@layout/widget_userinfo_group" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/widget_userinfo.xml b/app/src/main/res/layout/widget_userinfo.xml
index 8b6510c5f..a9846e5ea 100644
--- a/app/src/main/res/layout/widget_userinfo.xml
+++ b/app/src/main/res/layout/widget_userinfo.xml
@@ -4,45 +4,66 @@
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
-  android:minHeight="72dp"
-  android:orientation="horizontal">
+  android:background="?android:attr/selectableItemBackground"
+  android:baselineAligned="false"
+  android:clipToPadding="false"
+  android:focusable="true"
+  android:gravity="center_vertical"
+  android:minHeight="?android:attr/listPreferredItemHeightSmall"
+  android:paddingEnd="?android:attr/listPreferredItemPaddingRight"
+  android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+  android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+  android:paddingStart="?android:attr/listPreferredItemPaddingLeft">
 
-  <android.support.v7.widget.AppCompatImageView
-    android:id="@+id/icon"
-    android:layout_width="40dp"
-    android:layout_height="40dp"
-    android:layout_gravity="center_vertical"
-    android:layout_marginLeft="20dp"
-    android:layout_marginStart="20dp"
-    android:scaleType="fitCenter"
-    app:srcCompat="@drawable/ic_account"
-    app:tint="?colorAccent" />
+  <FrameLayout
+    android:id="@+id/icon_frame"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginLeft="-4dp"
+    android:layout_marginStart="-4dp"
+    android:gravity="start|center_vertical"
+    android:minWidth="60dp"
+    android:orientation="horizontal"
+    android:paddingBottom="4dp"
+    android:paddingEnd="12dp"
+    android:paddingLeft="0dp"
+    android:paddingRight="12dp"
+    android:paddingStart="0dp"
+    android:paddingTop="4dp">
+
+    <android.support.v7.internal.widget.PreferenceImageView
+      android:id="@+id/icon"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      app:maxHeight="48dp"
+      app:maxWidth="48dp" />
+  </FrameLayout>
 
   <LinearLayout
-    android:layout_width="match_parent"
+    android:layout_width="0dip"
     android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
-    android:layout_marginLeft="12dp"
-    android:layout_marginStart="12dp"
-    android:orientation="vertical">
+    android:layout_weight="1"
+    android:orientation="vertical"
+    android:paddingBottom="16dp"
+    android:paddingTop="16dp">
 
     <TextView
       android:id="@+id/name"
-      android:layout_width="match_parent"
+      android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      android:layout_marginTop="8dp"
-      android:ellipsize="end"
+      android:ellipsize="marquee"
       android:singleLine="true"
-      android:textAppearance="?android:attr/textAppearanceSmall"
+      android:textColor="?colorTextPrimary"
+      android:textSize="16sp"
       tools:text="@sample/userinfo_basic.json/data/name" />
 
     <TextView
       android:id="@+id/value"
-      android:layout_width="match_parent"
+      android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      android:layout_marginBottom="8dp"
-      android:textAppearance="?android:attr/textAppearanceMedium"
-      android:textColor="?colorTextPrimary"
+      android:maxLines="10"
+      android:textAppearance="?android:attr/textAppearanceSmall"
+      android:textColor="?colorTextSecondary"
       tools:text="@sample/userinfo_basic.json/data/value" />
   </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/widget_userinfo_group.xml b/app/src/main/res/layout/widget_userinfo_group.xml
index e70bf9622..cd1b58f84 100644
--- a/app/src/main/res/layout/widget_userinfo_group.xml
+++ b/app/src/main/res/layout/widget_userinfo_group.xml
@@ -1,52 +1,32 @@
 <?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
-  android:layout_marginBottom="12dp"
-  android:layout_marginLeft="8dp"
-  android:layout_marginRight="8dp"
-  app:cardElevation="2dp">
+  android:orientation="vertical">
 
-  <LinearLayout
+  <TextView
+    android:id="@+id/title"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="vertical">
+    android:gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingBottom="8dp"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingRight"
+    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingLeft"
+    android:paddingTop="8dp"
+    android:textColor="?colorAccent"
+    android:textSize="16sp"
+    android:textStyle="bold"
+    tools:text="@sample/userinfo_groups.json/data/name" />
 
-    <LinearLayout
-      android:id="@+id/title_container"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:orientation="vertical">
-
-      <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start"
-        android:ellipsize="end"
-        android:paddingBottom="20dp"
-        android:paddingLeft="20dp"
-        android:paddingRight="20dp"
-        android:paddingTop="20dp"
-        android:singleLine="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="?colorAccent"
-        tools:text="@sample/userinfo_groups.json/data/name" />
-
-      <View
-        android:layout_width="match_parent"
-        android:layout_height="2dp"
-        android:background="?colorDivider" />
-
-    </LinearLayout>
+  <android.support.v7.widget.RecyclerView
+    android:id="@+id/properties"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    tools:itemCount="3"
+    tools:listitem="@layout/widget_userinfo" />
 
-    <android.support.v7.widget.RecyclerView
-      android:id="@+id/properties"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      tools:itemCount="3"
-      tools:listitem="@layout/widget_userinfo" />
-  </LinearLayout>
-</android.support.v7.widget.CardView>
\ No newline at end of file
+</LinearLayout>
\ No newline at end of file
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/InfoGroup.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/InfoGroup.kt
index 95505f372..fad7f67b7 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/InfoGroup.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/InfoGroup.kt
@@ -1,6 +1,6 @@
 package de.kuschku.quasseldroid.viewmodel.data
 
 data class InfoGroup(
-  val name: String? = null,
+  val name: String,
   val properties: List<InfoProperty>
 )
\ No newline at end of file
-- 
GitLab