From 08a444b4e5d2e95302b5fa99832a8e2d9ee1c508 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 15 Apr 2018 20:12:37 +0200
Subject: [PATCH] Improves editing of settings

---
 app/src/main/AndroidManifest.xml              | 16 +++++-
 .../quasseldroid/dagger/ActivityModule.kt     | 26 ++++++---
 .../chat/buffers/BufferViewConfigFragment.kt  |  8 ++-
 .../ui/chat/topic/TopicFragment.kt            |  2 +-
 .../ui/coresettings/CoreSettingsFragment.kt   | 32 +++++++++--
 .../ui/coresettings/SettingsFragment.kt       | 48 +++++++++++++++--
 ...istFragment.kt => ChatListBaseFragment.kt} | 35 ++++++++----
 .../chatlist/ChatListCreateFragment.kt        | 14 +++++
 .../chatlist/ChatListEditFragment.kt          | 20 +++++++
 .../chatlist/ChatlistCreateActivity.kt        | 12 +++++
 .../ChatlistCreateFragmentProvider.kt         | 10 ++++
 ...istActivity.kt => ChatlistEditActivity.kt} |  4 +-
 ...der.kt => ChatlistEditFragmentProvider.kt} |  4 +-
 ...ityFragment.kt => IdentityBaseFragment.kt} | 30 ++++++++---
 .../identity/IdentityCreateActivity.kt        | 12 +++++
 .../identity/IdentityCreateFragment.kt        | 15 ++++++
 .../IdentityCreateFragmentProvider.kt         | 10 ++++
 ...ityActivity.kt => IdentityEditActivity.kt} |  4 +-
 .../identity/IdentityEditFragment.kt          | 20 +++++++
 ...der.kt => IdentityEditFragmentProvider.kt} |  4 +-
 .../ignoreitem/IgnoreItemFragment.kt          | 12 ++++-
 .../ignorelist/IgnoreListFragment.kt          | 14 ++++-
 .../networkconfig/NetworkConfigFragment.kt    | 28 ++++++++--
 .../quasseldroid/util/ui/SettingsActivity.kt  | 26 ++++++++-
 app/src/main/res/menu/context_setting.xml     |  6 ++-
 app/src/main/res/values/strings.xml           |  3 ++
 .../quassel/syncables/RpcHandler.kt           | 54 +++++++++++++------
 .../de/kuschku/libquassel/session/ISession.kt |  3 ++
 .../de/kuschku/libquassel/session/Session.kt  |  1 +
 .../viewmodel/QuasselViewModel.kt             |  1 +
 30 files changed, 399 insertions(+), 75 deletions(-)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/{ChatListFragment.kt => ChatListBaseFragment.kt} (84%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListCreateFragment.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListEditFragment.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/{ChatListActivity.kt => ChatlistEditActivity.kt} (75%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/{ChatListFragmentProvider.kt => ChatlistEditFragmentProvider.kt} (60%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/{IdentityFragment.kt => IdentityBaseFragment.kt} (85%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragment.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/{IdentityActivity.kt => IdentityEditActivity.kt} (77%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragment.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/{IdentityFragmentProvider.kt => IdentityEditFragmentProvider.kt} (60%)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4ceb73f87..353a7e690 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -62,13 +62,25 @@
       android:parentActivityName=".ui.chat.ChatActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.identity.IdentityActivity"
+      android:name=".ui.coresettings.identity.IdentityCreateActivity"
       android:exported="false"
       android:label="@string/settings_identity_title"
       android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name=".ui.coresettings.chatlist.ChatListActivity"
+      android:name=".ui.coresettings.identity.IdentityEditActivity"
+      android:exported="false"
+      android:label="@string/settings_identity_title"
+      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:windowSoftInputMode="adjustResize" />
+    <activity
+      android:name=".ui.coresettings.chatlist.ChatlistCreateActivity"
+      android:exported="false"
+      android:label="@string/settings_chatlist_title"
+      android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
+      android:windowSoftInputMode="adjustResize" />
+    <activity
+      android:name=".ui.coresettings.chatlist.ChatlistEditActivity"
       android:exported="false"
       android:label="@string/settings_chatlist_title"
       android:parentActivityName=".ui.coresettings.CoreSettingsActivity"
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 1f8d98d5c..50e08e155 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
@@ -22,10 +22,14 @@ import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseSettingsActivity
 import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseSettingsFragmentProvider
 import de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity
 import de.kuschku.quasseldroid.ui.coresettings.CoreSettingsFragmentProvider
-import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatListActivity
-import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatListFragmentProvider
-import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityActivity
-import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityFragmentProvider
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateFragmentProvider
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditActivity
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditFragmentProvider
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityCreateActivity
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityCreateFragmentProvider
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityEditActivity
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityEditFragmentProvider
 import de.kuschku.quasseldroid.ui.coresettings.ignoreitem.IgnoreItemActivity
 import de.kuschku.quasseldroid.ui.coresettings.ignoreitem.IgnoreItemFragmentProvider
 import de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity
@@ -67,11 +71,17 @@ abstract class ActivityModule {
   @ContributesAndroidInjector(modules = [CoreSettingsFragmentProvider::class])
   abstract fun bindCoreSettingsActivity(): CoreSettingsActivity
 
-  @ContributesAndroidInjector(modules = [IdentityFragmentProvider::class])
-  abstract fun bindIdentityActivity(): IdentityActivity
+  @ContributesAndroidInjector(modules = [IdentityCreateFragmentProvider::class])
+  abstract fun bindIdentityCreateActivity(): IdentityCreateActivity
 
-  @ContributesAndroidInjector(modules = [ChatListFragmentProvider::class])
-  abstract fun bindChatListActivity(): ChatListActivity
+  @ContributesAndroidInjector(modules = [IdentityEditFragmentProvider::class])
+  abstract fun bindIdentityEditActivity(): IdentityEditActivity
+
+  @ContributesAndroidInjector(modules = [ChatlistCreateFragmentProvider::class])
+  abstract fun bindChatListCreateActivity(): ChatlistCreateActivity
+
+  @ContributesAndroidInjector(modules = [ChatlistEditFragmentProvider::class])
+  abstract fun bindChatListEditActivity(): ChatlistEditActivity
 
   @ContributesAndroidInjector(modules = [IgnoreListFragmentProvider::class])
   abstract fun bindIgnoreActivity(): IgnoreListActivity
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 63fbb4182..a4b20a53f 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
@@ -98,9 +98,11 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
                   session.bufferSyncer?.requestRemoveBuffer(info.bufferId)
                 }
               }
+              .onAny { _, _ ->
+                actionMode?.finish()
+              }
               .build()
               .show()
-            actionMode?.finish()
             true
           }
           R.id.action_rename     -> {
@@ -119,9 +121,11 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
               .negativeColorAttr(R.attr.colorTextPrimary)
               .backgroundColorAttr(R.attr.colorBackgroundCard)
               .contentColorAttr(R.attr.colorTextPrimary)
+              .onAny { _, _ ->
+                actionMode?.finish()
+              }
               .build()
               .show()
-            actionMode?.finish()
             true
           }
           R.id.action_unhide     -> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
index 90656dd37..c68b8e0c2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt
@@ -24,7 +24,7 @@ import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer
 import de.kuschku.quasseldroid.viewmodel.EditorViewModel
 import javax.inject.Inject
 
-class TopicFragment : SettingsFragment() {
+class TopicFragment : SettingsFragment(), SettingsFragment.Savable {
   @BindView(R.id.chatline)
   lateinit var chatline: RichEditText
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
index 8a800c24d..f9f6d54e0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/CoreSettingsFragment.kt
@@ -9,14 +9,17 @@ import android.support.v7.widget.RecyclerView
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.Button
 import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 import de.kuschku.libquassel.quassel.syncables.Identity
 import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.quasseldroid.R
-import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatListActivity
-import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityActivity
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity
+import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistEditActivity
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityCreateActivity
+import de.kuschku.quasseldroid.ui.coresettings.identity.IdentityEditActivity
 import de.kuschku.quasseldroid.ui.coresettings.ignorelist.IgnoreListActivity
 import de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigActivity
 import de.kuschku.quasseldroid.util.helper.combineLatest
@@ -27,12 +30,21 @@ class CoreSettingsFragment : ServiceBoundFragment() {
   @BindView(R.id.networks)
   lateinit var networks: RecyclerView
 
+  @BindView(R.id.new_network)
+  lateinit var newNetwork: Button
+
   @BindView(R.id.identities)
   lateinit var identities: RecyclerView
 
+  @BindView(R.id.new_identity)
+  lateinit var newIdentity: Button
+
   @BindView(R.id.chatlists)
   lateinit var chatlists: RecyclerView
 
+  @BindView(R.id.new_chatlist)
+  lateinit var newChatlist: Button
+
   @BindView(R.id.ignorelist)
   lateinit var ignorelist: View
 
@@ -59,11 +71,11 @@ class CoreSettingsFragment : ServiceBoundFragment() {
     }
 
     val identityAdapter = SettingsItemAdapter {
-      IdentityActivity.launch(requireContext(), identity = it)
+      IdentityEditActivity.launch(requireContext(), identity = it)
     }
 
     val chatListAdapter = SettingsItemAdapter {
-      ChatListActivity.launch(requireContext(), chatlist = it)
+      ChatlistEditActivity.launch(requireContext(), chatlist = it)
     }
 
     val itemDecoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
@@ -121,6 +133,18 @@ class CoreSettingsFragment : ServiceBoundFragment() {
       IgnoreListActivity.launch(requireContext())
     }
 
+    newNetwork.setOnClickListener {
+      //
+    }
+
+    newIdentity.setOnClickListener {
+      IdentityCreateActivity.launch(requireContext())
+    }
+
+    newChatlist.setOnClickListener {
+      ChatlistCreateActivity.launch(requireContext())
+    }
+
     return view
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsFragment.kt
index 76e93128a..9aa7fcd9b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsFragment.kt
@@ -4,27 +4,65 @@ import android.os.Bundle
 import android.view.Menu
 import android.view.MenuInflater
 import android.view.MenuItem
+import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 
 abstract class SettingsFragment : ServiceBoundFragment() {
+  private var saveable: Savable? = null
+  private var deletable: Deletable? = null
+
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setHasOptionsMenu(true)
+    saveable = this as? Savable
+    deletable = this as? Deletable
   }
 
   override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
     inflater?.inflate(R.menu.context_setting, menu)
+    menu?.findItem(R.id.action_save)?.isVisible = saveable != null
+    menu?.findItem(R.id.action_delete)?.isVisible = deletable != null
     super.onCreateOptionsMenu(menu, inflater)
   }
 
   override fun onOptionsItemSelected(item: MenuItem?) = when (item?.itemId) {
-    R.id.action_save -> {
-      if (onSave()) activity?.finish()
+    R.id.action_save   -> {
+      saveable?.let {
+        if (it.onSave()) activity?.finish()
+      }
+      true
+    }
+    R.id.action_delete -> {
+      deletable?.let {
+        MaterialDialog.Builder(activity!!)
+          .content(R.string.delete_confirmation)
+          .positiveText(R.string.label_yes)
+          .negativeText(R.string.label_no)
+          .negativeColorAttr(R.attr.colorTextPrimary)
+          .backgroundColorAttr(R.attr.colorBackgroundCard)
+          .contentColorAttr(R.attr.colorTextPrimary)
+          .onPositive { _, _ ->
+            it.onDelete()
+            requireActivity().finish()
+          }
+          .build()
+          .show()
+      }
       true
     }
-    else             -> super.onOptionsItemSelected(item)
+    else               -> super.onOptionsItemSelected(item)
+  }
+
+  interface Changeable {
+    fun hasChanged(): Boolean
+  }
+
+  interface Savable {
+    fun onSave(): Boolean
   }
 
-  abstract fun onSave(): Boolean
-}
\ No newline at end of file
+  interface Deletable {
+    fun onDelete()
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
similarity index 84%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
index 72326304d..cffea51bd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt
@@ -25,8 +25,9 @@ import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import io.reactivex.Observable
 
-class ChatListFragment : SettingsFragment() {
-  private var chatlist: Pair<BufferViewConfig, BufferViewConfig>? = null
+abstract class ChatListBaseFragment : SettingsFragment(), SettingsFragment.Savable,
+                                      SettingsFragment.Changeable {
+  protected var chatlist: Pair<BufferViewConfig?, BufferViewConfig>? = null
 
   @BindView(R.id.buffer_view_name)
   lateinit var bufferViewName: TextView
@@ -152,7 +153,22 @@ class ChatListFragment : SettingsFragment() {
     return view
   }
 
-  override fun onSave() = chatlist?.let { (it, data) ->
+  override fun hasChanged() = chatlist?.let { (it, data) ->
+    applyChanges(data, it)
+
+    it == null ||
+    data.bufferViewName() != it.bufferViewName() ||
+    data.showSearch() != it.showSearch() ||
+    data.sortAlphabetically() != it.sortAlphabetically() ||
+    data.addNewBuffersAutomatically() != it.addNewBuffersAutomatically() ||
+    data.hideInactiveBuffers() != it.hideInactiveBuffers() ||
+    data.hideInactiveNetworks() != it.hideInactiveNetworks() ||
+    data.allowedBufferTypes() != it.allowedBufferTypes() ||
+    data.networkId() != it.networkId() ||
+    data.minimumActivity() != it.minimumActivity()
+  } ?: false
+
+  protected fun applyChanges(data: BufferViewConfig, old: BufferViewConfig?) {
     data.setBufferViewName(bufferViewName.text.toString())
     data.setShowSearch(showSearch.isChecked)
     data.setSortAlphabetically(sortAlphabetically.isChecked)
@@ -173,11 +189,10 @@ class ChatListFragment : SettingsFragment() {
     data.setNetworkId(networkId.selectedItemId.toInt())
     data.setMinimumActivity(minimumActivity.selectedItemId.toInt())
 
-    data.initSetBufferList(it.initBufferList())
-    data.initSetTemporarilyRemovedBuffers(it.initTemporarilyRemovedBuffers())
-    data.initSetRemovedBuffers(it.initRemovedBuffers())
-
-    it.requestUpdate(data.toVariantMap())
-    true
-  } ?: false
+    if (old != null) {
+      data.initSetBufferList(old.initBufferList())
+      data.initSetTemporarilyRemovedBuffers(old.initTemporarilyRemovedBuffers())
+      data.initSetRemovedBuffers(old.initRemovedBuffers())
+    }
+  }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListCreateFragment.kt
new file mode 100644
index 000000000..e6adf93aa
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListCreateFragment.kt
@@ -0,0 +1,14 @@
+package de.kuschku.quasseldroid.ui.coresettings.chatlist
+
+import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
+import de.kuschku.libquassel.util.helpers.value
+
+class ChatListCreateFragment : ChatListBaseFragment() {
+  override fun onSave() = viewModel.session.value?.orNull()?.let { session ->
+    BufferViewConfig(-1, session.proxy).let { data ->
+      applyChanges(data, null)
+      viewModel.bufferViewManager.value?.orNull()?.requestCreateBufferView(data.toVariantMap())
+      true
+    }
+  } ?: false
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListEditFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListEditFragment.kt
new file mode 100644
index 000000000..931b3e3db
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListEditFragment.kt
@@ -0,0 +1,20 @@
+package de.kuschku.quasseldroid.ui.coresettings.chatlist
+
+import de.kuschku.libquassel.util.helpers.value
+import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
+
+class ChatListEditFragment : ChatListBaseFragment(), SettingsFragment.Deletable {
+  override fun onSave() = chatlist?.let { (it, data) ->
+    applyChanges(data, it)
+    it?.requestUpdate(data.toVariantMap())
+    true
+  } ?: false
+
+  override fun onDelete() {
+    chatlist?.let { (it, _) ->
+      it?.let {
+        viewModel.bufferViewManager.value?.orNull()?.requestDeleteBufferView(it.bufferViewId())
+      }
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
new file mode 100644
index 000000000..9f5c304df
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateActivity.kt
@@ -0,0 +1,12 @@
+package de.kuschku.quasseldroid.ui.coresettings.chatlist
+
+import android.content.Context
+import android.content.Intent
+import de.kuschku.quasseldroid.util.ui.SettingsActivity
+
+class ChatlistCreateActivity : SettingsActivity(ChatListCreateFragment()) {
+  companion object {
+    fun launch(context: Context) = context.startActivity(intent(context))
+    fun intent(context: Context) = Intent(context, ChatlistCreateActivity::class.java)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateFragmentProvider.kt
new file mode 100644
index 000000000..527726516
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistCreateFragmentProvider.kt
@@ -0,0 +1,10 @@
+package de.kuschku.quasseldroid.ui.coresettings.chatlist
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class ChatlistCreateFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindChatListCreateFragment(): ChatListCreateFragment
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
similarity index 75%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
index 45a42e7b2..07d9c196c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.content.Intent
 import de.kuschku.quasseldroid.util.ui.SettingsActivity
 
-class ChatListActivity : SettingsActivity(ChatListFragment()) {
+class ChatlistEditActivity : SettingsActivity(ChatListEditFragment()) {
   companion object {
     fun launch(
       context: Context,
@@ -14,7 +14,7 @@ class ChatListActivity : SettingsActivity(ChatListFragment()) {
     fun intent(
       context: Context,
       chatlist: Int
-    ) = Intent(context, ChatListActivity::class.java).apply {
+    ) = Intent(context, ChatlistEditActivity::class.java).apply {
       putExtra("chatlist", chatlist)
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditFragmentProvider.kt
similarity index 60%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditFragmentProvider.kt
index 033de4aae..4ae8a0bda 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatlistEditFragmentProvider.kt
@@ -4,7 +4,7 @@ import dagger.Module
 import dagger.android.ContributesAndroidInjector
 
 @Module
-abstract class ChatListFragmentProvider {
+abstract class ChatlistEditFragmentProvider {
   @ContributesAndroidInjector
-  abstract fun bindChatListFragment(): ChatListFragment
+  abstract fun bindChatListEditFragment(): ChatListEditFragment
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
similarity index 85%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragment.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
index e3aa0a3b9..1c5703173 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt
@@ -23,8 +23,10 @@ import de.kuschku.quasseldroid.util.helper.toLiveData
 import io.reactivex.Observable
 
 
-class IdentityFragment : SettingsFragment() {
-  private var identity: Pair<Identity, Identity>? = null
+abstract class IdentityBaseFragment : SettingsFragment(), SettingsFragment.Savable,
+                                      SettingsFragment.Changeable {
+
+  protected var identity: Pair<Identity?, Identity>? = null
 
   @BindView(R.id.identity_name)
   lateinit var identityName: TextView
@@ -139,7 +141,23 @@ class IdentityFragment : SettingsFragment() {
       }.build().show()
   }
 
-  override fun onSave() = identity?.let { (it, data) ->
+  override fun hasChanged() = identity?.let { (it, data) ->
+    applyChanges(data)
+
+    it == null ||
+    data.identityName() != it.identityName() ||
+    data.realName() != it.realName() ||
+    data.ident() != it.ident() ||
+    data.kickReason() != it.kickReason() ||
+    data.partReason() != it.partReason() ||
+    data.quitReason() != it.quitReason() ||
+    data.awayReason() != it.awayReason() ||
+    data.detachAwayEnabled() != it.detachAwayEnabled() ||
+    data.detachAwayReason() != it.detachAwayReason() ||
+    data.nicks() != it.nicks()
+  } ?: false
+
+  protected fun applyChanges(data: Identity) {
     data.setIdentityName(identityName.text.toString())
     data.setRealName(realName.text.toString())
     data.setIdent(ident.text.toString())
@@ -150,9 +168,5 @@ class IdentityFragment : SettingsFragment() {
     data.setDetachAwayEnabled(detachAway.isChecked)
     data.setDetachAwayReason(detachAwayReason.text.toString())
     data.setNicks(adapter.nicks)
-
-    it.requestUpdate(data.toVariantMap())
-    true
-  } ?: false
-
+  }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
new file mode 100644
index 000000000..f6a8239a6
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateActivity.kt
@@ -0,0 +1,12 @@
+package de.kuschku.quasseldroid.ui.coresettings.identity
+
+import android.content.Context
+import android.content.Intent
+import de.kuschku.quasseldroid.util.ui.SettingsActivity
+
+class IdentityCreateActivity : SettingsActivity(IdentityCreateFragment()) {
+  companion object {
+    fun launch(context: Context) = context.startActivity(intent(context))
+    fun intent(context: Context) = Intent(context, IdentityCreateActivity::class.java)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragment.kt
new file mode 100644
index 000000000..b80b28970
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragment.kt
@@ -0,0 +1,15 @@
+package de.kuschku.quasseldroid.ui.coresettings.identity
+
+import de.kuschku.libquassel.quassel.syncables.Identity
+import de.kuschku.libquassel.util.helpers.value
+
+
+class IdentityCreateFragment : IdentityBaseFragment() {
+  override fun onSave() = viewModel.session.value?.orNull()?.let { session ->
+    Identity(session.proxy).let { data ->
+      applyChanges(data)
+      session.rpcHandler?.requestCreateIdentity(data.toVariantMap(), mapOf())
+      true
+    }
+  } ?: false
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragmentProvider.kt
new file mode 100644
index 000000000..e73e4cfdb
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityCreateFragmentProvider.kt
@@ -0,0 +1,10 @@
+package de.kuschku.quasseldroid.ui.coresettings.identity
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class IdentityCreateFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindIdentityCreateFragment(): IdentityCreateFragment
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
similarity index 77%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
index b137bf1f6..c9ec38bdb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditActivity.kt
@@ -5,7 +5,7 @@ import android.content.Intent
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.quasseldroid.util.ui.SettingsActivity
 
-class IdentityActivity : SettingsActivity(IdentityFragment()) {
+class IdentityEditActivity : SettingsActivity(IdentityEditFragment()) {
   companion object {
     fun launch(
       context: Context,
@@ -15,7 +15,7 @@ class IdentityActivity : SettingsActivity(IdentityFragment()) {
     fun intent(
       context: Context,
       identity: IdentityId
-    ) = Intent(context, IdentityActivity::class.java).apply {
+    ) = Intent(context, IdentityEditActivity::class.java).apply {
       putExtra("identity", identity)
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragment.kt
new file mode 100644
index 000000000..e8a5bdcc2
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragment.kt
@@ -0,0 +1,20 @@
+package de.kuschku.quasseldroid.ui.coresettings.identity
+
+import de.kuschku.libquassel.util.helpers.value
+import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
+
+class IdentityEditFragment : IdentityBaseFragment(), SettingsFragment.Deletable {
+  override fun onSave() = identity?.let { (it, data) ->
+    applyChanges(data)
+    it?.requestUpdate(data.toVariantMap())
+    true
+  } ?: false
+
+  override fun onDelete() {
+    identity?.let { (it, _) ->
+      it?.let {
+        viewModel.session.value?.orNull()?.rpcHandler?.requestRemoveIdentity(it.id())
+      }
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragmentProvider.kt
similarity index 60%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragmentProvider.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragmentProvider.kt
index 1c156fbe7..ec469d848 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityFragmentProvider.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityEditFragmentProvider.kt
@@ -4,7 +4,7 @@ import dagger.Module
 import dagger.android.ContributesAndroidInjector
 
 @Module
-abstract class IdentityFragmentProvider {
+abstract class IdentityEditFragmentProvider {
   @ContributesAndroidInjector
-  abstract fun bindIdentityFragment(): IdentityFragment
+  abstract fun bindIdentityEditFragment(): IdentityEditFragment
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
index 90034f76b..3ac7edbb7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreItemFragment.kt
@@ -17,7 +17,8 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
 import de.kuschku.quasseldroid.util.ui.AnimationHelper
 
-class IgnoreItemFragment : SettingsFragment() {
+class IgnoreItemFragment : SettingsFragment(), SettingsFragment.Savable,
+                           SettingsFragment.Changeable {
   @BindView(R.id.enabled)
   lateinit var enabled: SwitchCompat
 
@@ -141,4 +142,13 @@ class IgnoreItemFragment : SettingsFragment() {
     true
   }
 
+  override fun hasChanged() = item != IgnoreListManager.IgnoreListItem(
+    isActive = enabled.isChecked,
+    ignoreRule = ignoreRule.text.toString(),
+    isRegEx = isRegEx.isChecked,
+    type = type.selectedItemId.toInt(),
+    strictness = strictness.selectedItemId.toInt(),
+    scope = scope.selectedItemId.toInt(),
+    scopeRule = scopeRule.text.toString()
+  )
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
index a30ac9887..08b5f5d17 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListFragment.kt
@@ -21,7 +21,8 @@ import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
 import de.kuschku.quasseldroid.ui.coresettings.ignoreitem.IgnoreItemActivity
 import de.kuschku.quasseldroid.util.helper.toLiveData
 
-class IgnoreListFragment : SettingsFragment() {
+class IgnoreListFragment : SettingsFragment(), SettingsFragment.Savable,
+                           SettingsFragment.Changeable {
   @BindView(R.id.list)
   lateinit var list: RecyclerView
 
@@ -96,11 +97,20 @@ class IgnoreListFragment : SettingsFragment() {
   }
 
   override fun onSave() = ignoreListManager?.let { (it, data) ->
-    data.setIgnoreList(adapter.list)
+    applyChanges(data)
     it.requestUpdate(data.toVariantMap())
     true
   } ?: false
 
+  override fun hasChanged() = ignoreListManager?.let { (it, data) ->
+    applyChanges(data)
+    data != it
+  } ?: false
+
+  private fun applyChanges(data: IgnoreListManager) {
+    data.setIgnoreList(adapter.list)
+  }
+
   companion object {
     private const val REQUEST_UPDATE_RULE = 1
     private const val REQUEST_CREATE_RULE = 2
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
index ceac297b1..e9367b373 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkconfig/NetworkConfigFragment.kt
@@ -16,7 +16,8 @@ import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
 import de.kuschku.quasseldroid.util.helper.setDependent
 import de.kuschku.quasseldroid.util.helper.toLiveData
 
-class NetworkConfigFragment : SettingsFragment() {
+class NetworkConfigFragment : SettingsFragment(), SettingsFragment.Savable,
+                              SettingsFragment.Changeable {
   private var networkConfig: Pair<NetworkConfig, NetworkConfig>? = null
 
   @BindView(R.id.ping_timeout_enabled)
@@ -84,6 +85,26 @@ class NetworkConfigFragment : SettingsFragment() {
 
 
   override fun onSave() = networkConfig?.let { (it, data) ->
+    applyChanges(data)
+
+    it.requestUpdate(data.toVariantMap())
+    true
+  } ?: false
+
+  override fun hasChanged() = networkConfig?.let { (it, data) ->
+    applyChanges(data)
+
+    data.pingTimeoutEnabled() != it.pingTimeoutEnabled() ||
+    data.pingInterval() != it.pingInterval() ||
+    data.maxPingCount() != it.maxPingCount() ||
+    data.autoWhoEnabled() != it.autoWhoEnabled() ||
+    data.autoWhoInterval() != it.autoWhoInterval() ||
+    data.autoWhoNickLimit() != it.autoWhoNickLimit() ||
+    data.autoWhoDelay() != it.autoWhoDelay() ||
+    data.standardCtcp() != it.standardCtcp()
+  } ?: false
+
+  private fun applyChanges(data: NetworkConfig) {
     data.setPingTimeoutEnabled(pingTimeoutEnabled.isChecked)
     pingInterval.text.toString().toIntOrNull()?.let(data::setPingInterval)
     maxPingCount.text.toString().toIntOrNull()?.let(data::setMaxPingCount)
@@ -93,8 +114,5 @@ class NetworkConfigFragment : SettingsFragment() {
     autoWhoNickLimit.text.toString().toIntOrNull()?.let(data::setAutoWhoNickLimit)
     autoWhoDelay.text.toString().toIntOrNull()?.let(data::setAutoWhoDelay)
     data.setStandardCtcp(standardCtcp.isChecked)
-
-    it.requestUpdate(data.toVariantMap())
-    true
-  } ?: false
+  }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt
index 30b536ccf..f3ec01f76 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt
@@ -5,12 +5,16 @@ import android.support.v4.app.Fragment
 import android.support.v7.widget.Toolbar
 import butterknife.BindView
 import butterknife.ButterKnife
+import com.afollestad.materialdialogs.MaterialDialog
 import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.ui.coresettings.SettingsFragment
 import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
 
 abstract class SettingsActivity(private val fragment: Fragment? = null) : ServiceBoundActivity() {
   protected open fun fragment(): Fragment? = null
 
+  private var changeable: SettingsFragment.Changeable? = null
+
   @BindView(R.id.toolbar)
   lateinit var toolbar: Toolbar
 
@@ -31,5 +35,25 @@ abstract class SettingsActivity(private val fragment: Fragment? = null) : Servic
       transaction.replace(R.id.fragment_container, fragment)
       transaction.commit()
     }
+
+    this.changeable = fragment as? SettingsFragment.Changeable
+  }
+
+  override fun onBackPressed() {
+    val changeable = this.changeable
+    if (changeable?.hasChanged() == true) {
+      MaterialDialog.Builder(this)
+        .content(R.string.cancel_confirmation)
+        .positiveText(R.string.label_yes)
+        .negativeText(R.string.label_no)
+        .negativeColorAttr(R.attr.colorTextPrimary)
+        .backgroundColorAttr(R.attr.colorBackgroundCard)
+        .contentColorAttr(R.attr.colorTextPrimary)
+        .onPositive { _, _ ->
+          super.onBackPressed()
+        }
+        .build()
+        .show()
+    } else super.onBackPressed()
   }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/res/menu/context_setting.xml b/app/src/main/res/menu/context_setting.xml
index c167e748c..fbec4bd5c 100644
--- a/app/src/main/res/menu/context_setting.xml
+++ b/app/src/main/res/menu/context_setting.xml
@@ -5,4 +5,8 @@
     android:id="@+id/action_save"
     android:title="@string/label_save"
     app:showAsAction="ifRoom" />
-</menu>
\ No newline at end of file
+  <item
+    android:id="@+id/action_delete"
+    android:title="@string/label_delete"
+    app:showAsAction="ifRoom" />
+</menu>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9682b2c7b..c0cddc5d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -79,4 +79,7 @@
   <string name="notification_channel_highlight_title">Highlight</string>
 
   <string name="buffer_delete_confirmation">Do you want to delete this buffer permanently?</string>
+
+  <string name="delete_confirmation">Are you sure you want to delete this permanently? This can not be undone</string>
+  <string name="cancel_confirmation">You have unsaved changes. Do you wish to discard them?</string>
 </resources>
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
index e02a481bf..0d9c3e25f 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
@@ -41,27 +41,47 @@ class RpcHandler(
     backlogStorage.storeMessages(session, message)
   }
 
-  override fun requestCreateIdentity(identity: QVariantMap, additional: QVariantMap) {
-  }
-
-  override fun requestRemoveIdentity(identityId: IdentityId) {
-  }
-
-  override fun requestCreateNetwork(networkInfo: INetwork.NetworkInfo, channels: List<String>) {
-  }
-
-  override fun requestRemoveNetwork(networkId: NetworkId) {
-  }
+  override fun requestCreateIdentity(identity: QVariantMap, additional: QVariantMap) =
+    RPC(
+      "2requestCreateIdentity(Identity,QVariantMap)",
+      ARG(identity, QType.Identity),
+      ARG(additional, Type.QVariantMap)
+    )
+
+  override fun requestRemoveIdentity(identityId: IdentityId) =
+    RPC(
+      "2requestRemoveIdentity(IdentityId)",
+      ARG(identityId, QType.IdentityId)
+    )
+
+  override fun requestCreateNetwork(networkInfo: INetwork.NetworkInfo, channels: List<String>) =
+    RPC(
+      "2requestCreateNetwork(NetworkInfo,QStringList)",
+      ARG(networkInfo, QType.NetworkInfo),
+      ARG(channels, Type.QStringList)
+    )
+
+  override fun requestRemoveNetwork(networkId: NetworkId) =
+    RPC(
+      "2requestRemoveNetwork(NetworkId)",
+      ARG(networkId, QType.NetworkId)
+    )
 
   override fun requestPasswordChange(peerPtr: Long, user: String, old: String, new: String) {
   }
 
-  override fun requestKickClient(id: Int) = RPC("2requestKickClient(Int)", ARG(id, Type.Int))
-
-  override fun sendInput(bufferInfo: BufferInfo, message: String) = RPC(
-    "2sendInput(BufferInfo,QString)", ARG(bufferInfo, QType.BufferInfo),
-    ARG(message, Type.QString)
-  )
+  override fun requestKickClient(id: Int) =
+    RPC(
+      "2requestKickClient(Int)",
+      ARG(id, Type.Int)
+    )
+
+  override fun sendInput(bufferInfo: BufferInfo, message: String) =
+    RPC(
+      "2sendInput(BufferInfo,QString)",
+      ARG(bufferInfo, QType.BufferInfo),
+      ARG(message, Type.QString)
+    )
 
   inline fun RPC(function: String, vararg arg: QVariant_) {
     // Don’t transmit calls back that we just got from the network
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
index bdbdd4a8a..d35de1f70 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
@@ -34,6 +34,8 @@ interface ISession : Closeable {
   val rpcHandler: RpcHandler?
   val initStatus: Observable<Pair<Int, Int>>
 
+  val proxy: SignalProxy
+
   val error: Flowable<HandshakeMessage>
 
   val lag: Observable<Long>
@@ -42,6 +44,7 @@ interface ISession : Closeable {
 
   companion object {
     val NULL = object : ISession {
+      override val proxy: SignalProxy = SignalProxy.NULL
       override val error = BehaviorSubject.create<HandshakeMessage>()
         .toFlowable(BackpressureStrategy.BUFFER)
       override val state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED)
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
index 23439087d..ec0bb88ee 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -24,6 +24,7 @@ class Session(
   val disconnectFromCore: () -> Unit,
   exceptionHandler: (Throwable) -> Unit
 ) : ProtocolHandler(exceptionHandler), ISession {
+  override val proxy: SignalProxy = this
   override val features = Features(clientData.clientFeatures, QuasselFeatures.empty())
 
   override val sslSession
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
index 86e9b29ba..8332bff62 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -55,6 +55,7 @@ class QuasselViewModel : ViewModel() {
   val backend = backendWrapper.switchMap { it }
   val sessionManager = backend.mapMap(Backend::sessionManager)
   val session = sessionManager.mapSwitchMap(SessionManager::session)
+  val rpcHandler = session.mapMapNullable(ISession::rpcHandler)
 
   val connectionProgress = sessionManager.mapSwitchMap(SessionManager::connectionProgress)
     .mapOrElse(Triple(ConnectionState.DISCONNECTED, 0, 0))
-- 
GitLab