Skip to content

Commit 0052ff7

Browse files
committed
[atomic_x]Update atomic_x 4.0.1
1 parent 60f3774 commit 0052ff7

64 files changed

Lines changed: 3372 additions & 2221 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

atomic-x/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 4.0.1
2+
* Added floating button features to the chat page: "Jump to Latest Position," "X Unread Messages," and "Someone @-ed Me".
3+
* Text message links now support opening in a browser.
4+
* Fixed issues with photo album selection.
5+
* Fixed failure to send messages after using camera or taking photos.
6+
* Improved alert experience for denied permission requests.
7+
* Enhanced voice recording experience.
8+
* Optimized keyboard interaction.
9+
* Restricted camera and video recording to portrait mode.
10+
* Fixed other known issues.
11+
112
## 4.0.0
213
* Adapted for atomic_x_core 4.0.0.
314

atomic-x/android/src/main/kotlin/io/trtc/tuikit/atomicx/albumpicker/AlbumPicker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ data class AlbumPickerModel(
2828
@Parcelize
2929
data class AlbumPickerConfig(
3030
var pickMode: PickMode = PickMode.ALL,
31-
var maxCount: Int = 99,
31+
var maxCount: Int = 9,
3232
var gridCount: Int = 4,
3333
var primaryColor: Int = -1
3434
) : Parcelable

atomic-x/android/src/main/kotlin/io/trtc/tuikit/atomicx/albumpicker/AlbumPickerHandler.kt

Lines changed: 69 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package io.trtc.tuikit.atomicx.albumpicker
22

33
import android.app.Application
44
import android.net.Uri
5+
import android.os.Handler
6+
import android.os.Looper
57
import android.text.TextUtils
68
import android.util.Log
79
import android.webkit.MimeTypeMap
@@ -13,6 +15,7 @@ import io.trtc.tuikit.atomicx.basecomponent.theme.ThemeState
1315
import io.trtc.tuikit.atomicx.basecomponent.utils.ContextProvider
1416
import io.trtc.tuikit.atomicx.messageinput.utils.FileUtils
1517
import io.trtc.tuikit.atomicx.utils.LocaleUtils
18+
import java.util.concurrent.Executors
1619

1720
/**
1821
* AlbumPickerHandler
@@ -28,6 +31,8 @@ class AlbumPickerHandler(
2831

2932
private var pendingResult: MethodChannel.Result? = null
3033
private var lifecycleCallbacks: Application.ActivityLifecycleCallbacks? = null
34+
private val executor = Executors.newSingleThreadExecutor()
35+
private val mainHandler = Handler(Looper.getMainLooper())
3136

3237
fun handlePickMedia(call: MethodCall, result: MethodChannel.Result) {
3338
Log.d(TAG, "handlePickMedia called")
@@ -50,8 +55,8 @@ class AlbumPickerHandler(
5055
val scriptCode = call.argument<String>("scriptCode")
5156

5257
Log.d(
53-
TAG,
54-
"Config - pickMode: $pickModeInt, maxCount: $maxCount, gridCount: $gridCount, primaryColor: $primaryColor, language: $languageCode"
58+
TAG, "Config - pickMode: $pickModeInt, maxCount: $maxCount, gridCount: $gridCount, "
59+
+ "primaryColor: $primaryColor, language: $languageCode"
5560
)
5661

5762
val pickMode = when (pickModeInt) {
@@ -67,7 +72,6 @@ class AlbumPickerHandler(
6772
gridCount = gridCount,
6873
)
6974

70-
// 设置主题色
7175
if (!primaryColor.isNullOrEmpty()) {
7276
ThemeState.shared.setPrimaryColor(primaryColor)
7377
}
@@ -81,7 +85,6 @@ class AlbumPickerHandler(
8185
Log.d(TAG, "onFinishedSelect: $count items")
8286

8387
if (count == 0) {
84-
// 用户取消
8588
pendingResult?.success(null)
8689
pendingResult = null
8790
cleanupLanguageCallback()
@@ -90,72 +93,70 @@ class AlbumPickerHandler(
9093

9194
override fun onProgress(model: AlbumPickerModel, index: Int, progress: Double) {
9295
Log.d(TAG, "onProgress: index=$index, progress=$progress")
93-
94-
try {
95-
val mediaPathUri = model.mediaPath ?: ""
96-
if (mediaPathUri.isEmpty()) {
97-
Log.e(TAG, "model.mediaPath is empty")
98-
return
99-
}
100-
101-
val context = ContextProvider.appContext
102-
val uri = Uri.parse(mediaPathUri)
103-
val mediaPath = FileUtils.getPathFromUri(context, uri)
104-
105-
if (mediaPath.isEmpty()) {
106-
Log.e(TAG, "Failed to convert URI to path: $mediaPathUri")
107-
return
108-
}
109-
110-
Log.d(TAG, "Converted URI to path: $mediaPathUri -> $mediaPath")
111-
112-
val fileExtension = FileUtils.getFileExtensionFromUrl(mediaPath)
113-
val fileSize = FileUtils.getFileSize(mediaPath)
11496

115-
val mediaTypeValue = when (model.mediaType) {
116-
PickMediaType.IMAGE -> 0
117-
PickMediaType.VIDEO -> 1
118-
PickMediaType.GIF -> 2
97+
executor.execute {
98+
try {
99+
val mediaPathUri = model.mediaPath ?: ""
100+
if (mediaPathUri.isEmpty()) {
101+
Log.e(TAG, "model.mediaPath is empty")
102+
return@execute
103+
}
104+
105+
val context = ContextProvider.appContext
106+
val uri = Uri.parse(mediaPathUri)
107+
val mediaPath = FileUtils.getPathFromUri(context, uri)
108+
109+
if (mediaPath.isEmpty()) {
110+
Log.e(TAG, "Failed to convert URI to path: $mediaPathUri")
111+
return@execute
112+
}
113+
114+
Log.d(TAG, "Converted URI to path: $mediaPathUri -> $mediaPath")
115+
116+
val fileExtension = FileUtils.getFileExtensionFromUrl(mediaPath)
117+
val fileSize = FileUtils.getFileSize(mediaPath)
118+
119+
val mediaTypeValue = when (model.mediaType) {
120+
PickMediaType.IMAGE -> 0
121+
PickMediaType.VIDEO -> 1
122+
PickMediaType.GIF -> 2
123+
}
124+
125+
Log.d(TAG, "Processed file: path=$mediaPath, size=$fileSize, type=$mediaTypeValue")
126+
127+
val dataMap = mutableMapOf(
128+
"id" to model.id.toLong(),
129+
"mediaType" to mediaTypeValue,
130+
"mediaPath" to mediaPath,
131+
"fileExtension" to fileExtension,
132+
"fileSize" to fileSize,
133+
"isOrigin" to model.isOrigin
134+
)
135+
136+
if (mediaTypeValue == 1 && model.videoThumbnailPath != null) {
137+
dataMap["videoThumbnailPath"] = model.videoThumbnailPath
138+
}
139+
140+
val progressEvent = mapOf(
141+
"type" to "progress",
142+
"index" to index,
143+
"progress" to progress,
144+
"data" to dataMap
145+
)
146+
147+
mainHandler.post {
148+
eventSink(progressEvent)
149+
150+
if (progress >= 1.0) {
151+
pendingResult?.success(null)
152+
pendingResult = null
153+
cleanupLanguageCallback()
154+
}
155+
}
156+
157+
} catch (e: Exception) {
158+
Log.e(TAG, "Error processing model: $model", e)
119159
}
120-
121-
Log.d(
122-
TAG,
123-
"Processed file: path=$mediaPath, size=$fileSize, type=$mediaTypeValue"
124-
)
125-
126-
// 构建数据字典
127-
val dataMap = mutableMapOf(
128-
"id" to model.id.toLong(),
129-
"mediaType" to mediaTypeValue,
130-
"mediaPath" to mediaPath,
131-
"fileExtension" to fileExtension,
132-
"fileSize" to fileSize,
133-
"isOrigin" to model.isOrigin
134-
)
135-
136-
// 如果是视频且有缩略图,直接添加缩略图路径
137-
if (mediaTypeValue == 1 && model.videoThumbnailPath != null) {
138-
dataMap["videoThumbnailPath"] = model.videoThumbnailPath
139-
}
140-
141-
// 发送进度事件
142-
val progressEvent = mapOf(
143-
"type" to "progress",
144-
"index" to index,
145-
"progress" to progress,
146-
"data" to dataMap
147-
)
148-
eventSink(progressEvent)
149-
150-
// 当所有资源处理完成时,结束
151-
if (progress >= 1.0) {
152-
pendingResult?.success(null)
153-
pendingResult = null
154-
cleanupLanguageCallback()
155-
}
156-
157-
} catch (e: Exception) {
158-
Log.e(TAG, "Error processing model: $model", e)
159160
}
160161
}
161162
})

atomic-x/android/src/main/kotlin/io/trtc/tuikit/atomicx/albumpicker/impl/AlbumPickerImpl.kt

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package io.trtc.tuikit.atomicx.albumpicker.impl
22

33
import android.content.Intent
44
import android.net.Uri
5+
import android.os.Handler
6+
import android.os.Looper
57
import android.text.TextUtils
68
import android.webkit.MimeTypeMap
79
import com.tencent.qcloud.tuicore.TUICore
@@ -16,6 +18,7 @@ import io.trtc.tuikit.atomicx.albumpicker.util.AlbumPickerUtil
1618
import io.trtc.tuikit.atomicx.basecomponent.utils.ContextProvider
1719
import io.trtc.tuikit.atomicx.messageinput.utils.FileUtils
1820
import java.util.UUID
21+
import java.util.concurrent.Executors
1922

2023
class AlbumPickerImpl : AbstractAlbumPicker {
2124
companion object {
@@ -39,22 +42,27 @@ class AlbumPickerImpl : AbstractAlbumPicker {
3942
return@ITUINotification
4043
}
4144
listener.onFinishedSelect(dataList.size)
42-
val context = ContextProvider.appContext
43-
dataList.forEachIndexed { index, any ->
44-
val uri = any as? Uri ?: return@forEachIndexed
45-
val path = uri.toString()
46-
var mediaType = getPickMediaType(uri)
47-
val thumbPath = if (mediaType == PickMediaType.VIDEO) {
48-
AlbumPickerUtil.ensureVideoThumbnailPath(context, uri)
49-
} else null
50-
val model = AlbumPickerModel(
51-
id = AlbumPickerUtil.generateId(path),
52-
mediaPath = path,
53-
mediaType = mediaType,
54-
videoThumbnailPath = thumbPath,
55-
isOrigin = true
56-
)
57-
listener.onProgress(model, index, 1.0)
45+
val mainHandler = Handler(Looper.getMainLooper())
46+
Executors.newSingleThreadExecutor().execute {
47+
val context = ContextProvider.appContext
48+
dataList.forEachIndexed { index, any ->
49+
val uri = any as? Uri ?: return@forEachIndexed
50+
val path = uri.toString()
51+
var mediaType = getPickMediaType(uri)
52+
val thumbPath = if (mediaType == PickMediaType.VIDEO) {
53+
AlbumPickerUtil.ensureVideoThumbnailPath(context, uri)
54+
} else null
55+
val model = AlbumPickerModel(
56+
id = AlbumPickerUtil.generateId(path),
57+
mediaPath = path,
58+
mediaType = mediaType,
59+
videoThumbnailPath = thumbPath,
60+
isOrigin = true
61+
)
62+
mainHandler.post {
63+
listener.onProgress(model, index, 1.0)
64+
}
65+
}
5866
}
5967
}
6068
TUICore.registerEvent(eventKey, eventSubKey, notificationListener)

atomic-x/android/src/main/kotlin/io/trtc/tuikit/atomicx/albumpicker/viewmodels/AlbumPickerViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ class AlbumPickerViewModel(private val albumPickerConfig: AlbumPickerConfig) : V
244244
if (selectedMediaList.contains(baseBean)) {
245245
selectedMediaList.remove(baseBean)
246246
} else {
247+
if (selectedMediaList.size >= albumPickerConfig.maxCount) {
248+
return
249+
}
247250
selectedMediaList.add(baseBean)
248251
}
249252
_selectedMediaListFlow.value = selectedMediaList

atomic-x/android/src/main/kotlin/io/trtc/tuikit/atomicx/audiorecorder/AudioRecorder.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package io.trtc.tuikit.atomicx.audiorecorder
22

3-
import androidx.compose.runtime.Composable
4-
import androidx.compose.ui.Modifier
53
import io.trtc.tuikit.atomicx.audiorecorder.audiorecorderimpl.AudioRecorderImpl
6-
import kotlinx.coroutines.flow.StateFlow
74

85
enum class ResultCode(val code: Int) {
96
SUCCESS_EXCEED_MAX_DURATION(1),
@@ -23,8 +20,13 @@ interface AudioRecorderListener {
2320
object AudioRecorder {
2421
private val instance = AudioRecorderImpl()
2522

26-
val currentPower: StateFlow<Int> = instance.currentPowerFlow
27-
val currentTimeMs: StateFlow<Int> = instance.recordTimeMsFlow
23+
var onRecordTime: ((timeMs: Int) -> Unit)?
24+
get() = instance.onRecordTime
25+
set(value) { instance.onRecordTime = value }
26+
27+
var onPowerLevel: ((powerLevel: Int) -> Unit)?
28+
get() = instance.onPowerLevel
29+
set(value) { instance.onPowerLevel = value }
2830

2931
// To use AI noise reduction, the app must depend on LiteAVSDK_Professional v12.7+ and have the feature enabled.
3032
// Dependency: Add to app module's build.gradle dependencies: implementation("com.tencent.liteav:LiteAVSDK_Professional:12.7.0.xxxxx")

0 commit comments

Comments
 (0)