diff --git a/src/config_parser.c b/src/config_parser.c index 5038c4f6..06246007 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -828,9 +828,7 @@ static section_type_t parse_section_header(const char *line, char *name, size_t if (strcasecmp(section, "nat") == 0) return SECTION_NAT; if (strcasecmp(section, "tcp_proxy_client") == 0) return SECTION_TCP_PROXY_CLIENT; if (strcasecmp(section, "tcp_proxy_server") == 0) return SECTION_TCP_PROXY_SERVER; - if (strcasecmp(section, "chatserver") == 0) return SECTION_CHATSERVER; - if (strcasecmp(section, "ntp") == 0) return SECTION_NTP; - if (strcasecmp(section, "gui") == 0) return SECTION_GUI; + if (strcasecmp(section, "chat") == 0) return SECTION_CHATSERVER; if (strcasecmp(section, "chatserver") == 0) return SECTION_CHATSERVER; if (strcasecmp(section, "ntp") == 0) return SECTION_NTP; if (strcasecmp(section, "gui") == 0) return SECTION_GUI; diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt index a800a100..6e0f86d4 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt @@ -64,7 +64,7 @@ fun MessageBubble(message: Message, playbackState: ChatViewModel.PlaybackState = Spacer(Modifier.height(2.dp)) when { - isVoice -> VoiceBubble(message, textColor, isActive, playbackState, onPlayVoice, onSeekVoice) + isVoice -> VoiceBubble(message, textColor, isActive, playbackState, onPlayVoice, onSeekVoice, onDownloadFile) isMedia -> FileBubble(message, textColor, onDownloadFile, onOpenFile) else -> { Text(message.text, fontSize = 17.sp, color = textColor) @@ -87,7 +87,8 @@ fun MessageBubble(message: Message, playbackState: ChatViewModel.PlaybackState = private fun VoiceBubble(message: Message, textColor: Color, isActive: Boolean, ps: ChatViewModel.PlaybackState, onPlay: (String, Int) -> Unit, - onSeek: (String, Int, Int) -> Unit) { + onSeek: (String, Int, Int) -> Unit, + onDownload: (Message) -> Unit = {}) { val wf = message.waveform val wfCount = wf.size val durMs = message.voiceDurationMs @@ -95,15 +96,31 @@ private fun VoiceBubble(message: Message, textColor: Color, isActive: Boolean, val paused = isActive && ps.paused val elapsedMs = ps.elapsedMs val progress = ps.progress + val downloading = message.downloadState == "downloading" + val notDownloaded = message.filePath.isEmpty() && !downloading Column { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Box( modifier = Modifier.size(32.dp).background(Color.White, CircleShape) - .clickable { if (message.filePath.isNotEmpty()) onPlay(message.filePath, durMs) }, + .clickable { + when { + downloading -> {} + notDownloaded -> onDownload(message) + else -> onPlay(message.filePath, durMs) + } + }, contentAlignment = Alignment.Center ) { - Text(if (playing && !paused) "\u23F8" else "\u25B6", fontSize = 14.sp, color = Color.Black) + Text( + when { + downloading -> "\u23F3" + notDownloaded -> "\u2B07" + playing && !paused -> "\u23F8" + else -> "\u25B6" + }, + fontSize = 14.sp, color = Color.Black + ) } Spacer(Modifier.width(8.dp)) @@ -155,8 +172,12 @@ private fun VoiceBubble(message: Message, textColor: Color, isActive: Boolean, verticalAlignment = Alignment.Bottom ) { Text( - if (playing || paused) "${formatDurationMs(elapsedMs)} / ${formatDurationMs(durMs)}" - else formatDurationMs(durMs), + when { + downloading -> "Downloading..." + notDownloaded -> "Tap to download" + playing || paused -> "${formatDurationMs(elapsedMs)} / ${formatDurationMs(durMs)}" + else -> formatDurationMs(durMs) + }, fontSize = 12.sp, color = textColor.copy(alpha = 0.55f) )