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 0dbd525c08339ab5bc7b0a02946dc3308ff5f310..63c754f1c347101d4a980005b04926a3c14d7a99 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt @@ -292,6 +292,7 @@ class QuasselService : DaggerLifecycleService(), notificationManager.init() update() + updateNotificationStatus() } override fun onDestroy() { 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 b8d174a5f87d1097adecf61970bf2751409a5eb6..e1cb63af9f790856decd1af53f76376e076e9559 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 @@ -117,9 +117,10 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc findViewById(R.id.formatting_toolbar), appearanceSettings, { lines -> - viewModel.session { session -> + viewModel.session { sessionOptional -> + val session = sessionOptional.orNull() viewModel.buffer { bufferId -> - session.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo -> + session?.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo -> val output = mutableListOf<IAliasManager.Command>() for ((stripped, formatted) in lines) { viewModel.addRecentlySentMessage(stripped) @@ -205,12 +206,14 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc progressBar.hide() } ConnectionState.INIT -> { + progressBar.show() // Show indeterminate when no progress has been made yet progressBar.isIndeterminate = progress == 0 || max == 0 progressBar.progress = progress progressBar.max = max } else -> { + progressBar.show() progressBar.isIndeterminate = true } } 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 baf634d4a53374136055bf89843859a303f4a9cd..df45c9a343af0c0faaa18557ee0e245ee3ee218b 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 @@ -57,7 +57,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean { val selected = viewModel.selectedBuffer.value val info = selected?.info - val session = viewModel.session.value + val session = viewModel.session.value?.orNull() val bufferSyncer = session?.bufferSyncer val network = session?.networks?.get(selected?.info?.networkId) val bufferViewConfig = viewModel.bufferViewConfig.value 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 47fe8b8075bbe9df07cfa75b888a835d50dc5dd8..66662eeeae2a8e5b3d572258c5bee90409c6eed9 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 @@ -114,7 +114,7 @@ class MessageListFragment : ServiceBoundFragment() { viewModel.sessionManager_liveData.zip(lastMessageId).observe( this, Observer { runInBackground { - val session = it?.first + val session = it?.first?.orNull() val message = it?.second val bufferSyncer = session?.bufferSyncer if (message != null && bufferSyncer != null && previousMessageId != message.messageId) { @@ -125,8 +125,10 @@ class MessageListFragment : ServiceBoundFragment() { }) viewModel.markerLine_liveData.observe(this, Observer { - adapter.markerLinePosition = it - adapter.notifyDataSetChanged() + it?.ifPresent { + adapter.markerLinePosition = it + adapter.notifyDataSetChanged() + } }) var lastBuffer = -1 @@ -184,7 +186,7 @@ class MessageListFragment : ServiceBoundFragment() { val previous = lastBuffer val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() val messageId = adapter[firstVisibleItemPosition]?.messageId - val bufferSyncer = viewModel.sessionManager.value?.bufferSyncer + val bufferSyncer = viewModel.session.value?.orNull()?.bufferSyncer if (previous != null && messageId != null) { bufferSyncer?.requestSetMarkerLine(previous, messageId) } @@ -194,8 +196,8 @@ class MessageListFragment : ServiceBoundFragment() { private fun loadMore() { runInBackground { viewModel.buffer { bufferId -> - viewModel.sessionManager { - it.backlogManager?.requestBacklog( + viewModel.session { + it.orNull()?.backlogManager?.requestBacklog( bufferId = bufferId, last = database.message().findFirstByBufferId( bufferId 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 d5e987d835c28e0a78fae283cb9f494d403c216c..fcbe67e6f13f264e59ac6371d02201b5eba5f14c 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 @@ -132,15 +132,9 @@ abstract class ServiceBoundActivity : AppCompatActivity(), } val accountIdValid = accountId != -1L - log( - LoggingHandler.LogLevel.ERROR, "DEBUG", - "reconnect: $reconnect, accountIdValid: $accountIdValid" - ) - if (!reconnect || !accountIdValid) { if (!startedSelection) { - log(LoggingHandler.LogLevel.ERROR, "DEBUG", "started: $REQUEST_SELECT_ACCOUNT") startActivityForResult( Intent(this, AccountSelectionActivity::class.java), REQUEST_SELECT_ACCOUNT ) 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 d3b160dbe4184f68a9ec077da193b9c86e00334a..cfb0c8528da93a7c32973982898d413cf78a75b4 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -7,7 +7,8 @@ import de.kuschku.libquassel.quassel.QuasselFeature import de.kuschku.libquassel.quassel.syncables.* import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log -import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.* +import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG +import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO import de.kuschku.libquassel.util.hasFlag import io.reactivex.subjects.BehaviorSubject import org.threeten.bp.Instant @@ -53,7 +54,6 @@ class Session( override val lag = BehaviorSubject.createDefault(0L) init { - log(ERROR, "DEBUG", "created session:", RuntimeException()) coreConnection.start() } diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt index 981b13430924e3539f49d5aa0180b09d8bdf7992..137c42e1bcc7659d2eeb27dd1946f8b2cc980423 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt @@ -10,4 +10,38 @@ fun <T> Observable<T>.or(default: T): T = try { } val <T> Observable<T>.value - get() = this.map { Optional.of(it) }.blockingMostRecent(Optional.empty()).firstOrNull()?.orNull() \ No newline at end of file + get() = this.map { Optional.of(it) }.blockingMostRecent(Optional.empty()).firstOrNull()?.orNull() + +fun <T, U> Observable<Optional<T>>.mapMap(mapper: (T) -> U): Observable<Optional<U>> = map { + it.map(mapper) +} + +fun <T, U> Observable<Optional<T>>.mapMapNullable(mapper: (T) -> U?): Observable<Optional<U>> = map { + it.flatMap { + Optional.ofNullable(mapper(it)) + } +} + +fun <T, U> Observable<Optional<T>>.mapSwitchMap(mapper: (T) -> Observable<U>): Observable<Optional<U>> = switchMap { + if (it.isPresent()) { + it.map(mapper).get().map { Optional.of(it) } + } else { + Observable.just(Optional.empty()) + } +} + +fun <T, U> Observable<Optional<T>>.mapSwitchMapEmpty(mapper: (T) -> Observable<U>): Observable<U> = switchMap { + if (it.isPresent()) { + it.map(mapper).get() + } else { + Observable.empty() + } +} + +fun <T, U> Observable<Optional<T>>.flatMapSwitchMap(mapper: (T) -> Observable<Optional<U>>): Observable<Optional<U>> = switchMap { + it.map(mapper).orElse(Observable.just(Optional.empty())) +} + +fun <T> Observable<Optional<T>>.mapOrElse(orElse: T): Observable<T> = map { + it.orElse(orElse) +} \ No newline at end of file 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 718d242dcce3d574f01ccf49ddba2dba170e723a..943e12ae6d2b2e0bae1517164e5816e078bb1bba 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt @@ -5,13 +5,18 @@ import de.kuschku.libquassel.protocol.BufferId 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.* +import de.kuschku.libquassel.quassel.syncables.BufferViewConfig +import de.kuschku.libquassel.quassel.syncables.IrcChannel +import de.kuschku.libquassel.quassel.syncables.IrcUser +import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.session.Backend +import de.kuschku.libquassel.session.ConnectionState import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.and import de.kuschku.libquassel.util.hasFlag +import de.kuschku.libquassel.util.helpers.* import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.viewmodel.data.* @@ -39,33 +44,29 @@ class QuasselViewModel : ViewModel() { } val backend = backendWrapper.switchMap { it } - val sessionManager = backend - .filter(Optional<Backend>::isPresent) - .map(Optional<Backend>::get) - .map(Backend::sessionManager) + val sessionManager = backend.mapMap(Backend::sessionManager) val sessionManager_liveData = sessionManager.toLiveData() - val session = sessionManager.switchMap(SessionManager::session) + val session = sessionManager.mapSwitchMap(SessionManager::session) - val connectionProgress = sessionManager.switchMap(SessionManager::connectionProgress) + val connectionProgress = sessionManager.mapSwitchMap(SessionManager::connectionProgress) + .mapOrElse(Triple(ConnectionState.DISCONNECTED, 0, 0)) val connectionProgress_liveData = connectionProgress.toLiveData() - val bufferViewManager = session.map { Optional.ofNullable(it.bufferViewManager) } - .filter(Optional<BufferViewManager>::isPresent) - .map(Optional<BufferViewManager>::get) + val bufferViewManager = session.mapMapNullable(ISession::bufferViewManager) - val bufferViewConfig = bufferViewManager.switchMap { manager -> + val bufferViewConfig = bufferViewManager.flatMapSwitchMap { manager -> bufferViewConfigId.map { id -> Optional.ofNullable(manager.bufferViewConfig(id)) } } - val errors = session.switchMap(ISession::error) + val errors = session.mapSwitchMapEmpty(ISession::error) val errors_liveData = errors.toLiveData() /** * An observable of the changes of the markerline, as pairs of `(old, new)` */ - val markerLine = session.switchMap { currentSession -> + val markerLine = session.mapSwitchMap { currentSession -> buffer.switchMap { currentBuffer -> // Get a stream of the latest marker line val raw = currentSession.bufferSyncer?.liveMarkerLine(currentBuffer) ?: Observable.empty() @@ -74,15 +75,17 @@ class QuasselViewModel : ViewModel() { } val markerLine_liveData = markerLine.toLiveData() - val lag: Observable<Long> = session.switchMap(ISession::lag) + // Remove orElse + val lag: Observable<Long> = session.mapSwitchMap(ISession::lag).mapOrElse(0) - val isSecure: Observable<Boolean> = session.switchMap { session -> + val isSecure: Observable<Boolean> = session.mapSwitchMap { session -> session.state.map { _ -> session.sslSession != null } - } + }.mapOrElse(false) - val bufferData = combineLatest(session, buffer).switchMap { (session, id) -> + val bufferData = combineLatest(session, buffer).switchMap { (sessionOptional, id) -> + val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer if (bufferSyncer != null) { bufferSyncer.liveBufferInfos().switchMap { @@ -138,7 +141,8 @@ class QuasselViewModel : ViewModel() { } val nickData: Observable<List<IrcUserItem>> = combineLatest(session, buffer) - .switchMap { (session, buffer) -> + .switchMap { (sessionOptional, buffer) -> + val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer val bufferInfo = bufferSyncer?.bufferInfo(buffer) if (bufferInfo?.type?.hasFlag(Buffer_Type.ChannelBuffer) == true) { @@ -179,11 +183,12 @@ class QuasselViewModel : ViewModel() { val lastWord = BehaviorSubject.create<Observable<Pair<String, IntRange>>>() val autoCompleteData: Observable<Pair<String, List<AutoCompleteItem>>> = - combineLatest(session, buffer, lastWord).switchMap { (session, id, lastWordWrapper) -> + combineLatest(session, buffer, lastWord).switchMap { (sessionOptional, id, lastWordWrapper) -> lastWordWrapper .distinctUntilChanged() .debounce(300, TimeUnit.MILLISECONDS) .switchMap { lastWord -> + val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer val bufferInfo = bufferSyncer?.bufferInfo(id) if (bufferSyncer != null) { @@ -269,20 +274,21 @@ class QuasselViewModel : ViewModel() { } } - val bufferViewConfigs = bufferViewManager.switchMap { manager -> + val bufferViewConfigs = bufferViewManager.mapSwitchMap { manager -> manager.liveBufferViewConfigs().map { ids -> ids.mapNotNull { id -> manager.bufferViewConfig(id) }.sortedWith(BufferViewConfig.NameComparator) } - } + }.mapOrElse(emptyList()) val showHidden = BehaviorSubject.createDefault(false) val collapsedNetworks = BehaviorSubject.createDefault(emptySet<NetworkId>()) val selectedBufferId = BehaviorSubject.createDefault(-1) val selectedBuffer = combineLatest(session, selectedBufferId, bufferViewConfig) - .switchMap { (session, buffer, bufferViewConfigOptional) -> - val bufferSyncer = session.bufferSyncer + .switchMap { (sessionOptional, buffer, bufferViewConfigOptional) -> + val session = sessionOptional.orNull() + val bufferSyncer = session?.bufferSyncer val bufferViewConfig = bufferViewConfigOptional.orNull() if (bufferSyncer != null && bufferViewConfig != null) { val hiddenState = when { @@ -330,7 +336,8 @@ class QuasselViewModel : ViewModel() { val bufferList: Observable<Pair<BufferViewConfig?, List<BufferProps>>?> = combineLatest(session, bufferViewConfig, showHidden) - .switchMap { (session, configOptional, showHiddenRaw) -> + .switchMap { (sessionOptional, configOptional, showHiddenRaw) -> + val session = sessionOptional.orNull() val bufferSyncer = session?.bufferSyncer val showHidden = showHiddenRaw ?: false val config = configOptional.orNull()