This commit is contained in:
Gabriel 2026-04-06 12:00:12 +02:00 committed by GitHub
commit 34b001a0a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 19 deletions

View File

@ -180,6 +180,11 @@ class MainActivityViewModel @Inject constructor(
isReady.emit(true) isReady.emit(true)
} }
private suspend fun showLoginError() {
couldNotLogIn.emit(true)
startWithoutDestination()
}
private fun doPreStartupTasks() { private fun doPreStartupTasks() {
Log.d("MainActivity", "Performing pre-startup tasks") Log.d("MainActivity", "Performing pre-startup tasks")
viewModelScope.launch { viewModelScope.launch {
@ -231,7 +236,7 @@ class MainActivityViewModel @Inject constructor(
if (canReachStoat && !valid) { if (canReachStoat && !valid) {
Log.d("MainActivity", "Session token is invalid, could not log in") Log.d("MainActivity", "Session token is invalid, could not log in")
couldNotLogIn.emit(true) showLoginError()
} else { } else {
try { try {
Log.d("MainActivity", "Session token is valid, checking onboarding state") Log.d("MainActivity", "Session token is valid, checking onboarding state")
@ -251,7 +256,7 @@ class MainActivityViewModel @Inject constructor(
return@launch startWithoutDestination() return@launch startWithoutDestination()
} catch (e: Exception) { } catch (e: Exception) {
Log.e("MainActivity", "Failed to check onboarding state, could not log in", e) Log.e("MainActivity", "Failed to check onboarding state, could not log in", e)
couldNotLogIn.emit(true) showLoginError()
} }
try { try {
@ -265,7 +270,7 @@ class MainActivityViewModel @Inject constructor(
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("MainActivity", "Failed to login, could not log in", e) Log.e("MainActivity", "Failed to login, could not log in", e)
couldNotLogIn.emit(true) showLoginError()
} }
} }
} }

View File

@ -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.SendMessageReply
import chat.stoat.api.routes.channel.ackChannel import chat.stoat.api.routes.channel.ackChannel
import chat.stoat.api.routes.channel.editMessage 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.fetchMessagesFromChannel
import chat.stoat.api.routes.channel.sendMessage import chat.stoat.api.routes.channel.sendMessage
import chat.stoat.api.routes.microservices.autumn.FileArgs import chat.stoat.api.routes.microservices.autumn.FileArgs
@ -113,10 +114,25 @@ class ChannelScreenViewModel @Inject constructor(
private var loadMessagesJob: Job? = null 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) { fun switchChannel(id: String) {
// Reset state // Reset state
this.loadMessagesJob?.cancel() this.loadMessagesJob?.cancel()
this.channel = StoatAPI.channelCache[id] this.channel = null
this.items = mutableStateListOf(ChannelScreenItem.Loading) this.items = mutableStateListOf(ChannelScreenItem.Loading)
this.activePane = ChannelScreenActivePane.None this.activePane = ChannelScreenActivePane.None
this.typingUsers = mutableStateListOf() this.typingUsers = mutableStateListOf()
@ -126,30 +142,45 @@ class ChannelScreenViewModel @Inject constructor(
this.denyMessageField = false this.denyMessageField = false
this.denyMessageFieldReasonResource = R.string.typing_blank this.denyMessageFieldReasonResource = R.string.typing_blank
this.editingMessage = null this.editingMessage = null
this.ageGateUnlocked = channel?.nsfw != true this.ageGateUnlocked = null
this.showGeoGate = when { this.showGeoGate = false
channel?.nsfw == true && GeoStateProvider.geoState?.isAgeRestrictedGeo == true -> true
else -> false
}
viewModelScope.launch {
if (ageGateUnlocked != true) {
ageGateUnlocked = AgeGateUnlockedStorageProvider.getAgeGateUnlocked()
}
}
viewModelScope.launch { 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.draftAttachments = mutableStateListOf()
this.draftReplyTo = mutableStateListOf() this.draftReplyTo = mutableStateListOf()
this.attachmentUploadProgress = 0f this.attachmentUploadProgress = 0f
viewModelScope.launch { 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() ensureSelfHasMember()
denyMessageFieldIfNeeded() denyMessageFieldIfNeeded()
loadMessages(50, markLastAsRead = true)
} }
this.loadMessages(50, markLastAsRead = true)
} }
suspend fun unlockAgeGate() { 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]. * and, if [setInitial] is true, updates the text field to say the new [content].
*/ */
fun putDraftContent(content: String, setInitial: Boolean = false) { fun putDraftContent(content: String, setInitial: Boolean = false) {
viewModelScope.launch { channel?.id?.let { channelId ->
kvStorage.set("draftContent/${channel?.id}", content) viewModelScope.launch {
kvStorage.set("draftContent/$channelId", content)
}
} }
if (editingMessage == null) { if (editingMessage == null) {