From 3112743845591add35e71bcf141a430ddb2f3b08 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Tue, 14 May 2019 19:19:29 +0200 Subject: [PATCH] Refactor Session Management - Implements a cleaner state machine for session states - Updates RxJava - Improves auto reconnection handling --- app/build.gradle.kts | 1 + .../quasseldroid/service/AsyncBackend.kt | 31 ++- .../quasseldroid/service/BacklogRequester.kt | 2 +- .../quasseldroid/service/QuasselBinder.kt | 2 +- .../service/QuasselNotificationBackend.kt | 5 +- .../quasseldroid/service/QuasselService.kt | 132 ++++++------- .../quasseldroid/ui/chat/ChatActivity.kt | 122 ++++++------ .../quasseldroid/ui/chat/ToolbarFragment.kt | 8 +- .../chat/add/create/ChannelCreateFragment.kt | 10 +- .../ui/chat/add/join/ChannelJoinFragment.kt | 2 +- .../ui/chat/add/query/QueryCreateFragment.kt | 6 +- .../chat/buffers/BufferViewConfigFragment.kt | 20 +- .../ui/chat/input/AutoCompleteHelper.kt | 4 +- .../ui/chat/input/ChatlineFragment.kt | 3 +- .../ui/chat/messages/MessageListFragment.kt | 24 ++- .../ui/chat/nicks/NickListAdapter.kt | 2 +- .../ui/chat/nicks/NickListFragment.kt | 4 +- .../ui/chat/topic/TopicFragment.kt | 4 +- .../ui/coresettings/CoreSettingsFragment.kt | 2 +- .../chatlist/ChatListBaseFragment.kt | 4 +- .../chatlist/ChatListCreateFragment.kt | 2 +- .../chatlist/ChatListEditFragment.kt | 2 +- .../identity/IdentityBaseFragment.kt | 2 +- .../identity/IdentityCreateFragment.kt | 4 +- .../identity/IdentityEditFragment.kt | 4 +- .../network/NetworkBaseFragment.kt | 8 +- .../network/NetworkCreateFragment.kt | 6 +- .../network/NetworkEditFragment.kt | 4 +- .../passwordchange/PasswordChangeFragment.kt | 10 +- .../ui/info/channel/ChannelInfoFragment.kt | 10 +- .../info/channellist/ChannelListFragment.kt | 6 +- .../ui/info/core/CoreInfoFragment.kt | 5 +- .../ui/info/user/UserInfoFragment.kt | 12 +- .../ui/setup/ServiceBoundSetupActivity.kt | 8 +- .../ui/setup/ServiceBoundSlideFragment.kt | 6 +- .../quasseldroid/ui/setup/SetupActivity.kt | 2 +- .../ui/setup/core/CoreSetupActivity.kt | 2 +- .../ui/setup/network/NetworkSetupActivity.kt | 4 +- .../setup/network/NetworkSetupNetworkSlide.kt | 2 +- .../ui/setup/user/UserSetupActivity.kt | 4 +- .../ui/setup/user/UserSetupNetworkSlide.kt | 2 +- .../compatibility/AndroidLoggingHandler.kt | 4 +- .../util/helper/IntRangeHelper.kt | 2 +- .../util/service/BackendServiceConnection.kt | 2 +- .../util/service/ServiceBoundActivity.kt | 6 +- .../util/service/ServiceBoundFragment.kt | 6 +- .../quasseldroid/util/ui/ThemedActivity.kt | 2 +- .../libquassel/connection/CoreConnection.kt | 4 +- .../libquassel/connection/MessageRunnable.kt | 2 +- .../de/kuschku/libquassel/protocol/QTypes.kt | 2 +- .../protocol/coresetup/CoreSetupBackend.kt | 2 +- .../protocol/message/InitDataSerializer.kt | 4 +- .../protocol/message/InitRequestSerializer.kt | 4 +- .../protocol/message/RpcCallSerializer.kt | 4 +- .../protocol/message/SyncMessageSerializer.kt | 4 +- .../primitive/serializer/StringSerializer.kt | 2 +- .../quassel/syncables/BufferViewConfig.kt | 2 +- .../quassel/syncables/IrcChannel.kt | 2 +- .../libquassel/quassel/syncables/Network.kt | 4 +- .../quassel/syncables/RpcHandler.kt | 2 +- .../quassel/syncables/interfaces/INetwork.kt | 2 +- .../de/kuschku/libquassel/session/Error.kt | 3 +- .../de/kuschku/libquassel/session/ISession.kt | 35 ++-- .../libquassel/session/ObjectStorage.kt | 2 +- .../de/kuschku/libquassel/session/Session.kt | 21 ++- .../libquassel/session/SessionManager.kt | 178 +++++++----------- .../libquassel/session/SessionStateHandler.kt | 76 ++++++++ .../session/manager/ConnectionInfo.kt | 35 ++++ .../session/manager/SessionState.kt | 28 +++ .../util/compatibility/LoggingHandler.kt | 22 +-- .../reference/JavaLoggingHandler.kt | 4 +- .../de/kuschku/libquassel/util/flag/Flag.kt | 2 +- .../kuschku/libquassel/util/flag/LongFlag.kt | 2 +- .../kuschku/libquassel/util/flag/ShortFlag.kt | 2 +- .../util/{helpers => helper}/AnyHelper.kt | 2 +- .../util/{helpers => helper}/ArrayHelper.kt | 2 +- .../{helpers => helper}/ByteBufferHelper.kt | 2 +- .../{helpers => helper}/CollectionHelper.kt | 2 +- .../util/{helpers => helper}/MapHelper.kt | 2 +- .../util/{helpers => helper}/MathHelper.kt | 2 +- .../{helpers => helper}/ObservableHelper.kt | 82 +++++++- .../util/{helpers => helper}/StringHelper.kt | 2 +- .../WritableByteChannelHelper.kt | 2 +- .../java/de/kuschku/quasseldroid}/Backend.kt | 23 ++- .../util/helper/ObservableHelper.kt | 79 -------- .../viewmodel/QuasselViewModel.kt | 2 +- .../viewmodel/helper/ChatViewModelHelper.kt | 16 +- .../viewmodel/helper/EditorViewModelHelper.kt | 23 ++- .../helper/QuasselViewModelHelper.kt | 40 ++-- 89 files changed, 676 insertions(+), 570 deletions(-) create mode 100644 lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt create mode 100644 lib/src/main/java/de/kuschku/libquassel/session/manager/ConnectionInfo.kt create mode 100644 lib/src/main/java/de/kuschku/libquassel/session/manager/SessionState.kt rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/AnyHelper.kt (94%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/ArrayHelper.kt (96%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/ByteBufferHelper.kt (96%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/CollectionHelper.kt (97%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/MapHelper.kt (95%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/MathHelper.kt (95%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/ObservableHelper.kt (50%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/StringHelper.kt (96%) rename lib/src/main/java/de/kuschku/libquassel/util/{helpers => helper}/WritableByteChannelHelper.kt (95%) rename {lib/src/main/java/de/kuschku/libquassel/session => viewmodel/src/main/java/de/kuschku/quasseldroid}/Backend.kt (68%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index afa441c01..c1c6b5bb7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -140,6 +140,7 @@ dependencies { implementation("commons-codec", "commons-codec", "1.12") implementation("com.squareup.retrofit2", "retrofit", "2.5.0") implementation("com.squareup.retrofit2", "converter-gson", "2.5.0") + implementation("com.github.pwittchen", "reactivenetwork-rx2", "3.0.2") withVersion("10.1.0") { implementation("com.jakewharton", "butterknife", version) kapt("com.jakewharton", "butterknife-compiler", version) diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt index 1068e7be8..33a022c3e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt @@ -19,9 +19,8 @@ package de.kuschku.quasseldroid.service -import de.kuschku.libquassel.connection.SocketAddress -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.compatibility.HandlerService +import de.kuschku.quasseldroid.Backend class AsyncBackend( private val handler: HandlerService, @@ -39,23 +38,19 @@ class AsyncBackend( } } - override fun connectUnlessConnected(address: SocketAddress, user: String, pass: String, - requireSsl: Boolean, reconnect: Boolean) { + override fun autoConnect( + ignoreConnectionState: Boolean, + ignoreSetting: Boolean, + ignoreErrors: Boolean, + connectionInfo: Backend.ConnectionInfo? + ) { handler.backend { - backend.connectUnlessConnected(address, user, pass, requireSsl, reconnect) - } - } - - override fun connect(address: SocketAddress, user: String, pass: String, requireSsl: Boolean, - reconnect: Boolean) { - handler.backend { - backend.connect(address, user, pass, requireSsl, reconnect) - } - } - - override fun reconnect() { - handler.backend { - backend.reconnect() + backend.autoConnect( + ignoreConnectionState, + ignoreSetting, + ignoreErrors, + connectionInfo + ) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt b/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt index 40bfc7d69..cdbfe21cf 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt @@ -26,7 +26,7 @@ import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.persistence.dao.findFirstByBufferId import de.kuschku.quasseldroid.persistence.dao.get import de.kuschku.quasseldroid.persistence.db.AccountDatabase diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselBinder.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselBinder.kt index d4d7d450c..05a2a5dc3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselBinder.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselBinder.kt @@ -20,6 +20,6 @@ package de.kuschku.quasseldroid.service import android.os.Binder -import de.kuschku.libquassel.session.Backend +import de.kuschku.quasseldroid.Backend class QuasselBinder(val backend: Backend) : Binder() diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt index dba7e5d4f..03a89ce31 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt @@ -31,7 +31,8 @@ import de.kuschku.libquassel.quassel.syncables.IgnoreListManager import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.NotificationManager import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.clampOf +import de.kuschku.libquassel.util.helper.clampOf +import de.kuschku.libquassel.util.helper.or import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp @@ -259,7 +260,7 @@ class QuasselNotificationBackend @Inject constructor( this.showNotification(buffer) } }, - clampOf(session.lag.value * 3 + 100, 16, 3_000), + clampOf(session.lag.or(0) * 3 + 100, 16, 3_000), TimeUnit.MILLISECONDS ) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt index bf557b57d..ba8068b5a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt @@ -19,11 +19,14 @@ package de.kuschku.quasseldroid.service -import android.content.* -import android.net.ConnectivityManager +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences import android.text.SpannableString import androidx.core.app.RemoteInput import androidx.lifecycle.Observer +import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import de.kuschku.libquassel.connection.ConnectionState import de.kuschku.libquassel.connection.HostnameVerifier import de.kuschku.libquassel.connection.SocketAddress @@ -31,16 +34,16 @@ import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.Session import de.kuschku.libquassel.session.SessionManager -import de.kuschku.libquassel.util.compatibility.LoggingHandler +import de.kuschku.libquassel.session.manager.ConnectionInfo import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO -import de.kuschku.libquassel.util.helpers.clampOf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.clampOf +import de.kuschku.libquassel.util.helper.value import de.kuschku.malheur.CrashHandler +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.BuildConfig import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R @@ -64,9 +67,7 @@ import de.kuschku.quasseldroid.util.compatibility.AndroidHandlerService import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer import de.kuschku.quasseldroid.util.ui.LocaleHelper -import io.reactivex.subjects.PublishSubject import org.threeten.bp.Instant -import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.net.ssl.X509TrustManager @@ -117,12 +118,14 @@ class QuasselService : DaggerLifecycleService(), backendImplementation.disconnect(true) stopSelf() } else { - backendImplementation.connectUnlessConnected( - SocketAddress(account.host, account.port), - account.user, - account.pass, - account.requireSsl, - true + backendImplementation.autoConnect( + connectionInfo = Backend.ConnectionInfo( + SocketAddress(account.host, account.port), + account.user, + account.pass, + account.requireSsl, + true + ) ) } } @@ -185,7 +188,7 @@ class QuasselService : DaggerLifecycleService(), it.toString() to ircFormatSerializer.toEscapeCodes(SpannableString(it)) } - sessionManager.session.value?.let { session -> + sessionManager.connectedSession.value?.let { session -> session.bufferSyncer.bufferInfo(bufferId)?.also { bufferInfo -> val output = mutableListOf<IAliasManager.Command>() for ((_, formatted) in lines) { @@ -203,15 +206,17 @@ class QuasselService : DaggerLifecycleService(), } else { val clearMessageId = MsgId(intent.getLongExtra("mark_read_message", -1)) if (bufferId.isValidId() && clearMessageId.isValidId()) { - sessionManager.session.value?.bufferSyncer?.requestSetLastSeenMsg(bufferId, clearMessageId) - sessionManager.session.value?.bufferSyncer?.requestMarkBufferAsRead(bufferId) + sessionManager.connectedSession.value?.bufferSyncer?.requestSetLastSeenMsg(bufferId, + clearMessageId) + sessionManager.connectedSession.value?.bufferSyncer?.requestMarkBufferAsRead(bufferId) } val hideMessageId = MsgId(intent.getLongExtra("hide_message", -1)) if (bufferId.isValidId() && hideMessageId.isValidId()) { if (notificationSettings.markReadOnSwipe) { - sessionManager.session.value?.bufferSyncer?.requestSetLastSeenMsg(bufferId, hideMessageId) - sessionManager.session.value?.bufferSyncer?.requestMarkBufferAsRead(bufferId) + sessionManager.connectedSession.value?.bufferSyncer?.requestSetLastSeenMsg(bufferId, + hideMessageId) + sessionManager.connectedSession.value?.bufferSyncer?.requestMarkBufferAsRead(bufferId) } else { handlerService.backend { database.notifications().markHidden(bufferId, hideMessageId) @@ -277,36 +282,32 @@ class QuasselService : DaggerLifecycleService(), override fun sessionManager() = service?.sessionManager - override fun connectUnlessConnected(address: SocketAddress, user: String, pass: String, - requireSsl: Boolean, reconnect: Boolean) { + override fun autoConnect( + ignoreConnectionState: Boolean, + ignoreSetting: Boolean, + ignoreErrors: Boolean, + connectionInfo: Backend.ConnectionInfo? + ) { service?.apply { - sessionManager.ifDisconnected { - connect(address, user, pass, requireSsl, reconnect) - } - } - } - - override fun connect(address: SocketAddress, user: String, pass: String, requireSsl: Boolean, - reconnect: Boolean) { - service?.apply { - disconnect() - sessionManager.connect( - SessionManager.ConnectionInfo( - clientData = clientData, - trustManager = trustManager, - hostnameVerifier = hostnameVerifier, - address = address, - userData = Pair(user, pass), - requireSsl = requireSsl, - shouldReconnect = reconnect + if (connectionInfo != null) { + sessionManager.autoConnect( + ignoreConnectionState, + ignoreSetting, + ignoreErrors, + ConnectionInfo( + clientData = clientData, + trustManager = trustManager, + hostnameVerifier = hostnameVerifier, + address = connectionInfo.address, + userData = Pair(connectionInfo.username, + connectionInfo.password), + requireSsl = connectionInfo.requireSsl, + shouldReconnect = connectionInfo.shouldReconnect + ) ) - ) - } - } - - override fun reconnect() { - service?.apply { - sessionManager.reconnect() + } else { + sessionManager.autoConnect(ignoreConnectionState, ignoreSetting, ignoreErrors) + } } } @@ -318,8 +319,8 @@ class QuasselService : DaggerLifecycleService(), override fun requestConnectNewNetwork() { service?.apply { - sessionManager.session.flatMap(ISession::liveNetworkAdded).firstElement().flatMap { id -> - sessionManager.session.flatMap(ISession::liveNetworks) + sessionManager.connectedSession.flatMap(ISession::liveNetworkAdded).firstElement().flatMap { id -> + sessionManager.connectedSession.flatMap(ISession::liveNetworks) .map { it[id] } .flatMap { network -> network.liveInitialized @@ -345,18 +346,6 @@ class QuasselService : DaggerLifecycleService(), @Inject lateinit var accountDatabase: AccountDatabase - class CustomConnectivityReceiver : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - if (context != null && intent != null) { - connectivity.onNext(Unit) - } - } - - val connectivity = PublishSubject.create<Unit>() - } - - private val connectivityReceiver = CustomConnectivityReceiver() - private fun disconnectFromCore() { getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit { putBoolean(Keys.Status.reconnect, false) @@ -413,14 +402,17 @@ class QuasselService : DaggerLifecycleService(), } }) - connectivityReceiver.connectivity - .delay(200, TimeUnit.MILLISECONDS) - .throttleFirst(1, TimeUnit.SECONDS) + ReactiveNetwork + .observeNetworkConnectivity(applicationContext) .toLiveData() - .observe(this, Observer { + .observe(this, Observer { connectivity -> + log(INFO, "QuasselService", "Connectivity changed: $connectivity") handlerService.backend { - LoggingHandler.log(INFO, "QuasselService", "Autoreconnect: Network changed") - sessionManager.autoReconnect(true) + log(INFO, "QuasselService", "Reconnect triggered: Network changed") + sessionManager.autoConnect( + ignoreConnectionState = true, + ignoreSetting = true + ) } }) @@ -448,8 +440,6 @@ class QuasselService : DaggerLifecycleService(), registerOnSharedPreferenceChangeListener(this@QuasselService) } - registerReceiver(connectivityReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) - notificationManager.init() update() @@ -467,7 +457,7 @@ class QuasselService : DaggerLifecycleService(), scheduled = false backoff = clampOf(backoff * 2, BACKOFF_MIN, BACKOFF_MAX) - sessionManager.autoReconnect(true) + sessionManager.autoConnect(ignoreSetting = true) } } } @@ -480,8 +470,6 @@ class QuasselService : DaggerLifecycleService(), unregisterOnSharedPreferenceChangeListener(this@QuasselService) } - unregisterReceiver(connectivityReceiver) - sessionManager.dispose() asyncBackend.setDisconnectCallback(null) backendImplementation.service = null diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt index 0b964f748..186750118 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt @@ -56,12 +56,16 @@ import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults. import de.kuschku.libquassel.session.Error import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log +import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO import de.kuschku.libquassel.util.flag.and import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.flag.minus import de.kuschku.libquassel.util.flag.or -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.invoke +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.DefaultNetworkServer @@ -206,7 +210,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc val forceJoin = intent.getBooleanExtra(KEY_FORCE_JOIN, false) - modelHelper.session.filter(Optional<ISession>::isPresent).firstElement().subscribe { + modelHelper.connectedSession.filter(Optional<ISession>::isPresent).firstElement().subscribe { it.orNull()?.also { session -> val info = session.bufferSyncer.find( bufferName = channel, @@ -249,7 +253,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc val forceJoin = intent.getBooleanExtra(KEY_FORCE_JOIN, false) - modelHelper.session.filter(Optional<ISession>::isPresent).firstElement().subscribe { + modelHelper.connectedSession.filter(Optional<ISession>::isPresent).firstElement().subscribe { it.orNull()?.also { session -> val info = session.bufferSyncer.find( bufferName = channel, @@ -465,7 +469,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc modelHelper.errors.toLiveData(BackpressureStrategy.BUFFER).observe(this, Observer { error -> error?.let { when (it) { - is Error.HandshakeError -> it.message.let { + is Error.HandshakeError -> it.message.let { when (it) { is HandshakeMessage.ClientInitAck -> if (it.coreConfigured == false) @@ -530,7 +534,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc val user = userField.text.toString() val pass = passField.text.toString() - backend.value.orNull()?.updateUserDataAndLogin(user, pass) + backend.value?.orNull()?.updateUserDataAndLogin(user, pass) } } .titleColorAttr(R.attr.colorTextPrimary) @@ -555,7 +559,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc .show() } } - is Error.SslError -> { + is Error.SslError -> { it.exception.let { if (it == QuasselSecurityException.NoSsl) { // Ssl is required but not available @@ -616,7 +620,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc ) runOnUiThread { - backend.value.orNull()?.reconnect() + log(INFO, "ChatActivity", "Reconnect triggered: User action") + backend.value?.orNull()?.autoConnect(ignoreErrors = true) } } } @@ -661,7 +666,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc } runOnUiThread { - backend.value.orNull()?.reconnect() + log(INFO, "ChatActivity", "Reconnect triggered: User action") + backend.value?.orNull()?.autoConnect(ignoreErrors = true) } } } @@ -699,7 +705,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc ) runOnUiThread { - backend.value.orNull()?.reconnect() + log(INFO, "ChatActivity", "Reconnect triggered: User action") + backend.value?.orNull()?.autoConnect(ignoreErrors = true) } } } @@ -714,51 +721,49 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc } } } - } - } - }) - - // Connection errors that should show up as toast - modelHelper.connectionErrors.toLiveData().observe(this, Observer { error -> - error?.let { - val cause = it.cause - when { - it is UnknownHostException -> { - val host = it.message?.replace("Host is unresolved: ", "") - - Toast.makeText(this, - getString(R.string.label_error_unknown_host, host), - Toast.LENGTH_LONG).show() - } - it is ProtocolVersionException -> { - Toast.makeText(this, - getString(R.string.label_error_invalid_protocol_version, - it.protocol.version.toInt()), - Toast.LENGTH_LONG).show() - } - it is ConnectException && - cause is libcore.io.ErrnoException -> { - val errorCode = OsConstants.errnoName(cause.errno) - val errorName = OsConstants.strerror(cause.errno) - - Toast.makeText(this, - getString(R.string.label_error_connection, errorName, errorCode), - Toast.LENGTH_LONG).show() - } - it is ConnectException && - Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && - cause is ErrnoException -> { - val errorCode = OsConstants.errnoName(cause.errno) - val errorName = OsConstants.strerror(cause.errno) - - Toast.makeText(this, - getString(R.string.label_error_connection, errorName, errorCode), - Toast.LENGTH_LONG).show() - } - else -> { - Toast.makeText(this, - getString(R.string.label_error_connection_closed), - Toast.LENGTH_LONG).show() + is Error.ConnectionError -> { + it.throwable.let { + val cause = it.cause + when { + it is UnknownHostException -> { + val host = it.message?.replace("Host is unresolved: ", "") + + Toast.makeText(this, + getString(R.string.label_error_unknown_host, host), + Toast.LENGTH_LONG).show() + } + it is ProtocolVersionException -> { + Toast.makeText(this, + getString(R.string.label_error_invalid_protocol_version, + it.protocol.version.toInt()), + Toast.LENGTH_LONG).show() + } + it is ConnectException && + cause is libcore.io.ErrnoException -> { + val errorCode = OsConstants.errnoName(cause.errno) + val errorName = OsConstants.strerror(cause.errno) + + Toast.makeText(this, + getString(R.string.label_error_connection, errorName, errorCode), + Toast.LENGTH_LONG).show() + } + it is ConnectException && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && + cause is ErrnoException -> { + val errorCode = OsConstants.errnoName(cause.errno) + val errorName = OsConstants.strerror(cause.errno) + + Toast.makeText(this, + getString(R.string.label_error_connection, errorName, errorCode), + Toast.LENGTH_LONG).show() + } + else -> { + Toast.makeText(this, + getString(R.string.label_error_connection_closed), + Toast.LENGTH_LONG).show() + } + } + } } } } @@ -777,7 +782,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc drawerLayout.openDrawer(GravityCompat.START) } connectedAccount = accountId - modelHelper.session.value?.orNull()?.let { session -> + modelHelper.connectedSession.value?.orNull()?.let { session -> if (session.identities.isEmpty()) { UserSetupActivity.launch(this) } @@ -808,9 +813,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc connectionStatusDisplay.setOnClickListener { modelHelper.sessionManager.value?.orNull()?.apply { - ifDisconnected { - autoReconnect() - } + log(INFO, "ChatActivity", "Reconnect triggered: User action") + backend.value?.orNull()?.autoConnect(ignoreErrors = true, ignoreSetting = true) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt index 55a290928..d07e81af1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt @@ -31,7 +31,8 @@ import butterknife.ButterKnife import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings @@ -40,7 +41,10 @@ import de.kuschku.quasseldroid.ui.info.channel.ChannelInfoActivity import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity import de.kuschku.quasseldroid.util.ColorContext import de.kuschku.quasseldroid.util.avatars.AvatarHelper -import de.kuschku.quasseldroid.util.helper.* +import de.kuschku.quasseldroid.util.helper.loadAvatars +import de.kuschku.quasseldroid.util.helper.setTooltip +import de.kuschku.quasseldroid.util.helper.toLiveData +import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid.util.service.ServiceBoundFragment import de.kuschku.quasseldroid.util.ui.SpanFormatter diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt index a9d464267..a4cbde6d3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt @@ -35,13 +35,13 @@ import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.IrcChannel import de.kuschku.libquassel.quassel.syncables.Network -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.ui.chat.add.NetworkAdapter import de.kuschku.quasseldroid.ui.chat.add.NetworkItem -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.setDependent import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFragment @@ -158,7 +158,7 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { networkId = selectedNetworkId, type = Buffer_Type.of(Buffer_Type.StatusBuffer) )?.let { statusBuffer -> - modelHelper.session.value?.orNull()?.rpcHandler?.apply { + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.apply { sendInput(statusBuffer, "/join $channelName") } } @@ -175,7 +175,7 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { networkId = selectedNetworkId, type = Buffer_Type.of(Buffer_Type.StatusBuffer) )?.let { statusBuffer -> - modelHelper.session.value?.orNull()?.rpcHandler?.apply { + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.apply { sendInput(statusBuffer, "/join $channelName") modelHelper.networks.switchMap { it[selectedNetworkId]?.liveIrcChannel(channelName) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt index 4c6d13f73..eb48e2121 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt @@ -32,11 +32,11 @@ import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.Network +import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.ui.chat.add.NetworkAdapter import de.kuschku.quasseldroid.ui.chat.add.NetworkItem -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.service.ServiceBoundFragment import de.kuschku.quasseldroid.viewmodel.helper.QuasselViewModelHelper diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt index 83af1433c..297d261e3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt @@ -47,8 +47,9 @@ import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.mapOrElse -import de.kuschku.libquassel.util.helpers.mapSwitchMap +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.mapOrElse +import de.kuschku.libquassel.util.helper.mapSwitchMap import de.kuschku.libquassel.util.irc.IrcCaseMappers import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp @@ -60,7 +61,6 @@ import de.kuschku.quasseldroid.ui.chat.add.NetworkItem import de.kuschku.quasseldroid.ui.chat.nicks.NickListAdapter import de.kuschku.quasseldroid.util.ColorContext import de.kuschku.quasseldroid.util.avatars.AvatarHelper -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.loadWithFallbacks import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.toLiveData 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 5b7e32009..e5ffbc302 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 @@ -49,10 +49,7 @@ import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.flag.minus -import de.kuschku.libquassel.util.helpers.mapMap -import de.kuschku.libquassel.util.helpers.mapOrElse -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.* import de.kuschku.quasseldroid.BuildConfig import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.db.AccountDatabase @@ -68,7 +65,10 @@ import de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity import de.kuschku.quasseldroid.ui.info.channellist.ChannelListActivity import de.kuschku.quasseldroid.util.ColorContext import de.kuschku.quasseldroid.util.avatars.AvatarHelper -import de.kuschku.quasseldroid.util.helper.* +import de.kuschku.quasseldroid.util.helper.setTooltip +import de.kuschku.quasseldroid.util.helper.styledAttributes +import de.kuschku.quasseldroid.util.helper.toLiveData +import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid.util.service.ServiceBoundFragment import de.kuschku.quasseldroid.util.ui.view.WarningBarView @@ -128,7 +128,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean { val selected = modelHelper.selectedBuffer.value val info = selected?.info - val session = modelHelper.session.value?.orNull() + val session = modelHelper.connectedSession.value?.orNull() val bufferSyncer = session?.bufferSyncer val network = session?.networks?.get(selected?.info?.networkId) val bufferViewConfig = modelHelper.bufferViewConfig.value @@ -274,7 +274,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { var hasSetBufferViewConfigId = false adapter.setOnUpdateFinishedListener { if (!hasSetBufferViewConfigId) { - chatListSpinner.setSelection(adapter.indexOf(modelHelper.chat.bufferViewConfigId.value).nullIf { it == -1 } + chatListSpinner.setSelection(adapter.indexOf(modelHelper.chat.bufferViewConfigId.or(-1)).nullIf { it == -1 } ?: 0) modelHelper.chat.bufferViewConfigId.onNext(chatListSpinner.selectedItemId.toInt()) hasSetBufferViewConfigId = true @@ -486,11 +486,13 @@ class BufferViewConfigFragment : ServiceBoundFragment() { }) chatListToolbar.inflateMenu(R.menu.context_bufferlist) - chatListToolbar.menu.findItem(R.id.action_search).isChecked = modelHelper.chat.bufferSearchTemporarilyVisible.value + chatListToolbar.menu.findItem(R.id.action_search).isChecked = modelHelper.chat.bufferSearchTemporarilyVisible.or( + false) chatListToolbar.setOnMenuItemClickListener { item -> when (item.itemId) { R.id.action_archived_chats -> { - ArchiveActivity.launch(requireContext(), chatlistId = modelHelper.chat.bufferViewConfigId.value) + ArchiveActivity.launch(requireContext(), + chatlistId = modelHelper.chat.bufferViewConfigId.or(-1)) true } R.id.action_search -> { diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt index 6d2853800..bf7d2e0db 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt @@ -33,8 +33,8 @@ import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.libquassel.util.helper.value import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AutoCompleteSettings diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt index 10c866aff..b42092275 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt @@ -34,6 +34,7 @@ import butterknife.BindView import butterknife.ButterKnife import com.google.android.material.bottomsheet.BottomSheetBehavior import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager +import de.kuschku.libquassel.util.helper.invoke import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AutoCompleteSettings @@ -181,7 +182,7 @@ class ChatlineFragment : ServiceBoundFragment() { for ((stripped, _) in lines) { modelHelper.chat.addRecentlySentMessage(stripped) } - modelHelper.session { sessionOptional -> + modelHelper.connectedSession { sessionOptional -> val session = sessionOptional.orNull() modelHelper.chat.bufferId { bufferId -> session?.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo -> diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt index 554da02b7..a4b21fc9a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt @@ -49,9 +49,7 @@ import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.BufferSyncer import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.mapSwitchMap -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.* import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R @@ -131,8 +129,8 @@ class MessageListFragment : ServiceBoundFragment() { private val actionModeCallback = object : ActionMode.Callback { override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = when (item?.itemId) { R.id.action_user_info -> { - modelHelper.chat.selectedMessages.value.values.firstOrNull()?.let { msg -> - modelHelper.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> + modelHelper.chat.selectedMessages.value?.values?.firstOrNull()?.let { msg -> + modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> modelHelper.bufferData.value?.info?.let(BufferInfo::networkId)?.let { networkId -> UserInfoActivity.launch( requireContext(), @@ -153,7 +151,7 @@ class MessageListFragment : ServiceBoundFragment() { } R.id.action_copy -> { val builder = SpannableStringBuilder() - modelHelper.chat.selectedMessages.value.values.asSequence().sortedBy { + modelHelper.chat.selectedMessages.value?.values.orEmpty().asSequence().sortedBy { it.original.messageId }.map { if (it.name != null && it.content != null) { @@ -182,7 +180,7 @@ class MessageListFragment : ServiceBoundFragment() { } R.id.action_share -> { val builder = SpannableStringBuilder() - modelHelper.chat.selectedMessages.value.values.asSequence().sortedBy { + modelHelper.chat.selectedMessages.value?.values.orEmpty().asSequence().sortedBy { it.original.messageId }.map { if (it.name != null && it.content != null) { @@ -252,7 +250,7 @@ class MessageListFragment : ServiceBoundFragment() { linearLayoutManager = LinearLayoutManager(context) linearLayoutManager.reverseLayout = true - backlogRequester = BacklogRequester(modelHelper.session, database, accountDatabase) + backlogRequester = BacklogRequester(modelHelper.connectedSession, database, accountDatabase) adapter.setOnClickListener { msg -> if (actionMode != null) { @@ -262,7 +260,7 @@ class MessageListFragment : ServiceBoundFragment() { else -> actionMode?.menu?.findItem(R.id.action_user_info)?.isVisible = false } } else if (msg.hasSpoilers) { - val value = modelHelper.chat.expandedMessages.value + val value = modelHelper.chat.expandedMessages.value.orEmpty() modelHelper.chat.expandedMessages.onNext( if (value.contains(msg.original.messageId)) value - msg.original.messageId else value + msg.original.messageId @@ -288,7 +286,7 @@ class MessageListFragment : ServiceBoundFragment() { ) } adapter.setOnSenderIconClickListener { msg -> - modelHelper.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> + modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> modelHelper.bufferData.value?.info?.let(BufferInfo::networkId)?.let { networkId -> UserInfoActivity.launch( requireContext(), @@ -424,7 +422,7 @@ class MessageListFragment : ServiceBoundFragment() { } }) - modelHelper.session.toLiveData().zip(lastMessageId).observe( + modelHelper.connectedSession.toLiveData().zip(lastMessageId).observe( this, Observer { runInBackground { val session = it?.first?.orNull() @@ -508,7 +506,7 @@ class MessageListFragment : ServiceBoundFragment() { ?: BufferId(-1) if (buffer != lastBuffer) { adapter.clearCache() - modelHelper.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> + modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> onBufferChange(lastBuffer, buffer, firstVisibleMessageId, bufferSyncer) } lastBuffer = buffer @@ -557,7 +555,7 @@ class MessageListFragment : ServiceBoundFragment() { val previous = lastBuffer val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() val messageId = adapter[firstVisibleItemPosition]?.content?.messageId - val bufferSyncer = modelHelper.session.value?.orNull()?.bufferSyncer + val bufferSyncer = modelHelper.connectedSession.value?.orNull()?.bufferSyncer if (previous != null && messageId != null) { bufferSyncer?.requestSetMarkerLine(previous, messageId) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt index 81d95bc2e..9cfc6aa62 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt @@ -30,7 +30,7 @@ import androidx.recyclerview.widget.RecyclerView import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId -import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.letIf diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt index 2b81e90ff..33c954764 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt @@ -40,7 +40,7 @@ import com.bumptech.glide.util.FixedPreloadSizeProvider import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.libquassel.util.irc.IrcCaseMappers import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp @@ -193,7 +193,7 @@ class NickListFragment : ServiceBoundFragment() { } private val clickListener: ((NetworkId, String) -> Unit) = { networkId, nick -> - modelHelper.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> + modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> UserInfoActivity.launch( requireContext(), openBuffer = false, 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 4684d6211..6618e7f37 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 @@ -31,12 +31,12 @@ import butterknife.BindView import butterknife.ButterKnife import com.google.android.material.bottomsheet.BottomSheetBehavior import de.kuschku.libquassel.protocol.BufferId +import de.kuschku.libquassel.util.helper.invoke import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.input.* -import de.kuschku.quasseldroid.util.helper.invoke import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer @@ -128,7 +128,7 @@ class TopicFragment : ServiceBoundSettingsFragment(), Savable { } override fun onSave(): Boolean { - modelHelper.session { sessionOptional -> + modelHelper.connectedSession { sessionOptional -> val session = sessionOptional.orNull() modelHelper.chat.bufferId { bufferId -> session?.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo -> 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 b426457df..a48dd1ebe 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 @@ -36,6 +36,7 @@ import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.Identity import de.kuschku.libquassel.quassel.syncables.Network +import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.coresettings.aliaslist.AliasListActivity import de.kuschku.quasseldroid.ui.coresettings.chatlist.ChatlistCreateActivity @@ -49,7 +50,6 @@ import de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity import de.kuschku.quasseldroid.ui.coresettings.networkconfig.NetworkConfigActivity import de.kuschku.quasseldroid.ui.coresettings.passwordchange.PasswordChangeActivity import de.kuschku.quasseldroid.ui.info.core.CoreInfoActivity -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.missingfeatures.MissingFeature diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt index 466153b14..6d86850c8 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt @@ -41,9 +41,9 @@ import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.flag.minus import de.kuschku.libquassel.util.flag.plus +import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.Defaults -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.ui.settings.fragment.Changeable import de.kuschku.quasseldroid.util.ui.settings.fragment.Savable @@ -138,7 +138,7 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) : }) if (initDefault) { - modelHelper.session + modelHelper.connectedSession .filter(Optional<ISession>::isPresent) .map(Optional<ISession>::get) .firstElement() 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 index 57a87610c..431099cbe 100644 --- 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 @@ -19,7 +19,7 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value class ChatListCreateFragment : ChatListBaseFragment(true) { override fun onSave() = chatlist?.let { (_, data) -> 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 index b94bc5eac..f3d568f53 100644 --- 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 @@ -19,7 +19,7 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.util.ui.settings.fragment.Deletable class ChatListEditFragment : ChatListBaseFragment(false), Deletable { diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt index b0bd1f629..c0d6b152e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityBaseFragment.kt @@ -127,7 +127,7 @@ abstract class IdentityBaseFragment(private val initDefault: Boolean) : } if (initDefault) { - modelHelper.session + modelHelper.connectedSession .filter(Optional<ISession>::isPresent) .map(Optional<ISession>::get) .firstElement() 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 index 55679aae3..41c46ca48 100644 --- 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 @@ -19,10 +19,10 @@ package de.kuschku.quasseldroid.ui.coresettings.identity -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value class IdentityCreateFragment : IdentityBaseFragment(true) { - override fun onSave() = modelHelper.session.value?.orNull()?.let { session -> + override fun onSave() = modelHelper.connectedSession.value?.orNull()?.let { session -> identity?.let { (_, data) -> applyChanges(data) session.rpcHandler.createIdentity(data, mapOf()) 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 index 4523eb3b4..48e9e8a25 100644 --- 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 @@ -19,7 +19,7 @@ package de.kuschku.quasseldroid.ui.coresettings.identity -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.util.ui.settings.fragment.Deletable class IdentityEditFragment : IdentityBaseFragment(false), Deletable { @@ -32,7 +32,7 @@ class IdentityEditFragment : IdentityBaseFragment(false), Deletable { override fun onDelete() { identity?.let { (it, _) -> it?.let { - modelHelper.session.value?.orNull()?.rpcHandler?.removeIdentity(it.id()) + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.removeIdentity(it.id()) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt index 921fc5397..8148805de 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkBaseFragment.kt @@ -43,12 +43,12 @@ import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.Defaults import de.kuschku.quasseldroid.ui.coresettings.networkserver.NetworkServerActivity -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.setDependent import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.helper.visibleIf @@ -188,7 +188,7 @@ abstract class NetworkBaseFragment(private val initDefault: Boolean) : }) if (initDefault) { - modelHelper.session + modelHelper.connectedSession .filter(Optional<ISession>::isPresent) .map(Optional<ISession>::get) .firstElement() diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateFragment.kt index 30a627384..56354293d 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkCreateFragment.kt @@ -19,11 +19,11 @@ package de.kuschku.quasseldroid.ui.coresettings.network -import de.kuschku.libquassel.session.Backend -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value +import de.kuschku.quasseldroid.Backend class NetworkCreateFragment : NetworkBaseFragment(true) { - override fun onSave() = modelHelper.session.value?.orNull()?.let { session -> + override fun onSave() = modelHelper.connectedSession.value?.orNull()?.let { session -> network?.let { (_, data) -> applyChanges(data) modelHelper.backend.value?.ifPresent(Backend::requestConnectNewNetwork) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditFragment.kt index 1c76a2a7d..4d7900e4f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkEditFragment.kt @@ -19,7 +19,7 @@ package de.kuschku.quasseldroid.ui.coresettings.network -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.util.ui.settings.fragment.Deletable class NetworkEditFragment : NetworkBaseFragment(false), Deletable { @@ -32,7 +32,7 @@ class NetworkEditFragment : NetworkBaseFragment(false), Deletable { override fun onDelete() { network?.let { (it, _) -> it?.let { - modelHelper.session.value?.orNull()?.rpcHandler?.removeNetwork(it.networkId()) + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.removeNetwork(it.networkId()) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt index c77211353..04ddb0c96 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt @@ -34,9 +34,9 @@ import com.google.android.material.textfield.TextInputLayout import de.kuschku.libquassel.quassel.syncables.RpcHandler import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.mapMapNullable -import de.kuschku.libquassel.util.helpers.mapSwitchMap -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.mapMapNullable +import de.kuschku.libquassel.util.helper.mapSwitchMap +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.models.Account @@ -92,7 +92,7 @@ class PasswordChangeFragment : ServiceBoundFragment() { user.setText(account?.user) - modelHelper.session + modelHelper.connectedSession .mapMapNullable(ISession::rpcHandler) .mapSwitchMap(RpcHandler::passwordChanged) .filter(Optional<Boolean>::isPresent) @@ -144,7 +144,7 @@ class PasswordChangeFragment : ServiceBoundFragment() { waiting = account?.copy(pass = pass) - modelHelper.session.value?.orNull()?.rpcHandler?.changePassword( + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.changePassword( 0L, user.text.toString(), oldPassword.text.toString(), diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt index 49b933ff3..9706bbee6 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channel/ChannelInfoFragment.kt @@ -34,7 +34,8 @@ 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.IrcChannel -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity @@ -90,7 +91,8 @@ class ChannelInfoFragment : ServiceBoundFragment() { var currentBufferInfo: BufferInfo? - combineLatest(modelHelper.session, modelHelper.networks).map { (sessionOptional, networks) -> + combineLatest(modelHelper.connectedSession, + modelHelper.networks).map { (sessionOptional, networks) -> if (openBuffer == true) { val session = sessionOptional?.orNull() val bufferSyncer = session?.bufferSyncer @@ -127,7 +129,7 @@ class ChannelInfoFragment : ServiceBoundFragment() { } actionPart.setOnClickListener { - modelHelper.session.value?.orNull()?.let { session -> + modelHelper.connectedSession.value?.orNull()?.let { session -> session.bufferSyncer.find( networkId = channel.network().networkId(), type = Buffer_Type.of(Buffer_Type.StatusBuffer) @@ -139,7 +141,7 @@ class ChannelInfoFragment : ServiceBoundFragment() { } actionWho.setOnClickListener { - modelHelper.session.value?.orNull()?.let { session -> + modelHelper.connectedSession.value?.orNull()?.let { session -> session.bufferSyncer.find( networkId = channel.network().networkId(), type = Buffer_Type.of(Buffer_Type.StatusBuffer) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt index e5fbcc0c3..0b02d561a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListFragment.kt @@ -34,10 +34,10 @@ import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.protocol.QStringList import de.kuschku.libquassel.quassel.syncables.IrcListHelper import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.mapSwitchMap -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.mapSwitchMap +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.retint import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.ui.settings.fragment.ServiceBoundSettingsFragment diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt index 2ac930c12..d939e93da 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/CoreInfoFragment.kt @@ -35,7 +35,8 @@ import butterknife.ButterKnife import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.ssl.X509Helper import de.kuschku.libquassel.ssl.commonName -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.info.certificate.CertificateInfoActivity import de.kuschku.quasseldroid.util.helper.* @@ -205,7 +206,7 @@ class CoreInfoFragment : ServiceBoundFragment() { clients.layoutManager = LinearLayoutManager(requireContext()) val adapter = ClientAdapter() adapter.setDisconnectListener { - val sessionOptional = modelHelper.session.value + val sessionOptional = modelHelper.connectedSession.value val session = sessionOptional?.orNull() val rpcHandler = session?.rpcHandler rpcHandler?.requestKickClient(it) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt index 6bb05c0a9..91de4fbbd 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt @@ -47,8 +47,10 @@ import de.kuschku.libquassel.quassel.syncables.IgnoreListManager import de.kuschku.libquassel.quassel.syncables.IrcChannel import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.invoke +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.libquassel.util.helper.value import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.libquassel.util.irc.IrcCaseMappers import de.kuschku.quasseldroid.R @@ -179,7 +181,7 @@ class UserInfoFragment : ServiceBoundFragment() { getColor(0, 0) } - combineLatest(modelHelper.session, + combineLatest(modelHelper.connectedSession, modelHelper.networks).switchMap { (sessionOptional, networks) -> fun processUser(user: IrcUser, bufferSyncer: BufferSyncer? = null, info: BufferInfo? = null, ignoreItems: List<IgnoreListManager.IgnoreListItem>? = null): Observable<Optional<IrcUserInfo>> { @@ -352,7 +354,7 @@ class UserInfoFragment : ServiceBoundFragment() { actionWhois.visibleIf(user.knownToCore) actionQuery.setOnClickListener { view -> - modelHelper.session.value?.orNull()?.let { session -> + modelHelper.connectedSession.value?.orNull()?.let { session -> val info = session.bufferSyncer.find( bufferName = user.nick, networkId = user.networkId, @@ -433,7 +435,7 @@ class UserInfoFragment : ServiceBoundFragment() { } actionWhois.setOnClickListener { view -> - modelHelper.session { + modelHelper.connectedSession { it.orNull()?.let { session -> session.bufferSyncer.find( networkId = user.networkId, diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt index fd8005c1a..73f206f54 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt @@ -34,9 +34,9 @@ import butterknife.BindView import butterknife.ButterKnife import com.google.android.material.floatingactionbutton.FloatingActionButton import dagger.android.support.DaggerAppCompatActivity -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helper.nullIf +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings @@ -82,13 +82,13 @@ abstract class ServiceBoundSetupActivity : protected open val initData: Bundle = Bundle() protected fun runInBackground(f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backend(f) } } protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt index 6d065af8e..f4058e54a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt @@ -21,8 +21,8 @@ package de.kuschku.quasseldroid.ui.setup import android.content.Context import android.os.Bundle -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.util.service.BackendServiceConnection import io.reactivex.subjects.BehaviorSubject @@ -33,13 +33,13 @@ abstract class ServiceBoundSlideFragment : SlideFragment() { get() = connection.backend protected fun runInBackground(f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backend(f) } } protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt index a24d8dee2..be71c78d2 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt @@ -33,7 +33,7 @@ import butterknife.BindView import butterknife.ButterKnife import com.google.android.material.floatingactionbutton.FloatingActionButton import dagger.android.support.DaggerAppCompatActivity -import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity import de.kuschku.quasseldroid.ui.clientsettings.client.ClientSettingsActivity diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreSetupActivity.kt index b3a942f9e..b8520d141 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreSetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreSetupActivity.kt @@ -28,7 +28,7 @@ import de.kuschku.libquassel.protocol.coresetup.CoreSetupBackend import de.kuschku.libquassel.protocol.coresetup.CoreSetupData import de.kuschku.libquassel.protocol.message.HandshakeMessage import de.kuschku.libquassel.quassel.ExtendedFeature -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.persistence.models.Account import de.kuschku.quasseldroid.ui.setup.ServiceBoundSetupActivity import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupActivity.kt index e1ae92985..864090fe2 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupActivity.kt @@ -27,7 +27,7 @@ import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.IdentityId import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.ui.setup.ServiceBoundSetupActivity import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper import javax.inject.Inject @@ -51,7 +51,7 @@ class NetworkSetupActivity : ServiceBoundSetupActivity() { val identity = IdentityId(data.getInt("identity", -1)) if (networkId.isValidId() || (network != null && identity.isValidId())) { modelHelper.backend?.value?.ifPresent { backend -> - val session = modelHelper.session.value?.orNull() + val session = modelHelper.connectedSession.value?.orNull() session?.apply { rpcHandler.apply { when { diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt index 19a229770..4d59cdd91 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/network/NetworkSetupNetworkSlide.kt @@ -39,6 +39,7 @@ import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_PLAINTEXT import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_SSL +import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.DefaultNetworkServer import de.kuschku.quasseldroid.ui.coresettings.chatlist.NetworkAdapter @@ -46,7 +47,6 @@ import de.kuschku.quasseldroid.ui.coresettings.network.IdentityAdapter import de.kuschku.quasseldroid.ui.setup.ServiceBoundSlideFragment import de.kuschku.quasseldroid.util.Patterns import de.kuschku.quasseldroid.util.TextValidator -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.ui.AnimationHelper import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupActivity.kt index 292f05833..e063508ad 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupActivity.kt @@ -27,7 +27,7 @@ import androidx.lifecycle.Observer import de.kuschku.libquassel.protocol.IdentityId import de.kuschku.libquassel.quassel.syncables.Identity import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork -import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.DefaultNetwork import de.kuschku.quasseldroid.defaults.Defaults @@ -51,7 +51,7 @@ class UserSetupActivity : ServiceBoundSetupActivity() { val network = data.getSerializable("network") as? DefaultNetwork if (network != null) { modelHelper.backend?.value?.ifPresent { backend -> - modelHelper.session.value?.orNull()?.rpcHandler?.apply { + modelHelper.connectedSession.value?.orNull()?.rpcHandler?.apply { createIdentity(Defaults.identity(this@UserSetupActivity).apply { setIdentityName(this@UserSetupActivity.getString(R.string.default_identity_identity_name)) setNicks(listOf(data.getString("nick"))) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt index 8e6795c5a..d88581f54 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/UserSetupNetworkSlide.kt @@ -33,7 +33,7 @@ import butterknife.ButterKnife import com.google.android.material.textfield.TextInputLayout import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_PLAINTEXT import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.PortDefaults.PORT_SSL -import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.DefaultNetwork import de.kuschku.quasseldroid.defaults.DefaultNetworkServer diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/AndroidLoggingHandler.kt b/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/AndroidLoggingHandler.kt index 170644894..2ced1011a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/AndroidLoggingHandler.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/AndroidLoggingHandler.kt @@ -24,11 +24,11 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler import de.kuschku.quasseldroid.BuildConfig object AndroidLoggingHandler : LoggingHandler() { - override fun isLoggable(logLevel: LogLevel, tag: String): Boolean { + override fun _isLoggable(logLevel: LogLevel, tag: String): Boolean { return BuildConfig.DEBUG || Log.isLoggable(tag, priority(logLevel)) } - override fun log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) { + override fun _log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) { val priority = priority( logLevel ) diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt index ee13b1140..58ef4abb6 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt @@ -19,7 +19,7 @@ package de.kuschku.quasseldroid.util.helper -import de.kuschku.libquassel.util.helpers.clampOf +import de.kuschku.libquassel.util.helper.clampOf infix fun IntRange.without(other: IntRange): Iterable<IntRange> { val otherStart = clampOf(minOf(other.start, other.last + 1), this.start, this.last + 1) diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/BackendServiceConnection.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/BackendServiceConnection.kt index 2d375b908..89dfb5549 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/service/BackendServiceConnection.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/BackendServiceConnection.kt @@ -26,8 +26,8 @@ import android.content.ServiceConnection import android.os.IBinder import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.service.QuasselBinder import de.kuschku.quasseldroid.service.QuasselService import io.reactivex.subjects.BehaviorSubject diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt index ed62a7d1a..38749538f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt @@ -29,8 +29,8 @@ import android.view.WindowManager import android.widget.Toast import androidx.annotation.ColorRes import androidx.annotation.DrawableRes -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.ConnectionSettings @@ -58,13 +58,13 @@ abstract class ServiceBoundActivity : private var nightMode: Int? = null protected fun runInBackground(f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backend(f) } } protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt index 75cba1a03..f7f493faf 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt @@ -22,8 +22,8 @@ package de.kuschku.quasseldroid.util.service import android.content.Context import android.os.Bundle import dagger.android.support.DaggerFragment -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.viewmodel.QuasselViewModel import io.reactivex.subjects.BehaviorSubject @@ -38,13 +38,13 @@ abstract class ServiceBoundFragment : DaggerFragment() { get() = connection.backend protected fun runInBackground(f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backend(f) } } protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) { - connection.backend.value.ifPresent { + connection.backend.value?.ifPresent { it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ThemedActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ThemedActivity.kt index d688cc0d5..66f7255a3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/ThemedActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/ThemedActivity.kt @@ -29,7 +29,7 @@ import dagger.android.AndroidInjector import dagger.android.DispatchingAndroidInjector import dagger.android.HasFragmentInjector import dagger.android.support.HasSupportFragmentInjector -import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.quasseldroid.settings.AppearanceSettings import javax.inject.Inject diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt index 4f1ffca97..11147935a 100644 --- a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt +++ b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt @@ -39,8 +39,8 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.hexDump -import de.kuschku.libquassel.util.helpers.write +import de.kuschku.libquassel.util.helper.hexDump +import de.kuschku.libquassel.util.helper.write import de.kuschku.libquassel.util.nio.ChainedByteBuffer import de.kuschku.libquassel.util.nio.WrappedChannel import io.reactivex.subjects.BehaviorSubject diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/MessageRunnable.kt b/lib/src/main/java/de/kuschku/libquassel/connection/MessageRunnable.kt index 2236b83ea..ff3e5e6d7 100644 --- a/lib/src/main/java/de/kuschku/libquassel/connection/MessageRunnable.kt +++ b/lib/src/main/java/de/kuschku/libquassel/connection/MessageRunnable.kt @@ -23,7 +23,7 @@ import de.kuschku.libquassel.protocol.primitive.serializer.Serializer import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN -import de.kuschku.libquassel.util.helpers.write +import de.kuschku.libquassel.util.helper.write import de.kuschku.libquassel.util.nio.ChainedByteBuffer import de.kuschku.libquassel.util.nio.WrappedChannel import java.nio.ByteBuffer diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt index 6dc8b5585..4b1c6a2d9 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt @@ -27,7 +27,7 @@ import de.kuschku.libquassel.quassel.ProtocolFeature import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.flag.Flags import de.kuschku.libquassel.util.flag.ShortFlags -import de.kuschku.libquassel.util.helpers.deserializeString +import de.kuschku.libquassel.util.helper.deserializeString import java.nio.ByteBuffer typealias QStringList = List<String?> diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/coresetup/CoreSetupBackend.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/coresetup/CoreSetupBackend.kt index bd0d861b9..fc958810e 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/coresetup/CoreSetupBackend.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/coresetup/CoreSetupBackend.kt @@ -20,7 +20,7 @@ package de.kuschku.libquassel.protocol.coresetup import de.kuschku.libquassel.protocol.* -import de.kuschku.libquassel.util.helpers.getOr +import de.kuschku.libquassel.util.helper.getOr import java.io.Serializable data class CoreSetupBackend( diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitDataSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitDataSerializer.kt index 704bc471e..73e9f86c3 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitDataSerializer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitDataSerializer.kt @@ -21,8 +21,8 @@ package de.kuschku.libquassel.protocol.message import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer -import de.kuschku.libquassel.util.helpers.deserializeString -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.deserializeString +import de.kuschku.libquassel.util.helper.serializeString import java.nio.ByteBuffer object InitDataSerializer : SignalProxyMessageSerializer<SignalProxyMessage.InitData> { diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitRequestSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitRequestSerializer.kt index c5bb53f92..2ebef5f71 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitRequestSerializer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/InitRequestSerializer.kt @@ -24,8 +24,8 @@ import de.kuschku.libquassel.protocol.QVariantList import de.kuschku.libquassel.protocol.Type import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import de.kuschku.libquassel.protocol.value -import de.kuschku.libquassel.util.helpers.deserializeString -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.deserializeString +import de.kuschku.libquassel.util.helper.serializeString import java.nio.ByteBuffer object InitRequestSerializer : SignalProxyMessageSerializer<SignalProxyMessage.InitRequest> { diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/RpcCallSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/RpcCallSerializer.kt index a5da9505b..25fdf96dd 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/RpcCallSerializer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/RpcCallSerializer.kt @@ -24,8 +24,8 @@ import de.kuschku.libquassel.protocol.QVariantList import de.kuschku.libquassel.protocol.Type import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import de.kuschku.libquassel.protocol.value -import de.kuschku.libquassel.util.helpers.deserializeString -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.deserializeString +import de.kuschku.libquassel.util.helper.serializeString import java.nio.ByteBuffer object RpcCallSerializer : SignalProxyMessageSerializer<SignalProxyMessage.RpcCall> { diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/SyncMessageSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/SyncMessageSerializer.kt index 203b8647f..98bf74f7e 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/SyncMessageSerializer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/SyncMessageSerializer.kt @@ -24,8 +24,8 @@ import de.kuschku.libquassel.protocol.QVariantList import de.kuschku.libquassel.protocol.Type import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import de.kuschku.libquassel.protocol.value -import de.kuschku.libquassel.util.helpers.deserializeString -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.deserializeString +import de.kuschku.libquassel.util.helper.serializeString import java.nio.ByteBuffer object SyncMessageSerializer : SignalProxyMessageSerializer<SignalProxyMessage.SyncMessage> { diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt index 3c61e8d6b..7dbdd0cfe 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt @@ -21,7 +21,7 @@ package de.kuschku.libquassel.protocol.primitive.serializer import de.kuschku.libquassel.quassel.QuasselFeatures -import de.kuschku.libquassel.util.helpers.hexDump +import de.kuschku.libquassel.util.helper.hexDump import de.kuschku.libquassel.util.nio.ChainedByteBuffer import java.nio.ByteBuffer import java.nio.CharBuffer diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt index 22ebb65ef..6574f18e2 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt @@ -25,7 +25,7 @@ import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.interfaces.IBufferViewConfig import de.kuschku.libquassel.session.SignalProxy import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.clampOf +import de.kuschku.libquassel.util.helper.clampOf import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt index 7b9d44b01..fcdff341b 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt @@ -27,7 +27,7 @@ import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.session.SignalProxy import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.ERROR -import de.kuschku.libquassel.util.helpers.getOr +import de.kuschku.libquassel.util.helper.getOr import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject import java.nio.charset.Charset diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt index 41a5a1d01..8fd5e42e6 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt @@ -25,8 +25,8 @@ import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.* import de.kuschku.libquassel.session.SignalProxy -import de.kuschku.libquassel.util.helpers.getOr -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.getOr +import de.kuschku.libquassel.util.helper.serializeString import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.libquassel.util.irc.IrcCaseMappers import io.reactivex.Observable 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 524a0f263..6a284a5b9 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 @@ -28,7 +28,7 @@ import de.kuschku.libquassel.quassel.syncables.interfaces.IRpcHandler import de.kuschku.libquassel.session.BacklogStorage import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.NotificationManager -import de.kuschku.libquassel.util.helpers.deserializeString +import de.kuschku.libquassel.util.helper.deserializeString import de.kuschku.libquassel.util.rxjava.ReusableUnicastSubject import java.nio.ByteBuffer diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt index ead6bc2cd..b6e939379 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt @@ -25,7 +25,7 @@ import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import de.kuschku.libquassel.util.flag.Flag import de.kuschku.libquassel.util.flag.Flags -import de.kuschku.libquassel.util.helpers.serializeString +import de.kuschku.libquassel.util.helper.serializeString import java.io.Serializable import java.nio.ByteBuffer diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Error.kt b/lib/src/main/java/de/kuschku/libquassel/session/Error.kt index 0461ee6d3..3e791862b 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Error.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Error.kt @@ -23,6 +23,7 @@ import de.kuschku.libquassel.connection.QuasselSecurityException import de.kuschku.libquassel.protocol.message.HandshakeMessage sealed class Error { - data class HandshakeError(val message: HandshakeMessage) : Error() + data class ConnectionError(val throwable: Throwable) : Error() data class SslError(val exception: QuasselSecurityException) : Error() + data class HandshakeError(val message: HandshakeMessage) : Error() } 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 84fd10247..82b1321e3 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt @@ -35,9 +35,11 @@ import java.io.Closeable import javax.net.ssl.SSLSession interface ISession : Closeable { - val state: Observable<ConnectionState> val features: Features val sslSession: Observable<Optional<SSLSession>> + val lag: BehaviorSubject<Long> + + val proxy: SignalProxy val aliasManager: AliasManager val backlogManager: BacklogManager @@ -56,16 +58,9 @@ interface ISession : Closeable { fun liveNetworkAdded(): Observable<NetworkId> val networkConfig: NetworkConfig val rpcHandler: RpcHandler - val initStatus: Observable<Pair<Int, Int>> - fun network(id: NetworkId): Network? fun identity(id: IdentityId): Identity? - val proxy: SignalProxy - val error: Observable<Error> - val connectionError: Observable<Throwable> - val lag: BehaviorSubject<Long> - fun login(user: String, pass: String) fun setupCore(setupData: HandshakeMessage.CoreSetupData) { proxy.dispatch(setupData) @@ -77,16 +72,23 @@ interface ISession : Closeable { fun addIdentity(initData: QVariantMap) fun removeIdentity(identityId: IdentityId) + val progress: ProgressData + + data class ProgressData( + val state: Observable<ConnectionState>, + val progress: Observable<Pair<Int, Int>>, + val error: Observable<Error> + ) + companion object { val NULL = object : ISession { - override val proxy: SignalProxy = SignalProxy.NULL - override val error = Observable.empty<Error>() - override val connectionError = Observable.empty<Throwable>() - override val state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED) override val features: Features = Features( QuasselFeatures.empty(), QuasselFeatures.empty()) override val sslSession: Observable<Optional<SSLSession>> = Observable.empty() + override val lag = BehaviorSubject.createDefault(0L) + + override val proxy: SignalProxy = SignalProxy.NULL override val rpcHandler = RpcHandler(this) override val aliasManager = AliasManager(proxy) @@ -105,8 +107,6 @@ interface ISession : Closeable { override fun liveNetworks() = Observable.empty<Map<NetworkId, Network>>() override fun liveNetworkAdded(): Observable<NetworkId> = PublishSubject.create() override val networkConfig = NetworkConfig(proxy) - override val initStatus: Observable<Pair<Int, Int>> = Observable.just(0 to 0) - override val lag = BehaviorSubject.createDefault(0L) override fun network(id: NetworkId): Network? = null override fun identity(id: IdentityId): Identity? = null @@ -118,6 +118,13 @@ interface ISession : Closeable { override fun removeNetwork(networkId: NetworkId) = Unit override fun addIdentity(initData: QVariantMap) = Unit override fun removeIdentity(identityId: IdentityId) = Unit + + override val progress = ProgressData( + state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED), + progress = BehaviorSubject.createDefault(Pair(0, 0)), + error = Observable.empty() + ) + override fun close() = Unit } } diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt b/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt index 79630f842..914d829a7 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt @@ -25,7 +25,7 @@ import de.kuschku.libquassel.protocol.Type import de.kuschku.libquassel.protocol.message.SignalProxyMessage import de.kuschku.libquassel.quassel.exceptions.ObjectNotFoundException import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject -import de.kuschku.libquassel.util.helpers.removeIfEqual +import de.kuschku.libquassel.util.helper.removeIfEqual class ObjectStorage(private var proxy: SignalProxy) { fun deinit() { 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 346f33d4d..91eaf398b 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -71,12 +71,15 @@ class Session( trustManager, hostnameVerifier ) - override val state = coreConnection.state - private val _error = ReusableUnicastSubject.create<Error>() - override val error = _error.publish().refCount() - private val _connectionError = ReusableUnicastSubject.create<Throwable>() - override val connectionError = _connectionError.publish().refCount() + private val __error = ReusableUnicastSubject.create<Error>() + private val __connectionError = ReusableUnicastSubject.create<Throwable>() + private val __initProgress = BehaviorSubject.createDefault(0 to 0) + override val progress = ISession.ProgressData( + coreConnection.state, + __initProgress, + __error.publish().refCount() + ) override val aliasManager = AliasManager(this) override val backlogManager = BacklogManager(this, backlogStorage) @@ -105,8 +108,6 @@ class Session( override val rpcHandler = RpcHandler(this, backlogStorage, notificationManager) - override val initStatus = BehaviorSubject.createDefault(0 to 0) - override val lag = BehaviorSubject.createDefault(0L) private val heartBeatThread = heartBeatFactory() @@ -120,7 +121,7 @@ class Session( private fun handleError(error: Error) { hasErroredCallback?.invoke(error) - _error.onNext(error) + __error.onNext(error) } override fun handle(f: HandshakeMessage.ClientInitAck): Boolean { @@ -177,7 +178,7 @@ class Session( } fun handleConnectionError(connectionError: Throwable) { - _connectionError.onNext(connectionError) + __connectionError.onNext(connectionError) } override fun addNetwork(networkId: NetworkId) { @@ -261,7 +262,7 @@ class Session( } override fun onInitStatusChanged(progress: Int, total: Int) { - initStatus.onNext(progress to total) + __initProgress.onNext(Pair(progress, total)) } override fun onInitDone() { 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 27a4c6415..0966dc639 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt @@ -20,20 +20,18 @@ package de.kuschku.libquassel.session import de.kuschku.libquassel.connection.ConnectionState -import de.kuschku.libquassel.connection.HostnameVerifier -import de.kuschku.libquassel.connection.SocketAddress -import de.kuschku.libquassel.protocol.ClientData import de.kuschku.libquassel.protocol.message.HandshakeMessage import de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invokers +import de.kuschku.libquassel.session.manager.ConnectionInfo +import de.kuschku.libquassel.session.manager.SessionState 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.helpers.or +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.or +import de.kuschku.libquassel.util.helper.value import io.reactivex.Observable import io.reactivex.disposables.Disposable -import io.reactivex.functions.BiFunction -import io.reactivex.subjects.BehaviorSubject -import javax.net.ssl.X509TrustManager class SessionManager( offlineSession: ISession, @@ -42,7 +40,21 @@ class SessionManager( val handlerService: HandlerService, private val heartBeatFactory: () -> HeartBeatRunner, private val exceptionHandler: (Throwable) -> Unit -) { +) : SessionStateHandler(SessionState(offlineSession, null, null)) { + // Stateful fields + private var lastConnectionInfo: ConnectionInfo? = null + private var hasErrored: Boolean = false + + private val disposables = mutableListOf<Disposable>() + + // Helping Rx Mappers + val connectionProgress: Observable<Triple<ConnectionState, Int, Int>> = progressData.switchMap { + combineLatest(it.state, it.progress).map { (state, progress) -> + Triple(state, progress.first, progress.second) + } + } + + // Listeners private var disconnectFromCore: (() -> Unit)? = null private var initCallback: ((Session) -> Unit)? = null @@ -54,52 +66,12 @@ class SessionManager( this.initCallback = callback } - fun close() = session.or(lastSession).close() - - data class ConnectionInfo( - val clientData: ClientData, - val trustManager: X509TrustManager, - val hostnameVerifier: HostnameVerifier, - val address: SocketAddress, - val userData: Pair<String, String>, - val requireSsl: Boolean, - val shouldReconnect: Boolean - ) - - private var lastConnectionInfo: ConnectionInfo? = null - - private var inProgressSession = BehaviorSubject.createDefault(ISession.NULL) - private var lastSession: ISession = offlineSession - val state: Observable<ConnectionState> = inProgressSession.switchMap(ISession::state) - - private val initStatus: Observable<Pair<Int, Int>> = inProgressSession.switchMap(ISession::initStatus) - val session: Observable<ISession> = state.map { connectionState -> - if (connectionState == ConnectionState.CONNECTED) - inProgressSession.value - else - lastSession - } - - private var hasErrored: Boolean = false - - val error = inProgressSession.switchMap(ISession::error) - - val connectionError = inProgressSession.switchMap(ISession::connectionError) - - val connectionProgress: Observable<Triple<ConnectionState, Int, Int>> = Observable.combineLatest( - state, initStatus, - BiFunction<ConnectionState, Pair<Int, Int>, Triple<ConnectionState, Int, Int>> { t1, t2 -> - Triple(t1, t2.first, t2.second) - }) - - val disposables = mutableListOf<Disposable>() - init { log(INFO, "Session", "Session created") - disposables.add(state.subscribe { + disposables.add(state.distinctUntilChanged().subscribe { if (it == ConnectionState.CONNECTED) { - lastSession.close() + updateStateConnected() } }) @@ -108,38 +80,35 @@ class SessionManager( } fun login(user: String, pass: String) { - inProgressSession.value.login(user, pass) + connectingSession.value?.login(user, pass) } fun setupCore(setupData: HandshakeMessage.CoreSetupData) { - inProgressSession.value.setupCore(setupData) + connectingSession.value?.setupCore(setupData) } fun connect( connectionInfo: ConnectionInfo ) { log(DEBUG, "SessionManager", "Connecting") - inProgressSession.value.close() lastConnectionInfo = connectionInfo hasErrored = false - inProgressSession.onNext( - Session( - connectionInfo.address, - connectionInfo.userData, - connectionInfo.requireSsl, - connectionInfo.trustManager, - connectionInfo.hostnameVerifier, - connectionInfo.clientData, - handlerService, - heartBeatFactory, - disconnectFromCore, - initCallback, - exceptionHandler, - ::hasErroredCallback, - notificationManager, - backlogStorage - ) - ) + updateStateConnecting(Session( + connectionInfo.address, + connectionInfo.userData, + connectionInfo.requireSsl, + connectionInfo.trustManager, + connectionInfo.hostnameVerifier, + connectionInfo.clientData, + handlerService, + heartBeatFactory, + disconnectFromCore, + initCallback, + exceptionHandler, + ::hasErroredCallback, + notificationManager, + backlogStorage + )) } fun hasErroredCallback(error: Error) { @@ -147,52 +116,41 @@ class SessionManager( hasErrored = true } - /** - * @return if an autoreconnect has been necessary - */ - fun autoReconnect(forceReconnect: Boolean = false) = if (!hasErrored) { - state.or(ConnectionState.DISCONNECTED).let { - if (it == ConnectionState.CLOSED) { - log(INFO, "SessionManager", "Autoreconnect triggered") - reconnect(forceReconnect) - true - } else { - log(INFO, "SessionManager", "Autoreconnect failed: state is $it") - false - } + fun autoConnect( + ignoreConnectionState: Boolean = false, + ignoreSetting: Boolean = false, + ignoreErrors: Boolean = false, + connectionInfo: ConnectionInfo? = lastConnectionInfo + ): Boolean { + if (connectionInfo == null) { + log(INFO, "SessionManager", "Reconnect failed: not enough data available") + return false } - } else { - log(INFO, "SessionManager", "Autoreconnect failed: hasErrored") - false - } - - fun reconnect(forceReconnect: Boolean = false) { - if (lastConnectionInfo?.shouldReconnect == true || forceReconnect) { - val connectionInfo = lastConnectionInfo - if (connectionInfo != null) { - connect(connectionInfo) - } else { - log(INFO, "SessionManager", "Reconnect failed: not enough data available") - } - } else { + if (!connectionInfo.shouldReconnect && !ignoreSetting) { log(INFO, "SessionManager", "Reconnect failed: reconnect not allowed") + return false } - } - fun disconnect(forever: Boolean) { - if (forever) - backlogStorage.clearMessages() - inProgressSession.value.close() - inProgressSession.onNext(ISession.NULL) - } + val connectionState = state.or(ConnectionState.DISCONNECTED) + if (connectionState != ConnectionState.DISCONNECTED && !ignoreConnectionState) { + log(INFO, "SessionManager", "Reconnect failed: connection state is $connectionState") + return false + } - fun ifDisconnected(closure: (ISession) -> Unit) { - state.or(ConnectionState.DISCONNECTED).let { - if (it == ConnectionState.CLOSED || it == ConnectionState.DISCONNECTED) { - closure(inProgressSession.value) - } + if (hasErrored && !ignoreErrors) { + log(INFO, "SessionManager", "Reconnect failed: errors have been thrown") + return false } + + log(INFO, "SessionManager", "Reconnect successful") + connect(connectionInfo) + return true + } + + fun disconnect(forever: Boolean) { + if (forever) backlogStorage.clearMessages() + updateStateOffline() } fun dispose() { diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt new file mode 100644 index 000000000..8a5ea7efb --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt @@ -0,0 +1,76 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.session + +import de.kuschku.libquassel.session.manager.SessionState +import io.reactivex.subjects.BehaviorSubject + +open class SessionStateHandler constructor( + initialState: SessionState +) { + private val sessions = BehaviorSubject.createDefault(initialState) + + val connectedSession = sessions.map { + it.connected + ?: it.offline + } + + val connectingSession = sessions.map { + it.connecting + ?: it.connected + ?: it.offline + } + + val progressData = connectingSession.map { + it.progress + } + + val errors = progressData.switchMap { + it.error + } + + val progress = progressData.switchMap { + it.progress + } + + val state = progressData.switchMap { + it.state + } + + private fun updateState(f: SessionState.() -> SessionState) { + sessions.onNext(f(sessions.value)) + } + + protected fun updateStateConnecting(connectingSession: ISession) = updateState { + connecting?.close() + copy(connecting = connectingSession) + } + + protected fun updateStateConnected() = updateState { + connected?.close() + copy(connected = connecting, connecting = null) + } + + protected fun updateStateOffline() = updateState { + connected?.close() + connecting?.close() + copy(connecting = null, connected = null) + } +} diff --git a/lib/src/main/java/de/kuschku/libquassel/session/manager/ConnectionInfo.kt b/lib/src/main/java/de/kuschku/libquassel/session/manager/ConnectionInfo.kt new file mode 100644 index 000000000..aa7f9f8ee --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/session/manager/ConnectionInfo.kt @@ -0,0 +1,35 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.session.manager + +import de.kuschku.libquassel.connection.HostnameVerifier +import de.kuschku.libquassel.connection.SocketAddress +import de.kuschku.libquassel.protocol.ClientData +import javax.net.ssl.X509TrustManager + +data class ConnectionInfo( + val clientData: ClientData, + val trustManager: X509TrustManager, + val hostnameVerifier: HostnameVerifier, + val address: SocketAddress, + val userData: Pair<String, String>, + val requireSsl: Boolean, + val shouldReconnect: Boolean +) diff --git a/lib/src/main/java/de/kuschku/libquassel/session/manager/SessionState.kt b/lib/src/main/java/de/kuschku/libquassel/session/manager/SessionState.kt new file mode 100644 index 000000000..1f55044fa --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/session/manager/SessionState.kt @@ -0,0 +1,28 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.session.manager + +import de.kuschku.libquassel.session.ISession + +data class SessionState( + val offline: ISession, + val connecting: ISession?, + val connected: ISession? +) 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 806e4d76d..e1b1520d3 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 @@ -23,15 +23,15 @@ package de.kuschku.libquassel.util.compatibility import de.kuschku.libquassel.util.compatibility.reference.JavaLoggingHandler abstract class LoggingHandler { - abstract fun log(logLevel: LogLevel, tag: String, message: String? = null, - throwable: Throwable? = null) + abstract fun _log(logLevel: LogLevel, tag: String, message: String? = null, + throwable: Throwable? = null) - abstract fun isLoggable(logLevel: LogLevel, tag: String): Boolean + abstract fun _isLoggable(logLevel: LogLevel, tag: String): Boolean inline fun isLoggable(logLevel: LogLevel, tag: String, f: LogContext.() -> Unit) { - if (isLoggable(logLevel, tag)) { + if (_isLoggable(logLevel, tag)) { object : LogContext { override fun log(message: String?, throwable: Throwable?) { - this@LoggingHandler.log(logLevel, tag, message, throwable) + this@LoggingHandler._log(logLevel, tag, message, throwable) } }.f() } @@ -53,17 +53,17 @@ abstract class LoggingHandler { companion object { val loggingHandlers: MutableSet<LoggingHandler> = mutableSetOf(JavaLoggingHandler) - inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, message: String?, + inline fun log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) { - LoggingHandler.loggingHandlers - .filter { it.isLoggable(logLevel, tag) } - .forEach { it.log(logLevel, tag, message, throwable) } + loggingHandlers + .filter { it._isLoggable(logLevel, tag) } + .forEach { it._log(logLevel, tag, message, throwable) } } - inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, throwable: Throwable) = + inline fun log(logLevel: LogLevel, tag: String, throwable: Throwable) = log(logLevel, tag, null, throwable) - inline fun log(logLevel: LoggingHandler.LogLevel, tag: String, message: String) = + inline fun log(logLevel: LogLevel, tag: String, message: String) = log(logLevel, tag, message, null) } } diff --git a/lib/src/main/java/de/kuschku/libquassel/util/compatibility/reference/JavaLoggingHandler.kt b/lib/src/main/java/de/kuschku/libquassel/util/compatibility/reference/JavaLoggingHandler.kt index 08da6f1c4..4d2d75ac8 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/compatibility/reference/JavaLoggingHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/compatibility/reference/JavaLoggingHandler.kt @@ -24,13 +24,13 @@ import java.util.logging.Level import java.util.logging.Logger object JavaLoggingHandler : LoggingHandler() { - override fun isLoggable(logLevel: LogLevel, tag: String): Boolean { + override fun _isLoggable(logLevel: LogLevel, tag: String): Boolean { return Logger.getLogger(tag).isLoggable( priority(logLevel) ) } - override fun log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) { + override fun _log(logLevel: LogLevel, tag: String, message: String?, throwable: Throwable?) { val priority = priority( logLevel ) diff --git a/lib/src/main/java/de/kuschku/libquassel/util/flag/Flag.kt b/lib/src/main/java/de/kuschku/libquassel/util/flag/Flag.kt index c1b40a8a4..84c119221 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/flag/Flag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/flag/Flag.kt @@ -19,7 +19,7 @@ package de.kuschku.libquassel.util.flag -import de.kuschku.libquassel.util.helpers.sum +import de.kuschku.libquassel.util.helper.sum import java.io.Serializable interface Flag<T> : Serializable where T : Enum<T>, T : Flag<T> { diff --git a/lib/src/main/java/de/kuschku/libquassel/util/flag/LongFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/flag/LongFlag.kt index ce5deff1e..f10d64690 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/flag/LongFlag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/flag/LongFlag.kt @@ -19,7 +19,7 @@ package de.kuschku.libquassel.util.flag -import de.kuschku.libquassel.util.helpers.sum +import de.kuschku.libquassel.util.helper.sum import java.io.Serializable interface LongFlag<T> : Serializable where T : Enum<T>, T : LongFlag<T> { diff --git a/lib/src/main/java/de/kuschku/libquassel/util/flag/ShortFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/flag/ShortFlag.kt index 8369662f7..fbfe36b9c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/flag/ShortFlag.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/flag/ShortFlag.kt @@ -19,7 +19,7 @@ package de.kuschku.libquassel.util.flag -import de.kuschku.libquassel.util.helpers.sum +import de.kuschku.libquassel.util.helper.sum import java.io.Serializable interface ShortFlag<T> : Serializable where T : Enum<T>, T : ShortFlag<T> { diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/AnyHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/AnyHelper.kt similarity index 94% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/AnyHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/AnyHelper.kt index eac352e8d..abac54099 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/AnyHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/AnyHelper.kt @@ -17,6 +17,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper inline fun <T> T.nullIf(f: (T) -> Boolean): T? = if (f(this)) null else this diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/ArrayHelper.kt similarity index 96% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/ArrayHelper.kt index 0cad4c36f..fa359979d 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ArrayHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/ArrayHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/ByteBufferHelper.kt similarity index 96% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/ByteBufferHelper.kt index 88ca0e7d6..cf150ebb0 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/ByteBufferHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer import java.nio.ByteBuffer diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/CollectionHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/CollectionHelper.kt similarity index 97% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/CollectionHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/CollectionHelper.kt index 762ee9808..5aa07825c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/CollectionHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/CollectionHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper /** diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/MapHelper.kt similarity index 95% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/MapHelper.kt index 1c1605814..7d1d0a1ca 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/MapHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper fun <K, V> Map<K, V>.getOr(key: K, defValue: V) = this[key] ?: defValue diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/MathHelper.kt similarity index 95% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/MathHelper.kt index be6b40224..e75d19975 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/MathHelper.kt @@ -18,7 +18,7 @@ */ @file:Suppress("NOTHING_TO_INLINE") -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper inline fun clampOf(value: Int, lowerBound: Int, upperBound: Int): Int = maxOf(lowerBound, minOf(value, upperBound)) diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/ObservableHelper.kt similarity index 50% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/ObservableHelper.kt index 310b5effc..2743979f6 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/ObservableHelper.kt @@ -17,10 +17,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper import de.kuschku.libquassel.util.Optional import io.reactivex.Observable +import io.reactivex.ObservableSource +import io.reactivex.functions.BiFunction fun <T> Observable<T>.or(default: T): T = try { this.blockingLatest().firstOrNull() ?: default @@ -70,3 +72,81 @@ fun <T : Any, U : Any> Observable<Optional<T>>.flatMapSwitchMap( fun <T : Any> Observable<Optional<T>>.mapOrElse(orElse: T): Observable<T> = map { it.orElse(orElse) } + +inline fun <reified A, B> combineLatest( + a: ObservableSource<A>, + b: ObservableSource<B> +): Observable<Pair<A, B>> = + Observable.combineLatest(a, b, BiFunction(::Pair)) + +inline fun <reified A, B, C> combineLatest( + a: ObservableSource<A>, + b: ObservableSource<B>, + c: ObservableSource<C> +): Observable<Triple<A, B, C>> = + Observable.combineLatest(listOf(a, b, c)) { + Triple(it[0], it[1], it[2]) as Triple<A, B, C> + } + +inline fun <reified A, B, C, D> combineLatest( + a: ObservableSource<A>, + b: ObservableSource<B>, + c: ObservableSource<C>, + d: ObservableSource<D> +): Observable<Tuple4<A, B, C, D>> = + Observable.combineLatest(listOf(a, b, c, d)) { + Tuple4(it[0], it[1], it[2], it[3]) as Tuple4<A, B, C, D> + } + +inline fun <reified A, B, C, D, E> combineLatest( + a: ObservableSource<A>, + b: ObservableSource<B>, + c: ObservableSource<C>, + d: ObservableSource<D>, + e: ObservableSource<E> +): Observable<Tuple5<A, B, C, D, E>> = + Observable.combineLatest(listOf(a, b, c, d, e)) { + Tuple5(it[0], it[1], it[2], it[3], it[4]) as Tuple5<A, B, C, D, E> + } + +inline fun <reified A, B, C, D, E, F> combineLatest( + a: ObservableSource<A>, + b: ObservableSource<B>, + c: ObservableSource<C>, + d: ObservableSource<D>, + e: ObservableSource<E>, + f: ObservableSource<F> +): Observable<Tuple6<A, B, C, D, E, F>> = + Observable.combineLatest(listOf(a, b, c, d, e, f)) { + Tuple6(it[0], it[1], it[2], it[3], it[4], it[5]) as Tuple6<A, B, C, D, E, F> + } + +inline fun <reified T> combineLatest(sources: Iterable<ObservableSource<out T>?>) = + Observable.combineLatest(sources) { t -> t.toList() as List<T> } + +inline operator fun <T, U> Observable<T>.invoke(f: (T) -> U?) = + blockingLatest().firstOrNull()?.let(f) + +data class Tuple4<out A, out B, out C, out D>( + val first: A, + val second: B, + val third: C, + val fourth: D +) + +data class Tuple5<out A, out B, out C, out D, out E>( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E +) + +data class Tuple6<out A, out B, out C, out D, out E, out F>( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E, + val sixth: F +) diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/StringHelper.kt similarity index 96% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/StringHelper.kt index 30ee8c52a..81a0c7d69 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/StringHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/WritableByteChannelHelper.kt similarity index 95% rename from lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt rename to lib/src/main/java/de/kuschku/libquassel/util/helper/WritableByteChannelHelper.kt index 59d3e7fdc..0f89d9a98 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/WritableByteChannelHelper.kt @@ -17,7 +17,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.util.helpers +package de.kuschku.libquassel.util.helper import de.kuschku.libquassel.util.nio.ChainedByteBuffer import java.nio.channels.WritableByteChannel diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Backend.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt similarity index 68% rename from lib/src/main/java/de/kuschku/libquassel/session/Backend.kt rename to viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt index ac5985ecc..873396569 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Backend.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt @@ -17,20 +17,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.session +package de.kuschku.quasseldroid import de.kuschku.libquassel.connection.SocketAddress +import de.kuschku.libquassel.session.SessionManager interface Backend { - fun connectUnlessConnected(address: SocketAddress, user: String, pass: String, - requireSsl: Boolean, reconnect: Boolean) + fun autoConnect( + ignoreConnectionState: Boolean = false, + ignoreSetting: Boolean = false, + ignoreErrors: Boolean = false, + connectionInfo: ConnectionInfo? = null + ) - fun connect(address: SocketAddress, user: String, pass: String, requireSsl: Boolean, - reconnect: Boolean) - - fun reconnect() fun disconnect(forever: Boolean = false) fun sessionManager(): SessionManager? fun updateUserDataAndLogin(user: String, pass: String) fun requestConnectNewNetwork() + + data class ConnectionInfo( + val address: SocketAddress, + val username: String, + val password: String, + val requireSsl: Boolean, + val shouldReconnect: Boolean + ) } diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt index 461f5fe6f..29fcde095 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/helper/ObservableHelper.kt @@ -24,7 +24,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.LiveDataReactiveStreams import de.kuschku.libquassel.util.compatibility.HandlerService import io.reactivex.* -import io.reactivex.functions.BiFunction import io.reactivex.schedulers.Schedulers inline fun <T> Observable<T>.toLiveData( @@ -44,81 +43,3 @@ inline fun <T> Flowable<T>.toLiveData( handlerService: HandlerService? = null, scheduler: Scheduler = handlerService?.scheduler ?: Schedulers.computation() ): LiveData<T> = LiveDataReactiveStreams.fromPublisher(subscribeOn(scheduler)) - -inline fun <reified A, B> combineLatest( - a: ObservableSource<A>, - b: ObservableSource<B> -): Observable<Pair<A, B>> = - Observable.combineLatest(a, b, BiFunction(::Pair)) - -inline fun <reified A, B, C> combineLatest( - a: ObservableSource<A>, - b: ObservableSource<B>, - c: ObservableSource<C> -): Observable<Triple<A, B, C>> = - Observable.combineLatest(listOf(a, b, c)) { - Triple(it[0], it[1], it[2]) as Triple<A, B, C> - } - -inline fun <reified A, B, C, D> combineLatest( - a: ObservableSource<A>, - b: ObservableSource<B>, - c: ObservableSource<C>, - d: ObservableSource<D> -): Observable<Tuple4<A, B, C, D>> = - Observable.combineLatest(listOf(a, b, c, d)) { - Tuple4(it[0], it[1], it[2], it[3]) as Tuple4<A, B, C, D> - } - -inline fun <reified A, B, C, D, E> combineLatest( - a: ObservableSource<A>, - b: ObservableSource<B>, - c: ObservableSource<C>, - d: ObservableSource<D>, - e: ObservableSource<E> -): Observable<Tuple5<A, B, C, D, E>> = - Observable.combineLatest(listOf(a, b, c, d, e)) { - Tuple5(it[0], it[1], it[2], it[3], it[4]) as Tuple5<A, B, C, D, E> - } - -inline fun <reified A, B, C, D, E, F> combineLatest( - a: ObservableSource<A>, - b: ObservableSource<B>, - c: ObservableSource<C>, - d: ObservableSource<D>, - e: ObservableSource<E>, - f: ObservableSource<F> -): Observable<Tuple6<A, B, C, D, E, F>> = - Observable.combineLatest(listOf(a, b, c, d, e, f)) { - Tuple6(it[0], it[1], it[2], it[3], it[4], it[5]) as Tuple6<A, B, C, D, E, F> - } - -inline fun <reified T> combineLatest(sources: Iterable<ObservableSource<out T>?>) = - Observable.combineLatest(sources) { t -> t.toList() as List<T> } - -inline operator fun <T, U> Observable<T>.invoke(f: (T) -> U?) = - blockingLatest().firstOrNull()?.let(f) - -data class Tuple4<out A, out B, out C, out D>( - val first: A, - val second: B, - val third: C, - val fourth: D -) - -data class Tuple5<out A, out B, out C, out D, out E>( - val first: A, - val second: B, - val third: C, - val fourth: D, - val fifth: E -) - -data class Tuple6<out A, out B, out C, out D, out E, out F>( - val first: A, - val second: B, - val third: C, - val fourth: D, - val fifth: E, - val sixth: F -) 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 b18a60589..8021a2bb9 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt @@ -20,8 +20,8 @@ package de.kuschku.quasseldroid.viewmodel import androidx.lifecycle.ViewModel -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.util.Optional +import de.kuschku.quasseldroid.Backend import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt index 48a72a128..0e6a0ba72 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt @@ -32,12 +32,8 @@ import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.flag.and import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.flatMapSwitchMap -import de.kuschku.libquassel.util.helpers.mapNullable -import de.kuschku.libquassel.util.helpers.mapSwitchMap -import de.kuschku.libquassel.util.helpers.switchMapNullable +import de.kuschku.libquassel.util.helper.* import de.kuschku.libquassel.util.irc.IrcCaseMappers -import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.viewmodel.ChatViewModel import de.kuschku.quasseldroid.viewmodel.QuasselViewModel import de.kuschku.quasseldroid.viewmodel.data.* @@ -63,14 +59,14 @@ open class ChatViewModelHelper @Inject constructor( /** * An observable of the changes of the markerline, as pairs of `(old, new)` */ - val markerLine = session.mapSwitchMap { currentSession -> + val markerLine = connectedSession.mapSwitchMap { currentSession -> chat.bufferId.switchMap { currentBuffer -> // Get a stream of the latest marker line currentSession.bufferSyncer.liveMarkerLine(currentBuffer) } } - val bufferData = combineLatest(session, chat.bufferId) + val bufferData = combineLatest(connectedSession, chat.bufferId) .switchMap { (sessionOptional, id) -> val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer @@ -135,7 +131,7 @@ open class ChatViewModelHelper @Inject constructor( val bufferDataThrottled = bufferData.distinctUntilChanged().throttleLast(100, TimeUnit.MILLISECONDS) - val nickData: Observable<List<IrcUserItem>> = combineLatest(session, chat.bufferId) + val nickData: Observable<List<IrcUserItem>> = combineLatest(connectedSession, chat.bufferId) .switchMap { (sessionOptional, buffer) -> val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer @@ -179,7 +175,7 @@ open class ChatViewModelHelper @Inject constructor( val nickDataThrottled = nickData.distinctUntilChanged().throttleLast(100, TimeUnit.MILLISECONDS) - val selectedBuffer = combineLatest(session, chat.selectedBufferId, bufferViewConfig) + val selectedBuffer = combineLatest(connectedSession, chat.selectedBufferId, bufferViewConfig) .switchMap { (sessionOptional, buffer, bufferViewConfigOptional) -> val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer @@ -238,7 +234,7 @@ open class ChatViewModelHelper @Inject constructor( } val bufferList: Observable<Pair<BufferViewConfig?, List<BufferProps>>> = - combineLatest(session, bufferViewConfig, chat.showHidden, chat.bufferSearch) + combineLatest(connectedSession, bufferViewConfig, chat.showHidden, chat.bufferSearch) .switchMap { (sessionOptional, configOptional, showHiddenRaw, bufferSearch) -> val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt index ebe446511..a4d4200c8 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt @@ -28,9 +28,9 @@ import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.flag.hasFlag -import de.kuschku.libquassel.util.helpers.mapNullable -import de.kuschku.libquassel.util.helpers.nullIf -import de.kuschku.quasseldroid.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.combineLatest +import de.kuschku.libquassel.util.helper.mapNullable +import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.quasseldroid.viewmodel.ChatViewModel import de.kuschku.quasseldroid.viewmodel.EditorViewModel import de.kuschku.quasseldroid.viewmodel.QuasselViewModel @@ -46,15 +46,14 @@ open class EditorViewModelHelper @Inject constructor( quassel: QuasselViewModel ) : ChatViewModelHelper(chat, quassel) { val rawAutoCompleteData: Observable<Triple<Optional<ISession>, BufferId, Pair<String, IntRange>>> = - combineLatest(session, - chat.bufferId, - editor.lastWord).switchMap { (sessionOptional, id, lastWordWrapper) -> - lastWordWrapper - .distinctUntilChanged() - .map { lastWord -> - Triple(sessionOptional, id, lastWord) - } - } + combineLatest(connectedSession, chat.bufferId, editor.lastWord) + .switchMap { (sessionOptional, id, lastWordWrapper) -> + lastWordWrapper + .distinctUntilChanged() + .map { lastWord -> + Triple(sessionOptional, id, lastWord) + } + } val autoCompleteData: Observable<Pair<String, List<AutoCompleteItem>>> = rawAutoCompleteData .distinctUntilChanged() diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt index 4159c5a67..ad9184a4d 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt @@ -25,12 +25,12 @@ import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.CoreInfo -import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.ssl.X509Helper import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.helpers.* +import de.kuschku.libquassel.util.helper.* +import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.viewmodel.QuasselViewModel import io.reactivex.Observable import javax.inject.Inject @@ -41,15 +41,15 @@ open class QuasselViewModelHelper @Inject constructor( ) { val backend = quassel.backendWrapper.switchMap { it } val sessionManager = backend.mapMapNullable(Backend::sessionManager) - val session = sessionManager.mapSwitchMap(SessionManager::session) - val rpcHandler = session.mapMap(ISession::rpcHandler) - val ircListHelper = session.mapMap(ISession::ircListHelper) + val connectedSession = sessionManager.mapSwitchMap(SessionManager::connectedSession) + val rpcHandler = connectedSession.mapMap(ISession::rpcHandler) + val ircListHelper = connectedSession.mapMap(ISession::ircListHelper) val features = sessionManager.mapSwitchMap { manager -> manager.state.switchMap { state -> if (state != ConnectionState.CONNECTED) { Observable.just(Pair(false, Features.empty())) } else { - manager.session.map { + manager.connectedSession.map { Pair(true, it.features) } } @@ -68,48 +68,44 @@ open class QuasselViewModelHelper @Inject constructor( val connectionProgress = sessionManager.mapSwitchMap(SessionManager::connectionProgress) .mapOrElse(Triple(ConnectionState.DISCONNECTED, 0, 0)) - val bufferViewManager = session.mapMap(ISession::bufferViewManager) + val bufferViewManager = connectedSession.mapMap(ISession::bufferViewManager) val errors = sessionManager.switchMap { - it.orNull()?.error ?: Observable.empty() + it.orNull()?.errors ?: Observable.empty() } - val connectionErrors = sessionManager.switchMap { - it.orNull()?.connectionError ?: Observable.empty() - } - - val sslSession = session.flatMapSwitchMap(ISession::sslSession) + val sslSession = connectedSession.flatMapSwitchMap(ISession::sslSession) val peerCertificateChain = sslSession.mapMap(SSLSession::getPeerCertificateChain).mapMap { it.mapNotNull(X509Helper::convert) }.mapOrElse(emptyList()) val leafCertificate = peerCertificateChain.map { Optional.ofNullable(it.firstOrNull()) } - val coreInfo = session.mapMap(ISession::coreInfo).mapSwitchMap(CoreInfo::liveInfo) + val coreInfo = connectedSession.mapMap(ISession::coreInfo).mapSwitchMap(CoreInfo::liveInfo) val coreInfoClients = coreInfo.mapMap(CoreInfo.CoreData::sessionConnectedClientData) .mapOrElse(emptyList()) - val networkConfig = session.mapMap(ISession::networkConfig) + val networkConfig = connectedSession.mapMap(ISession::networkConfig) - val ignoreListManager = session.mapMap(ISession::ignoreListManager) + val ignoreListManager = connectedSession.mapMap(ISession::ignoreListManager) - val highlightRuleManager = session.mapMap(ISession::highlightRuleManager) + val highlightRuleManager = connectedSession.mapMap(ISession::highlightRuleManager) - val aliasManager = session.mapMap(ISession::aliasManager) + val aliasManager = connectedSession.mapMap(ISession::aliasManager) - val networks = session.switchMap { + val networks = connectedSession.switchMap { it.map(ISession::liveNetworks).orElse(Observable.just(emptyMap())) } - val identities = session.switchMap { + val identities = connectedSession.switchMap { it.map(ISession::liveIdentities).orElse(Observable.just(emptyMap())) } - val bufferSyncer = session.mapMap(ISession::bufferSyncer) + val bufferSyncer = connectedSession.mapMap(ISession::bufferSyncer) val allBuffers = bufferSyncer.mapSwitchMap { it.liveBufferInfos().map(Map<BufferId, BufferInfo>::values) }.mapOrElse(emptyList()) - val lag: Observable<Long> = session.mapSwitchMap(ISession::lag).mapOrElse(0) + val lag: Observable<Long> = connectedSession.mapSwitchMap(ISession::lag).mapOrElse(0) val bufferViewConfigs = bufferViewManager.mapSwitchMap { manager -> manager.liveBufferViewConfigs().map { ids -> -- GitLab