This commit is contained in:
2025-12-05 17:57:50 +08:00
parent 949d4ca6f2
commit b9225e720b
3 changed files with 85 additions and 69 deletions

View File

@@ -121,6 +121,9 @@ fun CallLogScreen(
else -> null else -> null
} }
viewModel.loadCallRecords(range, request) viewModel.loadCallRecords(range, request)
},
onScanAudio = {
viewModel.scanAllAudio()
} }
) )
}, },
@@ -305,16 +308,22 @@ fun CallLogContent(
@Composable @Composable
fun CallLogTopBar( fun CallLogTopBar(
selectedTimeRange: String, selectedTimeRange: String,
onTimeRangeSelected: (String) -> Unit onTimeRangeSelected: (String) -> Unit,
onScanAudio: () -> Unit = {}
) { ) {
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
val timeRanges = listOf("全部", "今天", "本周", "本月") val timeRanges = listOf("全部", "今天", "本周", "本月")
CenterAlignedTopAppBar( TopAppBar(
title = { title = {
Text("通话记录", fontWeight = FontWeight.Bold) Text("通话记录", fontWeight = FontWeight.Bold)
}, },
actions = { actions = {
Box {
TextButton(onClick = onScanAudio) {
Text("扫描录音")
}
}
Box { Box {
TextButton(onClick = { expanded = true }) { TextButton(onClick = { expanded = true }) {
Text(selectedTimeRange) Text(selectedTimeRange)

View File

@@ -13,7 +13,8 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.time.LocalDateTime import java.time.LocalDateTime
class CallLogViewModel(private val callLogRepository: CallLogRepository = CallLogRepository() class CallLogViewModel(
private val callLogRepository: CallLogRepository = CallLogRepository()
) : ViewModel() { ) : ViewModel() {
private val _callRecords = MutableStateFlow<List<CallRecord>>(emptyList()) private val _callRecords = MutableStateFlow<List<CallRecord>>(emptyList())
@@ -28,75 +29,77 @@ import java.time.LocalDateTime
private val _selectedTimeRange = MutableStateFlow("全部") private val _selectedTimeRange = MutableStateFlow("全部")
val selectedTimeRange: StateFlow<String> = _selectedTimeRange.asStateFlow() val selectedTimeRange: StateFlow<String> = _selectedTimeRange.asStateFlow()
// 新增:音频播放相关状态 // 新增:音频播放相关状态
private val _currentlyPlayingAudio = MutableStateFlow<String?>(null) private val _currentlyPlayingAudio = MutableStateFlow<String?>(null)
val currentlyPlayingAudio: StateFlow<String?> = _currentlyPlayingAudio.asStateFlow() val currentlyPlayingAudio: StateFlow<String?> = _currentlyPlayingAudio.asStateFlow()
private val _playbackError = MutableStateFlow<String?>(null) private val _playbackError = MutableStateFlow<String?>(null)
val playbackError: StateFlow<String?> = _playbackError.asStateFlow() val playbackError: StateFlow<String?> = _playbackError.asStateFlow()
/**
* 播放音频
*/
fun playAudio(audioUrl: String) {
_playbackError.value = null
// 如果正在播放同一个音频,则停止播放 /**
if (AudioPlayManager.isPlaying(audioUrl)) { * 播放音频
stopAudio() */
return fun playAudio(audioUrl: String) {
} _playbackError.value = null
AudioPlayManager.playAudio( // 如果正在播放同一个音频,则停止播放
audioUrl = audioUrl, if (AudioPlayManager.isPlaying(audioUrl)) {
onStart = { stopAudio()
_currentlyPlayingAudio.value = audioUrl return
}, }
onCompletion = {
_currentlyPlayingAudio.value = null
},
onError = { error ->
_playbackError.value = error
_currentlyPlayingAudio.value = null
}
)
}
/** AudioPlayManager.playAudio(
* 停止音频播放 audioUrl = audioUrl,
*/ onStart = {
fun stopAudio() { _currentlyPlayingAudio.value = audioUrl
AudioPlayManager.stopAudio() },
_currentlyPlayingAudio.value = null onCompletion = {
_playbackError.value = null _currentlyPlayingAudio.value = null
} },
onError = { error ->
_playbackError.value = error
_currentlyPlayingAudio.value = null
}
)
}
/** /**
* 停音频播放 * 停音频播放
*/ */
fun pauseAudio() { fun stopAudio() {
AudioPlayManager.pauseAudio() AudioPlayManager.stopAudio()
_currentlyPlayingAudio.value = null _currentlyPlayingAudio.value = null
} _playbackError.value = null
}
/** /**
* 检查是否正在播放指定音频 * 暂停音频播放
*/ */
fun isAudioPlaying(audioUrl: String): Boolean { fun pauseAudio() {
return AudioPlayManager.isPlaying(audioUrl) AudioPlayManager.pauseAudio()
} _currentlyPlayingAudio.value = null
}
/** /**
* 清除播放错误 * 检查是否正在播放指定音频
*/ */
fun clearPlaybackError() { fun isAudioPlaying(audioUrl: String): Boolean {
_playbackError.value = null return AudioPlayManager.isPlaying(audioUrl)
} }
/**
* 清除播放错误
*/
fun clearPlaybackError() {
_playbackError.value = null
}
override fun onCleared() {
super.onCleared()
// 清理资源
AudioPlayManager.stopAudio()
}
override fun onCleared() {
super.onCleared()
// 清理资源
AudioPlayManager.stopAudio()
}
/** /**
* 加载通话记录 * 加载通话记录
* @param timeRange 时间范围描述用于UI显示 * @param timeRange 时间范围描述用于UI显示
@@ -137,4 +140,8 @@ import java.time.LocalDateTime
fun clearError() { fun clearError() {
_errorMessage.value = null _errorMessage.value = null
} }
fun scanAllAudio() {
}
} }

View File

@@ -101,10 +101,10 @@ fun HomeScreen(
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = when (webSocketStatus) { text = when (webSocketStatus) {
WebSocketService.WebSocketStatus.CONNECTED -> "WebSocket 已连接" WebSocketService.WebSocketStatus.CONNECTED -> "快捷拨号服务 已连接"
WebSocketService.WebSocketStatus.CONNECTING -> "WebSocket 连接中" WebSocketService.WebSocketStatus.CONNECTING -> "快捷拨号服务 连接中"
WebSocketService.WebSocketStatus.DISCONNECTED -> "WebSocket 未连接" WebSocketService.WebSocketStatus.DISCONNECTED -> "快捷拨号服务 未连接"
WebSocketService.WebSocketStatus.ERROR -> "WebSocket 连接错误" WebSocketService.WebSocketStatus.ERROR -> "快捷拨号服务 连接错误"
}, },
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
@@ -140,7 +140,7 @@ fun HomeScreen(
text = when (webSocketStatus) { text = when (webSocketStatus) {
WebSocketService.WebSocketStatus.CONNECTED -> "连接正常" WebSocketService.WebSocketStatus.CONNECTED -> "连接正常"
WebSocketService.WebSocketStatus.CONNECTING -> "连接中..." WebSocketService.WebSocketStatus.CONNECTING -> "连接中..."
else -> "重连 WebSocket" else -> "重连 快捷拨号服务"
}, },
fontSize = 14.sp fontSize = 14.sp
) )