Гиф
This commit is contained in:
@@ -18,7 +18,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chats.presentation.components.EmojiPicker
|
||||
import chats.presentation.components.MediaPicker
|
||||
import chats.presentation.components.MessageBubble
|
||||
import core.presentation.components.AppAvatar
|
||||
import core.presentation.components.AppMediaLightbox
|
||||
@@ -246,7 +246,30 @@ fun ChatDetailScreen(
|
||||
}
|
||||
|
||||
if (isEmojiPickerVisible) {
|
||||
EmojiPicker(onEmojiSelected = { textInput += it })
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.loadTrendingGifs()
|
||||
}
|
||||
MediaPicker(
|
||||
trendingGifs = state.trendingGifs,
|
||||
searchedGifs = state.searchedGifs,
|
||||
recentGifs = state.recentGifs,
|
||||
gifCategories = state.gifCategories,
|
||||
isGifsLoading = state.isGifsLoading,
|
||||
error = state.error,
|
||||
onEmojiSelected = { textInput += it },
|
||||
onGifSelected = { url ->
|
||||
viewModel.sendGif(url)
|
||||
isEmojiPickerVisible = false
|
||||
},
|
||||
onGifSearch = { query ->
|
||||
viewModel.searchGifs(query)
|
||||
}
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.loadTrendingGifs()
|
||||
viewModel.loadGifCategories()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
import chats.data.remote.api.KlipyGifDto
|
||||
|
||||
data class ChatDetailState(
|
||||
val messages: List<Message> = emptyList(),
|
||||
val chatName: String? = null,
|
||||
@@ -26,7 +28,12 @@ data class ChatDetailState(
|
||||
val typingUser: String? = null,
|
||||
val error: String? = null,
|
||||
val canCall: Boolean = true,
|
||||
val maxFileSize: Long = 100 * 1024 * 1024
|
||||
val maxFileSize: Long = 100 * 1024 * 1024,
|
||||
val trendingGifs: List<KlipyGifDto> = emptyList(),
|
||||
val searchedGifs: List<KlipyGifDto> = emptyList(),
|
||||
val recentGifs: List<KlipyGifDto> = emptyList(),
|
||||
val gifCategories: List<chats.data.remote.api.GifCategoryDto> = emptyList(),
|
||||
val isGifsLoading: Boolean = false
|
||||
)
|
||||
|
||||
@HiltViewModel
|
||||
@@ -182,5 +189,78 @@ class ChatDetailViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadTrendingGifs() {
|
||||
if (_state.value.trendingGifs.isNotEmpty()) return
|
||||
|
||||
viewModelScope.launch {
|
||||
_state.update { it.copy(isGifsLoading = true) }
|
||||
try {
|
||||
val gifs = repository.getTrendingGifs(0)
|
||||
_state.update { it.copy(trendingGifs = gifs, isGifsLoading = false) }
|
||||
} catch (e: Exception) {
|
||||
_state.update { it.copy(isGifsLoading = false, error = "GIF load error: ${e.message}") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadGifCategories() {
|
||||
if (_state.value.gifCategories.isNotEmpty()) return
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val categories = repository.getGifCategories()
|
||||
_state.update { it.copy(gifCategories = categories) }
|
||||
} catch (e: Exception) {
|
||||
// Ignore failure
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var searchJob: Job? = null
|
||||
fun searchGifs(query: String) {
|
||||
searchJob?.cancel()
|
||||
if (query.isBlank()) {
|
||||
_state.update { it.copy(searchedGifs = emptyList()) }
|
||||
return
|
||||
}
|
||||
searchJob = viewModelScope.launch {
|
||||
delay(500)
|
||||
_state.update { it.copy(isGifsLoading = true) }
|
||||
try {
|
||||
val gifs = repository.searchGifs(query, 0)
|
||||
_state.update { it.copy(searchedGifs = gifs, isGifsLoading = false) }
|
||||
} catch (e: Exception) {
|
||||
_state.update { it.copy(isGifsLoading = false) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sendGif(url: String) {
|
||||
val chatId = currentChatId ?: return
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
repository.sendMessage(chatId, url)
|
||||
|
||||
// Add to recent
|
||||
val allGifs = _state.value.trendingGifs + _state.value.searchedGifs + _state.value.recentGifs
|
||||
val selectedGif = allGifs.find { gif ->
|
||||
val gifUrl = gif.files?.get("hd")?.get("gif")?.url
|
||||
?: gif.files?.get("sd")?.get("gif")?.url
|
||||
?: gif.file?.get("hd")?.get("gif")?.url
|
||||
?: gif.file?.get("sd")?.get("gif")?.url
|
||||
?: gif.media_formats?.get("gif")?.url
|
||||
?: gif.images?.original?.url
|
||||
gifUrl == url
|
||||
}
|
||||
|
||||
selectedGif?.let { gif ->
|
||||
val newList = (listOf(gif) + _state.value.recentGifs).distinctBy { it.id }.take(20)
|
||||
_state.update { it.copy(recentGifs = newList) }
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
_state.update { it.copy(error = e.localizedMessage) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user