refresh borders of sentences
This commit is contained in:
@@ -141,6 +141,28 @@ class OralTrainerController internal constructor(
|
||||
loadItems(listOf(item))
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces sentences without preparing/reloading media, preserving playback
|
||||
* position and state so a background boundary refresh can apply immediately.
|
||||
*/
|
||||
fun updateSentences(mediaId: String, sentences: List<SentenceBoundary>): Boolean {
|
||||
val index = mediaItems.indexOfFirst { it.id == mediaId }
|
||||
if (index < 0) {
|
||||
return false
|
||||
}
|
||||
val updatedItem = mediaItems[index].copy(sentences = sentences)
|
||||
if (mediaItems[index] == updatedItem) {
|
||||
return true
|
||||
}
|
||||
mediaItems[index] = updatedItem
|
||||
if (index == player.currentMediaItemIndex) {
|
||||
listeners.forEach { it.onMediaChanged(updatedItem) }
|
||||
notifySentenceIfChanged(force = true)
|
||||
notifySnapshot()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun play() {
|
||||
player.play()
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ class SentenceBoundaryApi internal constructor(
|
||||
connection.requestMethod = "GET"
|
||||
connection.connectTimeout = config.connectTimeoutMs
|
||||
connection.readTimeout = config.readTimeoutMs
|
||||
connection.useCaches = false
|
||||
connection.setRequestProperty("Accept", "application/json")
|
||||
connection.setRequestProperty("User-Agent", config.userAgent)
|
||||
val statusCode = connection.responseCode
|
||||
|
||||
@@ -107,6 +107,7 @@ class MainActivity : Activity() {
|
||||
|
||||
private var activeItemId: String = ""
|
||||
private var currentSentenceCount = 0
|
||||
private var sentenceBoundaryRequestGeneration = 0
|
||||
private var catalogVideos: List<TrainingVideoSummary> = emptyList()
|
||||
private var catalogStatusTextValue = "正在同步"
|
||||
private var activeModule = Module.TRAIN
|
||||
@@ -1419,6 +1420,9 @@ class MainActivity : Activity() {
|
||||
catalogStatusText.text = catalogStatusTextValue
|
||||
}
|
||||
renderCatalog()
|
||||
catalogVideos
|
||||
.firstOrNull { it.videoHash == activeItemId }
|
||||
?.let { refreshSentenceBoundaries(it, background = true) }
|
||||
}
|
||||
|
||||
override fun onError(error: Throwable) {
|
||||
@@ -1460,18 +1464,38 @@ class MainActivity : Activity() {
|
||||
val loadingItem = video.toTrainingMediaItem()
|
||||
controller.loadItem(loadingItem)
|
||||
currentSentenceCount = video.sentenceCount
|
||||
refreshSentenceBoundaries(video, background = false)
|
||||
}
|
||||
|
||||
private fun refreshSentenceBoundaries(
|
||||
video: TrainingVideoSummary,
|
||||
background: Boolean,
|
||||
) {
|
||||
val requestGeneration = ++sentenceBoundaryRequestGeneration
|
||||
if (!background && ::statusText.isInitialized) {
|
||||
statusText.text = "正在加载云端课程..."
|
||||
} else if (::statusText.isInitialized) {
|
||||
statusText.text = "正在刷新句子边界..."
|
||||
}
|
||||
sdk.sentenceBoundaryApi.fetch(video.videoHash, object : SentenceBoundaryApiCallback {
|
||||
override fun onSuccess(result: SentenceBoundaryApiResult) {
|
||||
if (activeItemId != video.videoHash) {
|
||||
if (
|
||||
sentenceBoundaryRequestGeneration != requestGeneration ||
|
||||
activeItemId != video.videoHash
|
||||
) {
|
||||
return
|
||||
}
|
||||
currentSentenceCount = result.sentences.size
|
||||
controller.loadItem(video.toTrainingMediaItem(result.sentences))
|
||||
controller.updateSentences(video.videoHash, result.sentences)
|
||||
refreshCurrentUi()
|
||||
statusText.text = "课程已就绪:${result.sentences.size} 句"
|
||||
}
|
||||
|
||||
override fun onError(error: Throwable) {
|
||||
if (activeItemId != video.videoHash) {
|
||||
if (
|
||||
sentenceBoundaryRequestGeneration != requestGeneration ||
|
||||
activeItemId != video.videoHash
|
||||
) {
|
||||
return
|
||||
}
|
||||
statusText.text = "句子边界加载失败:${error.message.orEmpty()}"
|
||||
|
||||
Reference in New Issue
Block a user