From d2f572d6ce347cf06aa3b990bdcac8f89742ecc9 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Thu, 22 Mar 2018 11:10:17 +0100 Subject: [PATCH] Refactoring into more modules --- app/build.gradle.kts | 1 + .../quasseldroid_ng/ui/chat/ChatActivity.kt | 13 +- .../ui/chat/ToolbarFragment.kt | 10 +- .../ui/chat/buffers/BufferListAdapter.kt | 43 ++---- .../chat/buffers/BufferViewConfigFragment.kt | 31 ++--- .../ui/chat/input/AutoCompleteAdapter.kt | 39 +----- .../quasseldroid_ng/ui/chat/input/Editor.kt | 3 +- .../ui/chat/messages/MessageListFragment.kt | 2 +- .../ui/chat/nicks/NickListAdapter.kt | 12 +- .../ui/chat/nicks/NickListFragment.kt | 2 +- lib/build.gradle.kts | 6 + .../syncables/interfaces/invokers/Invokers.kt | 2 +- .../libquassel/session/CoreConnection.kt | 43 +++--- .../de/kuschku/libquassel/session/Features.kt | 12 ++ .../de/kuschku/libquassel/session/ISession.kt | 6 +- .../libquassel/session/MessageRunnable.kt | 2 +- .../libquassel/session/ProtocolHandler.kt | 2 +- .../de/kuschku/libquassel/session/Session.kt | 19 ++- .../libquassel/session/SessionManager.kt | 9 +- .../util/compatibility/LoggingHandler.kt | 20 +-- .../libquassel/util/helpers/ArrayHelper.kt | 2 +- settings.gradle | 2 +- viewmodel/build.gradle.kts | 43 ++++++ viewmodel/proguard-rules.pro | 0 viewmodel/src/main/AndroidManifest.xml | 2 + .../util/helper/LiveDataHelper.kt | 0 .../util/helper/LiveDataZipHelper.kt | 6 +- .../util/helper/ObservableHelper.kt | 0 .../viewmodel/QuasselViewModel.kt | 126 +++++++++--------- .../viewmodel/data/AutoCompleteItem.kt | 32 +++++ .../viewmodel/data/BufferData.kt | 10 ++ .../viewmodel/data/BufferHiddenState.kt | 8 ++ .../viewmodel/data/BufferListItem.kt | 6 + .../viewmodel/data/BufferProps.kt | 19 +++ .../viewmodel/data/BufferState.kt | 6 + .../viewmodel/data/BufferStatus.kt | 7 + .../viewmodel/data/IrcUserItem.kt | 10 ++ .../viewmodel/data/SelectedBufferItem.kt | 11 ++ 38 files changed, 333 insertions(+), 234 deletions(-) create mode 100644 lib/src/main/java/de/kuschku/libquassel/session/Features.kt create mode 100644 viewmodel/build.gradle.kts create mode 100644 viewmodel/proguard-rules.pro create mode 100644 viewmodel/src/main/AndroidManifest.xml rename {app => viewmodel}/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataHelper.kt (100%) rename {app => viewmodel}/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt (97%) rename {app => viewmodel}/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ObservableHelper.kt (100%) rename {app/src/main/java/de/kuschku/quasseldroid_ng/ui => viewmodel/src/main/java/de/kuschku/quasseldroid_ng}/viewmodel/QuasselViewModel.kt (77%) create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/AutoCompleteItem.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferData.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferHiddenState.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferListItem.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferProps.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferState.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferStatus.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/IrcUserItem.kt create mode 100644 viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/SelectedBufferItem.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 502042025..7e50d3d16 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -133,6 +133,7 @@ dependencies { } // Quassel + implementation(project(":viewmodel")) implementation(project(":lib")) { exclude(group = "org.threeten", module = "threetenbp") } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt index 4627d3e55..19baffe7b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.kt @@ -34,19 +34,18 @@ import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase import de.kuschku.quasseldroid_ng.settings.BacklogSettings import de.kuschku.quasseldroid_ng.settings.Settings -import de.kuschku.quasseldroid_ng.ui.chat.input.AutoCompleteAdapter import de.kuschku.quasseldroid_ng.ui.chat.input.Editor import de.kuschku.quasseldroid_ng.ui.chat.input.MessageHistoryAdapter import de.kuschku.quasseldroid_ng.ui.settings.SettingsActivity import de.kuschku.quasseldroid_ng.ui.setup.accounts.AccountSelectionActivity -import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.helper.editApply import de.kuschku.quasseldroid_ng.util.helper.invoke -import de.kuschku.quasseldroid_ng.util.helper.let import de.kuschku.quasseldroid_ng.util.helper.sharedPreferences import de.kuschku.quasseldroid_ng.util.service.ServiceBoundActivity import de.kuschku.quasseldroid_ng.util.ui.MaterialContentLoadingProgressBar +import de.kuschku.quasseldroid_ng.viewmodel.QuasselViewModel +import de.kuschku.quasseldroid_ng.viewmodel.data.AutoCompleteItem class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenceChangeListener { @BindView(R.id.drawer_layout) @@ -125,7 +124,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc findViewById(R.id.formatting_toolbar), { lines -> viewModel.session { session -> - viewModel.getBuffer().let { bufferId -> + viewModel.getBuffer().value?.let { bufferId -> session.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo -> val output = mutableListOf<IAliasManager.Command>() for ((stripped, formatted) in lines) { @@ -204,8 +203,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc data class AutoCompletionState( val originalWord: String, val range: IntRange, - val lastCompletion: AutoCompleteAdapter.AutoCompleteItem? = null, - val completion: AutoCompleteAdapter.AutoCompleteItem + val lastCompletion: AutoCompleteItem? = null, + val completion: AutoCompleteItem ) override fun onSaveInstanceState(outState: Bundle?) { @@ -298,7 +297,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc R.id.clear -> { handler.post { viewModel.sessionManager { manager -> - viewModel.getBuffer().let { buffer -> + viewModel.getBuffer().value?.let { buffer -> manager.backlogStorage.clearMessages(buffer) manager.backlogManager?.requestBacklog( bufferId = buffer, diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ToolbarFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ToolbarFragment.kt index 7c8b69f1c..466ea7ba1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ToolbarFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ToolbarFragment.kt @@ -10,18 +10,16 @@ import android.widget.TextView import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.protocol.Buffer_Type -import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.hasFlag import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.settings.AppearanceSettings import de.kuschku.quasseldroid_ng.settings.Settings -import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.helper.visibleIf import de.kuschku.quasseldroid_ng.util.helper.zip import de.kuschku.quasseldroid_ng.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment import de.kuschku.quasseldroid_ng.util.ui.SpanFormatter +import de.kuschku.quasseldroid_ng.viewmodel.QuasselViewModel class ToolbarFragment : ServiceBoundFragment() { @BindView(R.id.toolbar_title) @@ -102,10 +100,4 @@ class ToolbarFragment : ServiceBoundFragment() { description, appearanceSettings.colorizeMirc ) ?: description - - data class BufferData( - val info: BufferInfo? = null, - val network: INetwork.NetworkInfo? = null, - val description: String? = null - ) } \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt index f5cbb490b..f4ae35f24 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferListAdapter.kt @@ -15,15 +15,21 @@ import android.widget.ImageView import android.widget.TextView import butterknife.BindView import butterknife.ButterKnife -import de.kuschku.libquassel.protocol.* +import de.kuschku.libquassel.protocol.BufferId +import de.kuschku.libquassel.protocol.Buffer_Activity +import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.hasFlag import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.util.helper.getCompatDrawable import de.kuschku.quasseldroid_ng.util.helper.styledAttributes import de.kuschku.quasseldroid_ng.util.helper.visibleIf import de.kuschku.quasseldroid_ng.util.helper.zip +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferListItem +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferProps +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferState +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferStatus class BufferListAdapter( lifecycleOwner: LifecycleOwner, @@ -145,33 +151,6 @@ class BufferListAdapter( override fun getItemViewType(position: Int) = data[position].props.info.type.toInt() - data class BufferListItem( - val props: BufferProps, - val state: BufferState - ) - - data class BufferProps( - val info: BufferInfo, - val network: INetwork.NetworkInfo, - val bufferStatus: BufferStatus, - val description: CharSequence, - val activity: Message_Types, - val highlights: Int = 0, - val bufferActivity: Buffer_Activities = Buffer_Activity.of(Buffer_Activity.NoActivity), - val hiddenState: HiddenState - ) - - enum class HiddenState { - VISIBLE, - HIDDEN_TEMPORARY, - HIDDEN_PERMANENT - } - - data class BufferState( - val networkExpanded: Boolean, - val selected: Boolean - ) - abstract class BufferViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { abstract fun bind(props: BufferProps, state: BufferState) @@ -522,10 +501,4 @@ class BufferListAdapter( } } } - - enum class BufferStatus { - ONLINE, - AWAY, - OFFLINE - } } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt index 2c3982090..e491e9592 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/buffers/BufferViewConfigFragment.kt @@ -13,7 +13,6 @@ import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.protocol.Buffer_Activity import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.Message_Type -import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.hasFlag import de.kuschku.libquassel.util.minus @@ -21,12 +20,13 @@ import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase import de.kuschku.quasseldroid_ng.settings.AppearanceSettings import de.kuschku.quasseldroid_ng.settings.Settings -import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.helper.map import de.kuschku.quasseldroid_ng.util.helper.zip import de.kuschku.quasseldroid_ng.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid_ng.viewmodel.QuasselViewModel +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferHiddenState class BufferViewConfigFragment : ServiceBoundFragment() { private val handlerThread = AndroidHandlerThread("ChatList") @@ -55,7 +55,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { val session = viewModel.session.value val bufferSyncer = session?.bufferSyncer val network = session?.networks?.get(selected?.info?.networkId) - val bufferViewConfig = viewModel.getBufferViewConfig().value + val bufferViewConfig = viewModel.bufferViewConfig.value return if (info != null && session != null) { when (item?.itemId) { @@ -88,7 +88,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() { .backgroundColorAttr(R.attr.colorBackgroundCard) .contentColorAttr(R.attr.colorTextPrimary) .onPositive { _, _ -> - session.bufferSyncer?.requestRemoveBuffer(selected.info.bufferId) + selected.info?.let { + session.bufferSyncer?.requestRemoveBuffer(info.bufferId) + } } .build() .show() @@ -102,7 +104,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() { info.bufferName, false ) { _, input -> - session.bufferSyncer?.requestRenameBuffer(selected.info.bufferId, input.toString()) + selected.info?.let { + session.bufferSyncer?.requestRenameBuffer(info.bufferId, input.toString()) + } } .positiveText(R.string.label_save) .negativeText(R.string.label_cancel) @@ -176,11 +180,11 @@ class BufferViewConfigFragment : ServiceBoundFragment() { chatListSpinner.adapter = adapter chatListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(p0: AdapterView<*>?) { - viewModel.setBufferViewConfig(null) + viewModel.setBufferViewConfigId(null) } override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) { - viewModel.setBufferViewConfig(adapter.getItem(p2)) + viewModel.setBufferViewConfigId(adapter.getItem(p2)?.bufferViewId()) } } @@ -240,15 +244,15 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ) val visibilityActions = when (buffer.hiddenState) { - BufferListAdapter.HiddenState.VISIBLE -> setOf( + BufferHiddenState.VISIBLE -> setOf( R.id.action_hide_temp, R.id.action_hide_perm ) - BufferListAdapter.HiddenState.HIDDEN_TEMPORARY -> setOf( + BufferHiddenState.HIDDEN_TEMPORARY -> setOf( R.id.action_unhide, R.id.action_hide_perm ) - BufferListAdapter.HiddenState.HIDDEN_PERMANENT -> setOf( + BufferHiddenState.HIDDEN_PERMANENT -> setOf( R.id.action_unhide, R.id.action_hide_temp ) @@ -327,11 +331,4 @@ class BufferViewConfigFragment : ServiceBoundFragment() { } listAdapter.toggleSelection(it) } - - data class SelectedItem( - val info: BufferInfo? = null, - val connectionState: INetwork.ConnectionState = INetwork.ConnectionState.Disconnected, - val joined: Boolean = false, - val hiddenState: BufferListAdapter.HiddenState = BufferListAdapter.HiddenState.VISIBLE - ) } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/AutoCompleteAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/AutoCompleteAdapter.kt index 62778a67e..367406a36 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/AutoCompleteAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/AutoCompleteAdapter.kt @@ -12,18 +12,17 @@ import android.widget.ImageView import android.widget.TextView import butterknife.BindView import butterknife.ButterKnife -import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.quasseldroid_ng.R -import de.kuschku.quasseldroid_ng.ui.chat.buffers.BufferListAdapter import de.kuschku.quasseldroid_ng.ui.chat.nicks.NickListAdapter.Companion.VIEWTYPE_AWAY import de.kuschku.quasseldroid_ng.util.helper.getCompatDrawable import de.kuschku.quasseldroid_ng.util.helper.styledAttributes import de.kuschku.quasseldroid_ng.util.helper.visibleIf +import de.kuschku.quasseldroid_ng.viewmodel.data.AutoCompleteItem +import de.kuschku.quasseldroid_ng.viewmodel.data.BufferStatus class AutoCompleteAdapter( private val clickListener: ((String) -> Unit)? = null -) : ListAdapter<AutoCompleteAdapter.AutoCompleteItem, AutoCompleteAdapter.AutoCompleteViewHolder>( +) : ListAdapter<AutoCompleteItem, AutoCompleteAdapter.AutoCompleteViewHolder>( object : DiffUtil.ItemCallback<AutoCompleteItem>() { override fun areItemsTheSame(oldItem: AutoCompleteItem, newItem: AutoCompleteItem) = oldItem.name == newItem.name @@ -63,34 +62,6 @@ class AutoCompleteAdapter( } } - sealed class AutoCompleteItem(open val name: String) : Comparable<AutoCompleteItem> { - override fun compareTo(other: AutoCompleteItem): Int { - return when { - this is UserItem && - other is ChannelItem -> -1 - this is ChannelItem && - other is UserItem -> 1 - else -> this.name.compareTo(other.name) - } - } - - data class UserItem( - val nick: String, - val modes: String, - val lowestMode: Int, - val realname: CharSequence, - val away: Boolean, - val networkCasemapping: String - ) : AutoCompleteItem(nick) - - data class ChannelItem( - val info: BufferInfo, - val network: INetwork.NetworkInfo, - val bufferStatus: BufferListAdapter.BufferStatus, - val description: CharSequence - ) : AutoCompleteItem(info.bufferName ?: "") - } - sealed class AutoCompleteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(data: AutoCompleteItem) = when { data is AutoCompleteItem.UserItem && this is NickViewHolder -> this.bindImpl(data) @@ -185,8 +156,8 @@ class AutoCompleteAdapter( status.setImageDrawable( when (data.bufferStatus) { - BufferListAdapter.BufferStatus.ONLINE -> online - else -> offline + BufferStatus.ONLINE -> online + else -> offline } ) } diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/Editor.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/Editor.kt index d7463e063..14a3c5cff 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/Editor.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/input/Editor.kt @@ -18,6 +18,7 @@ import de.kuschku.quasseldroid_ng.ui.chat.ChatActivity import de.kuschku.quasseldroid_ng.util.helper.lastWordIndices import de.kuschku.quasseldroid_ng.util.helper.lineSequence import de.kuschku.quasseldroid_ng.util.helper.retint +import de.kuschku.quasseldroid_ng.viewmodel.data.AutoCompleteItem import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject @@ -25,7 +26,7 @@ class Editor( // Contexts activity: AppCompatActivity, // LiveData - private val autoCompleteData: LiveData<Pair<String, List<AutoCompleteAdapter.AutoCompleteItem>>?>, + private val autoCompleteData: LiveData<Pair<String, List<AutoCompleteItem>>?>, lastWordContainer: MutableLiveData<Observable<Pair<String, IntRange>>>, // Views val chatline: AppCompatEditText, diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt index 49a76a1e9..d27154b6a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/messages/MessageListFragment.kt @@ -21,10 +21,10 @@ import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase import de.kuschku.quasseldroid_ng.settings.AppearanceSettings import de.kuschku.quasseldroid_ng.settings.BacklogSettings import de.kuschku.quasseldroid_ng.settings.Settings -import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.helper.* import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid_ng.viewmodel.QuasselViewModel class MessageListFragment : ServiceBoundFragment() { @BindView(R.id.messages) diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListAdapter.kt index 2b1a21ee6..9e21c534f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListAdapter.kt @@ -11,10 +11,11 @@ import butterknife.BindView import butterknife.ButterKnife import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.util.helper.visibleIf +import de.kuschku.quasseldroid_ng.viewmodel.data.IrcUserItem class NickListAdapter( private val clickListener: ((String) -> Unit)? = null -) : ListAdapter<NickListAdapter.IrcUserItem, NickListAdapter.NickViewHolder>( +) : ListAdapter<IrcUserItem, NickListAdapter.NickViewHolder>( object : DiffUtil.ItemCallback<IrcUserItem>() { override fun areItemsTheSame(oldItem: IrcUserItem, newItem: IrcUserItem) = oldItem.nick == newItem.nick @@ -42,15 +43,6 @@ class NickListAdapter( VIEWTYPE_ACTIVE } - data class IrcUserItem( - val nick: String, - val modes: String, - val lowestMode: Int, - val realname: CharSequence, - val away: Boolean, - val networkCasemapping: String - ) - class NickViewHolder( itemView: View, private val clickListener: ((String) -> Unit)? = null diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListFragment.kt index ba8d29d33..1abcaf0d8 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicks/NickListFragment.kt @@ -15,11 +15,11 @@ import de.kuschku.libquassel.util.irc.IrcCaseMappers import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.settings.AppearanceSettings import de.kuschku.quasseldroid_ng.settings.Settings -import de.kuschku.quasseldroid_ng.ui.viewmodel.QuasselViewModel import de.kuschku.quasseldroid_ng.util.AndroidHandlerThread import de.kuschku.quasseldroid_ng.util.helper.map import de.kuschku.quasseldroid_ng.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid_ng.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid_ng.viewmodel.QuasselViewModel class NickListFragment : ServiceBoundFragment() { private lateinit var viewModel: QuasselViewModel diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 8c2b7c1a6..e3cf7c1ba 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -19,6 +19,12 @@ dependencies { implementation("org.threeten", "threetenbp", "1.3.6") implementation("io.reactivex.rxjava2:rxjava:2.1.9") + + withVersion("2.15") { + implementation("com.google.dagger", "dagger", version) + kapt("com.google.dagger", "dagger-compiler", version) + } + implementation(project(":invokerannotations")) kapt(project(":invokergenerator")) diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt index f9aad6605..23a6d7d5c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt @@ -2,9 +2,9 @@ package de.kuschku.libquassel.quassel.syncables.interfaces.invokers import de.kuschku.libquassel.annotations.Syncable import de.kuschku.libquassel.quassel.syncables.interfaces.* +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN -import de.kuschku.libquassel.util.compatibility.log object Invokers { private val registry = mutableMapOf<String, Invoker<*>>() diff --git a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt index 3723825a1..88a7df98a 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt @@ -1,5 +1,6 @@ package de.kuschku.libquassel.session +import de.kuschku.libquassel.protocol.ClientData import de.kuschku.libquassel.protocol.message.HandshakeMessage import de.kuschku.libquassel.protocol.message.SignalProxyMessage import de.kuschku.libquassel.protocol.primitive.serializer.HandshakeVariantMapSerializer @@ -9,8 +10,8 @@ import de.kuschku.libquassel.protocol.primitive.serializer.VariantListSerializer import de.kuschku.libquassel.quassel.ProtocolFeature import de.kuschku.libquassel.util.compatibility.CompatibilityUtils import de.kuschku.libquassel.util.compatibility.HandlerService +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.* -import de.kuschku.libquassel.util.compatibility.log import de.kuschku.libquassel.util.hasFlag import de.kuschku.libquassel.util.helpers.hexDump import de.kuschku.libquassel.util.helpers.write @@ -24,9 +25,13 @@ import java.lang.Thread.UncaughtExceptionHandler import java.net.Socket import java.net.SocketException import java.nio.ByteBuffer +import javax.net.ssl.X509TrustManager class CoreConnection( - private val session: Session, + private val handler: ProtocolHandler, + private val clientData: ClientData, + private val features: Features, + private val trustManager: X509TrustManager, private val address: SocketAddress, private val handlerService: HandlerService ) : Thread(), Closeable { @@ -67,13 +72,13 @@ class CoreConnection( IntSerializer.serialize( chainedBuffer, - 0x42b33f00 or session.clientData.protocolFeatures.toInt(), - session.negotiatedFeatures + 0x42b33f00 or clientData.protocolFeatures.toInt(), + features.negotiated ) - for (supportedProtocol in session.clientData.supportedProtocols) { - IntSerializer.serialize(chainedBuffer, supportedProtocol.toInt(), session.negotiatedFeatures) + for (supportedProtocol in clientData.supportedProtocols) { + IntSerializer.serialize(chainedBuffer, supportedProtocol.toInt(), features.negotiated) } - IntSerializer.serialize(chainedBuffer, 1 shl 31, session.negotiatedFeatures) + IntSerializer.serialize(chainedBuffer, 1 shl 31, features.negotiated) channel?.write(chainedBuffer) channel?.flush() } @@ -82,13 +87,13 @@ class CoreConnection( sizeBuffer.clear() channel?.read(sizeBuffer) sizeBuffer.flip() - val protocol = ProtocolInfoSerializer.deserialize(sizeBuffer, session.negotiatedFeatures) + val protocol = ProtocolInfoSerializer.deserialize(sizeBuffer, features.negotiated) log(DEBUG, TAG, "Protocol negotiated $protocol") // Wrap socket in SSL context if ssl is enabled if (protocol.flags.hasFlag(ProtocolFeature.TLS)) { - channel = channel?.withSSL(session.trustManager, address) + channel = channel?.withSSL(trustManager, address) } // Wrap socket in deflater if compression is enabled @@ -102,10 +107,10 @@ class CoreConnection( // Send client clientData to core dispatch( HandshakeMessage.ClientInit( - clientVersion = session.clientData.identifier, + clientVersion = clientData.identifier, buildDate = DateTimeFormatter.ofPattern("MMM dd yyyy HH:mm:ss") - .format(session.clientData.buildDate.atOffset(ZoneOffset.UTC)), - clientFeatures = session.clientData.clientFeatures + .format(clientData.buildDate.atOffset(ZoneOffset.UTC)), + clientFeatures = clientData.clientFeatures ) ) } @@ -132,7 +137,7 @@ class CoreConnection( handlerService.write( MessageRunnable( data, HandshakeVariantMapSerializer, chainedBuffer, channel, - session.negotiatedFeatures + features.negotiated ) ) } catch (e: Throwable) { @@ -148,7 +153,7 @@ class CoreConnection( handlerService.write( MessageRunnable( data, VariantListSerializer, chainedBuffer, channel, - session.negotiatedFeatures + features.negotiated ) ) } catch (e: Throwable) { @@ -168,7 +173,7 @@ class CoreConnection( break sizeBuffer.flip() - val size = IntSerializer.deserialize(sizeBuffer, session.negotiatedFeatures) + val size = IntSerializer.deserialize(sizeBuffer, features.negotiated) if (size > 64 * 1024 * 1024) throw SocketException("Too large frame received: $size") val dataBuffer = ByteBuffer.allocateDirect(size) @@ -191,11 +196,11 @@ class CoreConnection( private fun processSigProxy(dataBuffer: ByteBuffer) { try { val msg = SignalProxyMessage.deserialize( - VariantListSerializer.deserialize(dataBuffer, session.negotiatedFeatures) + VariantListSerializer.deserialize(dataBuffer, features.negotiated) ) handlerService.handle { try { - session.handle(msg) + handler.handle(msg) } catch (e: Throwable) { log(WARN, TAG, "Error encountered while handling sigproxy message", e) log(WARN, TAG, msg.toString()) @@ -210,10 +215,10 @@ class CoreConnection( private fun processHandshake(dataBuffer: ByteBuffer) { try { val msg = HandshakeMessage.deserialize( - HandshakeVariantMapSerializer.deserialize(dataBuffer, session.negotiatedFeatures) + HandshakeVariantMapSerializer.deserialize(dataBuffer, features.negotiated) ) try { - session.handle(msg) + handler.handle(msg) } catch (e: Throwable) { log(WARN, TAG, "Error encountered while handling handshake message", e) log(WARN, TAG, msg.toString()) diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Features.kt b/lib/src/main/java/de/kuschku/libquassel/session/Features.kt new file mode 100644 index 000000000..3c9b09535 --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/session/Features.kt @@ -0,0 +1,12 @@ +package de.kuschku.libquassel.session + +import de.kuschku.libquassel.protocol.Quassel_Features +import de.kuschku.libquassel.util.and + +data class Features( + var client: Quassel_Features, + var core: Quassel_Features +) { + val negotiated: Quassel_Features + get() = core and client +} \ No newline at end of file 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 862b13a4d..d594b2a48 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt @@ -11,8 +11,7 @@ import javax.net.ssl.SSLSession interface ISession : Closeable { val state: Observable<ConnectionState> - val coreFeatures: Quassel_Features - val negotiatedFeatures: Quassel_Features + val features: Features val sslSession: SSLSession? val aliasManager: AliasManager? @@ -35,8 +34,7 @@ interface ISession : Closeable { companion object { val NULL = object : ISession { override val state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED) - override val coreFeatures: Quassel_Features = Quassel_Features.of() - override val negotiatedFeatures: Quassel_Features = Quassel_Features.of() + override val features: Features = Features(Quassel_Features.of(), Quassel_Features.of()) override val sslSession: SSLSession? = null override val rpcHandler: RpcHandler? = null diff --git a/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt index f48594eb6..d253ac080 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt @@ -2,8 +2,8 @@ package de.kuschku.libquassel.session import de.kuschku.libquassel.protocol.Quassel_Features import de.kuschku.libquassel.protocol.primitive.serializer.Serializer +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN -import de.kuschku.libquassel.util.compatibility.log import de.kuschku.libquassel.util.helpers.write import de.kuschku.libquassel.util.nio.ChainedByteBuffer import de.kuschku.libquassel.util.nio.WrappedChannel diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt index 867596176..b1703df15 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt @@ -7,9 +7,9 @@ import de.kuschku.libquassel.quassel.exceptions.ObjectNotFoundException import de.kuschku.libquassel.quassel.syncables.RpcHandler import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject import de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invokers +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN -import de.kuschku.libquassel.util.compatibility.log import org.threeten.bp.Instant import java.io.Closeable 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 7fc5c5e61..c3d919157 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -5,32 +5,31 @@ import de.kuschku.libquassel.protocol.message.HandshakeMessage import de.kuschku.libquassel.protocol.message.SignalProxyMessage import de.kuschku.libquassel.quassel.QuasselFeature import de.kuschku.libquassel.quassel.syncables.* -import de.kuschku.libquassel.util.and import de.kuschku.libquassel.util.compatibility.HandlerService +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO -import de.kuschku.libquassel.util.compatibility.log import de.kuschku.libquassel.util.hasFlag import io.reactivex.subjects.BehaviorSubject import org.threeten.bp.Instant import javax.net.ssl.X509TrustManager class Session( - val clientData: ClientData, - val trustManager: X509TrustManager, + clientData: ClientData, + trustManager: X509TrustManager, address: SocketAddress, handlerService: HandlerService, backlogStorage: BacklogStorage, private val userData: Pair<String, String> ) : ProtocolHandler(), ISession { - override var coreFeatures: Quassel_Features = Quassel_Feature.NONE - override val negotiatedFeatures - get() = coreFeatures and clientData.clientFeatures + override val features = Features(clientData.clientFeatures, Quassel_Features.of()) override val sslSession get() = coreConnection.sslSession - private val coreConnection = CoreConnection(this, address, handlerService) + private val coreConnection = CoreConnection( + this, clientData, features, trustManager, address, handlerService + ) override val state = coreConnection.state override val aliasManager = AliasManager(this) @@ -57,7 +56,7 @@ class Session( } override fun handle(f: HandshakeMessage.ClientInitAck): Boolean { - coreFeatures = f.coreFeatures ?: Quassel_Feature.NONE + features.core = f.coreFeatures ?: Quassel_Feature.NONE dispatch( HandshakeMessage.ClientLogin( user = userData.first, @@ -97,7 +96,7 @@ class Session( synchronize(bufferSyncer, true) synchronize(bufferViewManager, true) synchronize(coreInfo, true) - if (negotiatedFeatures.hasFlag(QuasselFeature.DccFileTransfer)) + if (features.negotiated.hasFlag(QuasselFeature.DccFileTransfer)) synchronize(dccConfig, true) synchronize(ignoreListManager, true) synchronize(ircListHelper, true) diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt index a657f67f5..6507e00e7 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt @@ -3,12 +3,11 @@ package de.kuschku.libquassel.session import de.kuschku.libquassel.protocol.ClientData import de.kuschku.libquassel.protocol.IdentityId import de.kuschku.libquassel.protocol.NetworkId -import de.kuschku.libquassel.protocol.Quassel_Features import de.kuschku.libquassel.quassel.syncables.* import de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invokers import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.libquassel.util.compatibility.LoggingHandler -import de.kuschku.libquassel.util.compatibility.log +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.helpers.or import io.reactivex.Observable import io.reactivex.functions.BiFunction @@ -17,10 +16,8 @@ import javax.net.ssl.SSLSession import javax.net.ssl.X509TrustManager class SessionManager(offlineSession: ISession, val backlogStorage: BacklogStorage) : ISession { - override val coreFeatures: Quassel_Features - get() = session.or(lastSession).coreFeatures - override val negotiatedFeatures: Quassel_Features - get() = session.or(lastSession).negotiatedFeatures + override val features: Features + get() = session.or(lastSession).features override val sslSession: SSLSession? get() = session.or(lastSession).sslSession override val aliasManager: AliasManager? diff --git a/lib/src/main/java/de/kuschku/libquassel/util/compatibility/LoggingHandler.kt b/lib/src/main/java/de/kuschku/libquassel/util/compatibility/LoggingHandler.kt index 73aa925a3..efc5ab6e3 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/compatibility/LoggingHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/compatibility/LoggingHandler.kt @@ -32,15 +32,15 @@ abstract class LoggingHandler { companion object { val loggingHandlers: MutableSet<LoggingHandler> = mutableSetOf(JavaLoggingHandler) - } -} -inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, message: String? = null, - throwable: Throwable? = null) { - LoggingHandler.loggingHandlers - .filter { it.isLoggable(logLevel, tag) } - .forEach { it.log(logLevel, tag, message, throwable) } -} + inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, message: String? = null, + throwable: Throwable? = null) { + LoggingHandler.loggingHandlers + .filter { it.isLoggable(logLevel, tag) } + .forEach { it.log(logLevel, tag, message, throwable) } + } -inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, throwable: Throwable? = null) - = log(logLevel, tag, null, throwable) + inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, throwable: Throwable? = null) = + log(logLevel, tag, null, throwable) + } +} diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt index 279bb3f85..8198d4ddf 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt @@ -1,7 +1,7 @@ package de.kuschku.libquassel.util.helpers +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN -import de.kuschku.libquassel.util.compatibility.log fun ByteArray.hexDump() { for (i in 0 until this.size step 33) { diff --git a/settings.gradle b/settings.gradle index 89d849405..c9875a387 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ -include ':invokerannotations', ':invokergenerator', ':lib', ':malheur', ':app', ":slidingpanel" +include ':invokerannotations', ':invokergenerator', ':lib', ':malheur', ':app', ":slidingpanel", ":viewmodel" rootProject.buildFileName = 'build.gradle.kts' diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts new file mode 100644 index 000000000..0be2deb0b --- /dev/null +++ b/viewmodel/build.gradle.kts @@ -0,0 +1,43 @@ +plugins { + id("com.android.library") + kotlin("android") + kotlin("kapt") +} + +android { + compileSdkVersion(27) + buildToolsVersion("27.0.3") + + defaultConfig { + minSdkVersion(16) + targetSdkVersion(27) + + consumerProguardFiles("proguard-rules.pro") + } +} + +dependencies { + implementation(kotlin("stdlib", "1.2.30")) + + // App Compat + withVersion("27.1.0") { + implementation("com.android.support", "appcompat-v7", version) + } + + // App Arch Lifecycle + withVersion("1.1.0") { + implementation("android.arch.lifecycle", "extensions", version) + implementation("android.arch.lifecycle", "reactivestreams", version) + kapt("android.arch.lifecycle", "compiler", version) + } + + // Utility + implementation("io.reactivex.rxjava2", "rxjava", "2.1.9") + implementation("org.threeten", "threetenbp", "1.3.6", classifier = "no-tzdb") + implementation("org.jetbrains", "annotations", "15.0") + + // Quassel + implementation(project(":lib")) { + exclude(group = "org.threeten", module = "threetenbp") + } +} \ No newline at end of file diff --git a/viewmodel/proguard-rules.pro b/viewmodel/proguard-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/viewmodel/src/main/AndroidManifest.xml b/viewmodel/src/main/AndroidManifest.xml new file mode 100644 index 000000000..834be4710 --- /dev/null +++ b/viewmodel/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest package="de.kuschku.quasseldroid_ng.viewmodel"></manifest> diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataHelper.kt similarity index 100% rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataHelper.kt rename to viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataHelper.kt diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt similarity index 97% rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt rename to viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt index 47836fb30..7e650dece 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/LiveDataZipHelper.kt @@ -93,7 +93,8 @@ fun <A, B, C> zipLiveData(a: LiveData<A>, b: LiveData<B>, * @see zipLiveData * @author Mitchell Skaggs */ -fun <A, B> LiveData<A>.zip(b: LiveData<B>): LiveData<Pair<A, B>> = zipLiveData(this, b) +fun <A, B> LiveData<A>.zip(b: LiveData<B>): LiveData<Pair<A, B>> = + zipLiveData(this, b) /** * This is merely an extension function for [zipLiveData]. @@ -102,4 +103,5 @@ fun <A, B> LiveData<A>.zip(b: LiveData<B>): LiveData<Pair<A, B>> = zipLiveData(t * @author Mitchell Skaggs */ fun <A, B, C> LiveData<A>.zip(b: LiveData<B>, - c: LiveData<C>): LiveData<Triple<A, B, C>> = zipLiveData(this, b, c) \ No newline at end of file + c: LiveData<C>): LiveData<Triple<A, B, C>> = + zipLiveData(this, b, c) \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ObservableHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ObservableHelper.kt similarity index 100% rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ObservableHelper.kt rename to viewmodel/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ObservableHelper.kt diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/QuasselViewModel.kt similarity index 77% rename from app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt rename to viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/QuasselViewModel.kt index fa61f0f23..7aca16bb7 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/QuasselViewModel.kt @@ -1,4 +1,4 @@ -package de.kuschku.quasseldroid_ng.ui.viewmodel +package de.kuschku.quasseldroid_ng.viewmodel import android.arch.lifecycle.LiveData import android.arch.lifecycle.MutableLiveData @@ -13,15 +13,10 @@ import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.ISession -import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.util.and import de.kuschku.libquassel.util.hasFlag -import de.kuschku.quasseldroid_ng.ui.chat.ToolbarFragment -import de.kuschku.quasseldroid_ng.ui.chat.buffers.BufferListAdapter -import de.kuschku.quasseldroid_ng.ui.chat.buffers.BufferViewConfigFragment -import de.kuschku.quasseldroid_ng.ui.chat.input.AutoCompleteAdapter -import de.kuschku.quasseldroid_ng.ui.chat.nicks.NickListAdapter import de.kuschku.quasseldroid_ng.util.helper.* +import de.kuschku.quasseldroid_ng.viewmodel.data.* import io.reactivex.Observable import java.util.concurrent.TimeUnit @@ -37,10 +32,10 @@ class QuasselViewModel : ViewModel() { this.buffer.value = buffer } - private val bufferViewConfig = MutableLiveData<BufferViewConfig?>() - fun getBufferViewConfig(): LiveData<BufferViewConfig?> = bufferViewConfig - fun setBufferViewConfig(bufferViewConfig: BufferViewConfig?) { - this.bufferViewConfig.value = bufferViewConfig + private val bufferViewConfigId = MutableLiveData<Int?>() + fun getBufferViewConfigId(): LiveData<Int?> = bufferViewConfigId + fun setBufferViewConfigId(bufferViewConfig: Int?) { + this.bufferViewConfigId.value = bufferViewConfig } val MAX_RECENT_MESSAGES = 20 @@ -61,6 +56,12 @@ class QuasselViewModel : ViewModel() { private val bufferViewManager = session.map(ISession::bufferViewManager) + val bufferViewConfig = bufferViewManager.switchMap { manager -> + bufferViewConfigId.map { id -> + manager.bufferViewConfig(id) + } + } + private var lastMarkerLine = -1 /** * An observable of the changes of the markerline, as pairs of `(old, new)` @@ -87,10 +88,9 @@ class QuasselViewModel : ViewModel() { } } - val lag: LiveData<Long?> = sessionManager.switchMapRx { it.session.switchMap { it.lag } } + val lag: LiveData<Long?> = session.switchMapRx(ISession::lag) - val isSecure: LiveData<Boolean?> = sessionManager.switchMapRx(SessionManager::session) - .switchMapRx { session -> + val isSecure: LiveData<Boolean?> = session.switchMapRx { session -> session.state.map { _ -> session.sslSession != null } @@ -103,13 +103,13 @@ class QuasselViewModel : ViewModel() { val info = bufferSyncer.bufferInfo(id) val network = session.networks[info?.networkId] if (info == null || network == null) { - Observable.just(ToolbarFragment.BufferData()) + Observable.just(BufferData()) } else { when (info.type.toInt()) { BufferInfo.Type.QueryBuffer.toInt() -> { network.liveIrcUser(info.bufferName).switchMap { user -> user.liveRealName().map { realName -> - ToolbarFragment.BufferData( + BufferData( info = info, network = network.networkInfo(), description = realName @@ -122,7 +122,7 @@ class QuasselViewModel : ViewModel() { info.bufferName ).switchMap { channel -> channel.liveTopic().map { topic -> - ToolbarFragment.BufferData( + BufferData( info = info, network = network.networkInfo(), description = topic @@ -132,14 +132,14 @@ class QuasselViewModel : ViewModel() { } BufferInfo.Type.StatusBuffer.toInt() -> { network.liveConnectionState.map { - ToolbarFragment.BufferData( + BufferData( info = info, network = network.networkInfo() ) } } else -> Observable.just( - ToolbarFragment.BufferData( + BufferData( description = "type is unknown: ${info.type.toInt()}" ) ) @@ -147,11 +147,11 @@ class QuasselViewModel : ViewModel() { } } } else { - Observable.just(ToolbarFragment.BufferData()) + Observable.just(BufferData()) } } - val nickData: LiveData<List<NickListAdapter.IrcUserItem>?> = session.zip( + val nickData: LiveData<List<IrcUserItem>?> = session.zip( buffer ).switchMapRx { (session, buffer) -> val bufferSyncer = session?.bufferSyncer @@ -161,8 +161,8 @@ class QuasselViewModel : ViewModel() { val ircChannel = network?.ircChannel(bufferInfo.bufferName) if (ircChannel != null) { ircChannel.liveIrcUsers().switchMap { users -> - combineLatest<NickListAdapter.IrcUserItem>( - users.map<IrcUser, Observable<NickListAdapter.IrcUserItem>?> { user -> + combineLatest<IrcUserItem>( + users.map<IrcUser, Observable<IrcUserItem>?> { user -> user.liveNick().switchMap { nick -> user.liveRealName().switchMap { realName -> user.liveIsAway().map { away -> @@ -173,7 +173,7 @@ class QuasselViewModel : ViewModel() { prefixModes.indexOf(it) }.min() ?: prefixModes.size - NickListAdapter.IrcUserItem( + IrcUserItem( nick, network.modesToPrefixes(userModes), lowestMode, @@ -196,7 +196,7 @@ class QuasselViewModel : ViewModel() { val lastWord = MutableLiveData<Observable<Pair<String, IntRange>>>() - val autoCompleteData: LiveData<Pair<String, List<AutoCompleteAdapter.AutoCompleteItem>>?> = session.zip( + val autoCompleteData: LiveData<Pair<String, List<AutoCompleteItem>>?> = session.zip( buffer, lastWord ).switchMapRx { (session, id, lastWordWrapper) -> lastWordWrapper @@ -216,29 +216,29 @@ class QuasselViewModel : ViewModel() { ) if (ircChannel != null) { ircChannel.liveIrcUsers().switchMap { users -> - val buffers: List<Observable<AutoCompleteAdapter.AutoCompleteItem.ChannelItem>?> = infos.values + val buffers: List<Observable<AutoCompleteItem.ChannelItem>?> = infos.values .filter { it.type.toInt() == Buffer_Type.ChannelBuffer.toInt() }.mapNotNull { info -> session.networks[info.networkId]?.let { info to it } - }.map<Pair<BufferInfo, Network>, Observable<AutoCompleteAdapter.AutoCompleteItem.ChannelItem>?> { (info, network) -> + }.map<Pair<BufferInfo, Network>, Observable<AutoCompleteItem.ChannelItem>?> { (info, network) -> network.liveIrcChannel( info.bufferName ).switchMap { channel -> channel.liveTopic().map { topic -> - AutoCompleteAdapter.AutoCompleteItem.ChannelItem( + AutoCompleteItem.ChannelItem( info = info, network = network.networkInfo(), bufferStatus = when (channel) { - IrcChannel.NULL -> BufferListAdapter.BufferStatus.OFFLINE - else -> BufferListAdapter.BufferStatus.ONLINE + IrcChannel.NULL -> BufferStatus.OFFLINE + else -> BufferStatus.ONLINE }, description = topic ) } } } - val nicks = users.map<IrcUser, Observable<AutoCompleteAdapter.AutoCompleteItem.UserItem>?> { user -> + val nicks = users.map<IrcUser, Observable<AutoCompleteItem.UserItem>?> { user -> user.liveNick().switchMap { nick -> user.liveRealName().switchMap { realName -> user.liveIsAway().map { away -> @@ -253,7 +253,7 @@ class QuasselViewModel : ViewModel() { ) }.min() ?: prefixModes.size - AutoCompleteAdapter.AutoCompleteItem.UserItem( + AutoCompleteItem.UserItem( nick, network.modesToPrefixes( userModes @@ -270,7 +270,7 @@ class QuasselViewModel : ViewModel() { } } - combineLatest<AutoCompleteAdapter.AutoCompleteItem>(nicks + buffers) + combineLatest<AutoCompleteItem>(nicks + buffers) .map { list -> val ignoredStartingCharacters = charArrayOf( '-', '_', '[', ']', '{', '}', '|', '`', '^', '.', '\\' @@ -324,11 +324,11 @@ class QuasselViewModel : ViewModel() { if (bufferSyncer != null && bufferViewConfig != null) { val hiddenState = when { bufferViewConfig.removedBuffers().contains(buffer) -> - BufferListAdapter.HiddenState.HIDDEN_PERMANENT + BufferHiddenState.HIDDEN_PERMANENT bufferViewConfig.temporarilyRemovedBuffers().contains(buffer) -> - BufferListAdapter.HiddenState.HIDDEN_TEMPORARY + BufferHiddenState.HIDDEN_TEMPORARY else -> - BufferListAdapter.HiddenState.VISIBLE + BufferHiddenState.VISIBLE } val info = bufferSyncer.bufferInfo(buffer) @@ -337,7 +337,7 @@ class QuasselViewModel : ViewModel() { when (info.type.enabledValues().firstOrNull()) { Buffer_Type.StatusBuffer -> { network?.liveConnectionState?.map { - BufferViewConfigFragment.SelectedItem( + SelectedBufferItem( info, connectionState = it, hiddenState = hiddenState @@ -346,7 +346,7 @@ class QuasselViewModel : ViewModel() { } Buffer_Type.ChannelBuffer -> { network?.liveIrcChannel(info.bufferName)?.map { - BufferViewConfigFragment.SelectedItem( + SelectedBufferItem( info, joined = it != IrcChannel.NULL, hiddenState = hiddenState @@ -354,17 +354,17 @@ class QuasselViewModel : ViewModel() { } } else -> - Observable.just(BufferViewConfigFragment.SelectedItem(info, hiddenState = hiddenState)) + Observable.just(SelectedBufferItem(info, hiddenState = hiddenState)) } } else { - Observable.just(BufferViewConfigFragment.SelectedItem(info, hiddenState = hiddenState)) + Observable.just(SelectedBufferItem(info, hiddenState = hiddenState)) } } else { - Observable.just(BufferViewConfigFragment.SelectedItem()) + Observable.just(SelectedBufferItem()) } } - val bufferList: LiveData<Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>?> = session.zip( + val bufferList: LiveData<Pair<BufferViewConfig?, List<BufferProps>>?> = session.zip( bufferViewConfig, showHidden ).switchMapRx { (session, config, showHiddenRaw) -> val bufferSyncer = session?.bufferSyncer @@ -378,7 +378,7 @@ class QuasselViewModel : ViewModel() { config.live_removedBuffers ) ).switchMap { (ids, temp, perm) -> - fun transformIds(ids: Collection<BufferId>, state: BufferListAdapter.HiddenState) = + fun transformIds(ids: Collection<BufferId>, state: BufferHiddenState) = ids.mapNotNull { id -> bufferSyncer.bufferInfo(id) }.filter { @@ -393,7 +393,7 @@ class QuasselViewModel : ViewModel() { } else { it to network } - }.map<Pair<BufferInfo, Network>, Observable<BufferListAdapter.BufferProps>?> { (info, network) -> + }.map<Pair<BufferInfo, Network>, Observable<BufferProps>?> { (info, network) -> bufferSyncer.liveActivity(info.bufferId).switchMap { activity -> bufferSyncer.liveHighlightCount(info.bufferId).map { highlights -> activity to highlights @@ -404,13 +404,13 @@ class QuasselViewModel : ViewModel() { network.liveIrcUser(info.bufferName).switchMap { user -> user.liveIsAway().switchMap { away -> user.liveRealName().map { realName -> - BufferListAdapter.BufferProps( + BufferProps( info = info, network = network.networkInfo(), bufferStatus = when { - user == IrcUser.NULL -> BufferListAdapter.BufferStatus.OFFLINE - away -> BufferListAdapter.BufferStatus.AWAY - else -> BufferListAdapter.BufferStatus.ONLINE + user == IrcUser.NULL -> BufferStatus.OFFLINE + away -> BufferStatus.AWAY + else -> BufferStatus.ONLINE }, description = realName, activity = activity, @@ -426,12 +426,12 @@ class QuasselViewModel : ViewModel() { info.bufferName ).switchMap { channel -> channel.liveTopic().map { topic -> - BufferListAdapter.BufferProps( + BufferProps( info = info, network = network.networkInfo(), bufferStatus = when (channel) { - IrcChannel.NULL -> BufferListAdapter.BufferStatus.OFFLINE - else -> BufferListAdapter.BufferStatus.ONLINE + IrcChannel.NULL -> BufferStatus.OFFLINE + else -> BufferStatus.ONLINE }, description = topic, activity = activity, @@ -443,10 +443,10 @@ class QuasselViewModel : ViewModel() { } BufferInfo.Type.StatusBuffer.toInt() -> { network.liveConnectionState.map { - BufferListAdapter.BufferProps( + BufferProps( info = info, network = network.networkInfo(), - bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, + bufferStatus = BufferStatus.OFFLINE, description = "", activity = activity, highlights = highlights, @@ -455,10 +455,10 @@ class QuasselViewModel : ViewModel() { } } else -> Observable.just( - BufferListAdapter.BufferProps( + BufferProps( info = info, network = network.networkInfo(), - bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, + bufferStatus = BufferStatus.OFFLINE, description = "", activity = activity, highlights = highlights, @@ -471,19 +471,19 @@ class QuasselViewModel : ViewModel() { bufferSyncer.liveBufferInfos().switchMap { val buffers = if (showHidden) { - transformIds(ids, BufferListAdapter.HiddenState.VISIBLE) + - transformIds(temp, BufferListAdapter.HiddenState.HIDDEN_TEMPORARY) + - transformIds(perm, BufferListAdapter.HiddenState.HIDDEN_PERMANENT) + transformIds(ids, BufferHiddenState.VISIBLE) + + transformIds(temp, BufferHiddenState.HIDDEN_TEMPORARY) + + transformIds(perm, BufferHiddenState.HIDDEN_PERMANENT) } else { - transformIds(ids, BufferListAdapter.HiddenState.VISIBLE) + transformIds(ids, BufferHiddenState.VISIBLE) } - combineLatest<BufferListAdapter.BufferProps>(buffers).map { list -> - Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>( + combineLatest<BufferProps>(buffers).map { list -> + Pair<BufferViewConfig?, List<BufferProps>>( config, list.filter { (!config.hideInactiveBuffers()) || - it.bufferStatus != BufferListAdapter.BufferStatus.OFFLINE || + it.bufferStatus != BufferStatus.OFFLINE || it.info.type.hasFlag(Buffer_Type.StatusBuffer) }) } @@ -492,7 +492,7 @@ class QuasselViewModel : ViewModel() { } } else { Observable.just( - Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>(null, emptyList()) + Pair<BufferViewConfig?, List<BufferProps>>(null, emptyList()) ) } } diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/AutoCompleteItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/AutoCompleteItem.kt new file mode 100644 index 000000000..0a27fcbed --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/AutoCompleteItem.kt @@ -0,0 +1,32 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +import de.kuschku.libquassel.quassel.BufferInfo +import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork + +sealed class AutoCompleteItem(open val name: String) : Comparable<AutoCompleteItem> { + override fun compareTo(other: AutoCompleteItem): Int { + return when { + this is UserItem && + other is ChannelItem -> -1 + this is ChannelItem && + other is UserItem -> 1 + else -> this.name.compareTo(other.name) + } + } + + data class UserItem( + val nick: String, + val modes: String, + val lowestMode: Int, + val realname: CharSequence, + val away: Boolean, + val networkCasemapping: String + ) : AutoCompleteItem(nick) + + data class ChannelItem( + val info: BufferInfo, + val network: INetwork.NetworkInfo, + val bufferStatus: BufferStatus, + val description: CharSequence + ) : AutoCompleteItem(info.bufferName ?: "") +} \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferData.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferData.kt new file mode 100644 index 000000000..915a98732 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferData.kt @@ -0,0 +1,10 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +import de.kuschku.libquassel.quassel.BufferInfo +import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork + +data class BufferData( + val info: BufferInfo? = null, + val network: INetwork.NetworkInfo? = null, + val description: String? = null +) \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferHiddenState.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferHiddenState.kt new file mode 100644 index 000000000..619839530 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferHiddenState.kt @@ -0,0 +1,8 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +enum class BufferHiddenState { + VISIBLE, + HIDDEN_TEMPORARY, + HIDDEN_PERMANENT +} + diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferListItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferListItem.kt new file mode 100644 index 000000000..27243657b --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferListItem.kt @@ -0,0 +1,6 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +data class BufferListItem( + val props: BufferProps, + val state: BufferState +) \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferProps.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferProps.kt new file mode 100644 index 000000000..53757d484 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferProps.kt @@ -0,0 +1,19 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +import de.kuschku.libquassel.protocol.Buffer_Activities +import de.kuschku.libquassel.protocol.Message_Types +import de.kuschku.libquassel.quassel.BufferInfo +import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork + +data class BufferProps( + val info: BufferInfo, + val network: INetwork.NetworkInfo, + val bufferStatus: BufferStatus, + val description: CharSequence, + val activity: Message_Types, + val highlights: Int = 0, + val bufferActivity: Buffer_Activities = BufferInfo.Activity.of( + BufferInfo.Activity.NoActivity + ), + val hiddenState: BufferHiddenState +) \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferState.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferState.kt new file mode 100644 index 000000000..361a42da6 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferState.kt @@ -0,0 +1,6 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +data class BufferState( + val networkExpanded: Boolean, + val selected: Boolean +) \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferStatus.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferStatus.kt new file mode 100644 index 000000000..d182f0f9b --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/BufferStatus.kt @@ -0,0 +1,7 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +enum class BufferStatus { + ONLINE, + AWAY, + OFFLINE +} \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/IrcUserItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/IrcUserItem.kt new file mode 100644 index 000000000..ce9af2f2b --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/IrcUserItem.kt @@ -0,0 +1,10 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +data class IrcUserItem( + val nick: String, + val modes: String, + val lowestMode: Int, + val realname: CharSequence, + val away: Boolean, + val networkCasemapping: String +) \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/SelectedBufferItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/SelectedBufferItem.kt new file mode 100644 index 000000000..617f50e0c --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid_ng/viewmodel/data/SelectedBufferItem.kt @@ -0,0 +1,11 @@ +package de.kuschku.quasseldroid_ng.viewmodel.data + +import de.kuschku.libquassel.quassel.BufferInfo +import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork + +data class SelectedBufferItem( + val info: BufferInfo? = null, + val connectionState: INetwork.ConnectionState = INetwork.ConnectionState.Disconnected, + val joined: Boolean = false, + val hiddenState: BufferHiddenState = BufferHiddenState.VISIBLE +) \ No newline at end of file -- GitLab