diff --git a/app/src/main/java/chat/stoat/activities/MainActivity.kt b/app/src/main/java/chat/stoat/activities/MainActivity.kt index 0c91a030..2a165c3d 100644 --- a/app/src/main/java/chat/stoat/activities/MainActivity.kt +++ b/app/src/main/java/chat/stoat/activities/MainActivity.kt @@ -180,6 +180,11 @@ class MainActivityViewModel @Inject constructor( isReady.emit(true) } + private suspend fun showLoginError() { + couldNotLogIn.emit(true) + startWithoutDestination() + } + private fun doPreStartupTasks() { Log.d("MainActivity", "Performing pre-startup tasks") viewModelScope.launch { @@ -231,7 +236,7 @@ class MainActivityViewModel @Inject constructor( if (canReachStoat && !valid) { Log.d("MainActivity", "Session token is invalid, could not log in") - couldNotLogIn.emit(true) + showLoginError() } else { try { Log.d("MainActivity", "Session token is valid, checking onboarding state") @@ -251,7 +256,7 @@ class MainActivityViewModel @Inject constructor( return@launch startWithoutDestination() } catch (e: Exception) { Log.e("MainActivity", "Failed to check onboarding state, could not log in", e) - couldNotLogIn.emit(true) + showLoginError() } try { @@ -265,7 +270,7 @@ class MainActivityViewModel @Inject constructor( } } catch (e: Exception) { Log.e("MainActivity", "Failed to login, could not log in", e) - couldNotLogIn.emit(true) + showLoginError() } } } diff --git a/app/src/main/java/chat/stoat/screens/chat/views/channel/ChannelScreenViewModel.kt b/app/src/main/java/chat/stoat/screens/chat/views/channel/ChannelScreenViewModel.kt index 5dd82f28..0054a8a5 100644 --- a/app/src/main/java/chat/stoat/screens/chat/views/channel/ChannelScreenViewModel.kt +++ b/app/src/main/java/chat/stoat/screens/chat/views/channel/ChannelScreenViewModel.kt @@ -33,6 +33,7 @@ import chat.stoat.api.realtime.frames.receivable.MessageUpdateFrame import chat.stoat.api.routes.channel.SendMessageReply import chat.stoat.api.routes.channel.ackChannel import chat.stoat.api.routes.channel.editMessage +import chat.stoat.api.routes.channel.fetchSingleChannel import chat.stoat.api.routes.channel.fetchMessagesFromChannel import chat.stoat.api.routes.channel.sendMessage import chat.stoat.api.routes.microservices.autumn.FileArgs @@ -113,10 +114,25 @@ class ChannelScreenViewModel @Inject constructor( private var loadMessagesJob: Job? = null + private suspend fun resolveChannel(channelId: String): Channel? { + StoatAPI.channelCache[channelId]?.let { return it } + + return try { + fetchSingleChannel(channelId).also { fetched -> + if (fetched.id != null) { + StoatAPI.channelCache[fetched.id!!] = fetched + } + } + } catch (e: Exception) { + Log.e("ChannelScreenViewModel", "Failed to resolve channel $channelId", e) + null + } + } + fun switchChannel(id: String) { // Reset state this.loadMessagesJob?.cancel() - this.channel = StoatAPI.channelCache[id] + this.channel = null this.items = mutableStateListOf(ChannelScreenItem.Loading) this.activePane = ChannelScreenActivePane.None this.typingUsers = mutableStateListOf() @@ -126,30 +142,45 @@ class ChannelScreenViewModel @Inject constructor( this.denyMessageField = false this.denyMessageFieldReasonResource = R.string.typing_blank this.editingMessage = null - this.ageGateUnlocked = channel?.nsfw != true - this.showGeoGate = when { - channel?.nsfw == true && GeoStateProvider.geoState?.isAgeRestrictedGeo == true -> true - else -> false - } - viewModelScope.launch { - if (ageGateUnlocked != true) { - ageGateUnlocked = AgeGateUnlockedStorageProvider.getAgeGateUnlocked() - } - } + this.ageGateUnlocked = null + this.showGeoGate = false viewModelScope.launch { - putDraftContent(kvStorage.get("draftContent/$id") ?: "", true) + val restoredDraft = kvStorage.get("draftContent/$id") ?: "" + draftContent = restoredDraft + initialTextFieldValue = restoredDraft + initialTextFieldValueDirtyMarker = ULID.makeNext() } this.draftAttachments = mutableStateListOf() this.draftReplyTo = mutableStateListOf() this.attachmentUploadProgress = 0f viewModelScope.launch { + val resolvedChannel = resolveChannel(id) + this@ChannelScreenViewModel.channel = resolvedChannel + + if (resolvedChannel == null) { + updateItems(emptyList()) + ActionChannel.send( + Action.ChatNavigate( + ChatRouterDestination.NoCurrentChannel(null) + ) + ) + return@launch + } + + this@ChannelScreenViewModel.ageGateUnlocked = resolvedChannel.nsfw != true + this@ChannelScreenViewModel.showGeoGate = + resolvedChannel.nsfw == true && GeoStateProvider.geoState?.isAgeRestrictedGeo == true + + if (ageGateUnlocked != true) { + ageGateUnlocked = AgeGateUnlockedStorageProvider.getAgeGateUnlocked() + } + ensureSelfHasMember() denyMessageFieldIfNeeded() + loadMessages(50, markLastAsRead = true) } - - this.loadMessages(50, markLastAsRead = true) } suspend fun unlockAgeGate() { @@ -260,8 +291,10 @@ class ChannelScreenViewModel @Inject constructor( * and, if [setInitial] is true, updates the text field to say the new [content]. */ fun putDraftContent(content: String, setInitial: Boolean = false) { - viewModelScope.launch { - kvStorage.set("draftContent/${channel?.id}", content) + channel?.id?.let { channelId -> + viewModelScope.launch { + kvStorage.set("draftContent/$channelId", content) + } } if (editingMessage == null) {