android: use saved chat endpoint in chats menu
This commit is contained in:
@@ -634,3 +634,8 @@
|
||||
- Improved `chat_updated` handling in realtime flow:
|
||||
- now refreshes both active and archived chats lists to sync user-scoped flags (`pinned`, `archived`) immediately.
|
||||
- Added parser fallback for realtime chat events to support payloads with either `chat_id` or `id`.
|
||||
|
||||
### Step 99 - Saved chat API parity
|
||||
- Added Android support for `GET /api/v1/chats/saved`.
|
||||
- Wired chats overflow `Saved` action to real backend request (instead of local title heuristic).
|
||||
- Saved chat is now upserted into local Room cache and opened via normal navigation flow.
|
||||
|
||||
@@ -31,6 +31,9 @@ interface ChatApiService {
|
||||
@Path("chat_id") chatId: Long,
|
||||
): ChatReadDto
|
||||
|
||||
@GET("/api/v1/chats/saved")
|
||||
suspend fun getSavedChat(): ChatReadDto
|
||||
|
||||
@POST("/api/v1/chats/{chat_id}/invite-link")
|
||||
suspend fun createInviteLink(
|
||||
@Path("chat_id") chatId: Long,
|
||||
|
||||
@@ -87,6 +87,18 @@ class NetworkChatRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSavedChat(): AppResult<ChatItem> = withContext(ioDispatcher) {
|
||||
try {
|
||||
val chat = chatApiService.getSavedChat()
|
||||
chatDao.upsertUsers(chat.toUserShortEntityOrNull()?.let(::listOf).orEmpty())
|
||||
val entity = chat.toChatEntity()
|
||||
chatDao.upsertChats(listOf(entity))
|
||||
AppResult.Success(entity.toDomain())
|
||||
} catch (error: Throwable) {
|
||||
AppResult.Error(error.toAppError())
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun createInviteLink(chatId: Long): AppResult<ChatInviteLink> = withContext(ioDispatcher) {
|
||||
try {
|
||||
AppResult.Success(chatApiService.createInviteLink(chatId = chatId).toDomain())
|
||||
|
||||
@@ -14,6 +14,7 @@ interface ChatRepository {
|
||||
fun observeChat(chatId: Long): Flow<ChatItem?>
|
||||
suspend fun refreshChats(archived: Boolean): AppResult<Unit>
|
||||
suspend fun refreshChat(chatId: Long): AppResult<Unit>
|
||||
suspend fun getSavedChat(): AppResult<ChatItem>
|
||||
suspend fun createInviteLink(chatId: Long): AppResult<ChatInviteLink>
|
||||
suspend fun joinByInvite(token: String): AppResult<ChatItem>
|
||||
suspend fun createChat(
|
||||
|
||||
@@ -118,6 +118,7 @@ fun ChatListRoute(
|
||||
onClearSearchHistory = viewModel::clearSearchHistory,
|
||||
onRefresh = viewModel::onPullToRefresh,
|
||||
onOpenChat = onOpenChat,
|
||||
onOpenSaved = viewModel::openSavedChat,
|
||||
isMainBarVisible = isMainBarVisible,
|
||||
onMainBarVisibilityChanged = onMainBarVisibilityChanged,
|
||||
onCreateGroup = viewModel::createGroup,
|
||||
@@ -154,6 +155,7 @@ fun ChatListScreen(
|
||||
onClearSearchHistory: () -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onOpenChat: (Long) -> Unit,
|
||||
onOpenSaved: () -> Unit,
|
||||
isMainBarVisible: Boolean,
|
||||
onMainBarVisibilityChanged: (Boolean) -> Unit,
|
||||
onCreateGroup: (String, List<Long>) -> Unit,
|
||||
@@ -414,15 +416,7 @@ fun ChatListScreen(
|
||||
leadingIcon = { Icon(Icons.Filled.Inventory2, contentDescription = null) },
|
||||
onClick = {
|
||||
showDefaultMenu = false
|
||||
val saved = state.chats.firstOrNull {
|
||||
val title = it.displayTitle.lowercase()
|
||||
title.contains("saved") || title.contains("избран")
|
||||
}
|
||||
if (saved != null) {
|
||||
onOpenChat(saved.id)
|
||||
} else {
|
||||
Toast.makeText(context, "Saved chat not found.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
onOpenSaved()
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
|
||||
@@ -150,6 +150,19 @@ class ChatListViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun openSavedChat() {
|
||||
viewModelScope.launch {
|
||||
when (val result = chatRepository.getSavedChat()) {
|
||||
is AppResult.Success -> {
|
||||
_uiState.update { it.copy(pendingOpenChatId = result.data.id) }
|
||||
}
|
||||
is AppResult.Error -> _uiState.update {
|
||||
it.copy(errorMessage = result.reason.toUiMessage())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onManagementChatSelected(chatId: Long?) {
|
||||
_uiState.update { it.copy(selectedManageChatId = chatId) }
|
||||
if (chatId != null) {
|
||||
|
||||
Reference in New Issue
Block a user