Reduce ChatScreen parameter footprint to avoid verifier crash
Some checks failed
Android CI / android (push) Failing after 6m25s
Android Release / release (push) Failing after 6m3s
CI / test (push) Failing after 3m25s

This commit is contained in:
2026-03-11 23:10:56 +03:00
parent 9af7597f8b
commit 28cb80fbb8

View File

@@ -311,100 +311,102 @@ fun ChatRoute(
ChatScreen(
state = state,
onBack = onBack,
onInputChanged = viewModel::onInputChanged,
onSendClick = viewModel::onSendClick,
onSelectMessage = viewModel::onSelectMessage,
onEnterMultiSelect = viewModel::onEnterMultiSelect,
onToggleMessageMultiSelection = viewModel::onToggleMessageMultiSelection,
onClearSelection = viewModel::onClearSelection,
onReplySelected = viewModel::onReplySelected,
onEditSelected = viewModel::onEditSelected,
onDeleteSelected = viewModel::onDeleteSelected,
onForwardSelected = viewModel::onForwardSelected,
onForwardDismiss = viewModel::onForwardDismiss,
onForwardTargetSelected = viewModel::onForwardTargetSelected,
onToggleReaction = viewModel::onToggleReaction,
onCancelComposeAction = viewModel::onCancelComposeAction,
onLoadMore = viewModel::loadMore,
onPickMedia = { pickMediaLauncher.launch("*/*") },
onCapturePhoto = { takePhotoLauncher.launch(null) },
onCaptureVideo = {
val file = createTempCaptureFile(context = context, prefix = "camera_video_", suffix = ".mp4")
val uri = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
file,
)
pendingCaptureVideoFile = file
pendingCaptureVideoUri = uri
captureVideoLauncher.launch(uri)
},
onCaptureCircleVideo = {
if (hasCameraPermission) {
showCircleRecorder = true
} else {
openCircleAfterPermissionGrant = true
circlePermissionLauncher.launch(
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
),
actions = ChatScreenActions(
onBack = onBack,
onInputChanged = viewModel::onInputChanged,
onSendClick = viewModel::onSendClick,
onSelectMessage = viewModel::onSelectMessage,
onEnterMultiSelect = viewModel::onEnterMultiSelect,
onToggleMessageMultiSelection = viewModel::onToggleMessageMultiSelection,
onClearSelection = viewModel::onClearSelection,
onReplySelected = viewModel::onReplySelected,
onEditSelected = viewModel::onEditSelected,
onDeleteSelected = viewModel::onDeleteSelected,
onForwardSelected = viewModel::onForwardSelected,
onForwardDismiss = viewModel::onForwardDismiss,
onForwardTargetSelected = viewModel::onForwardTargetSelected,
onToggleReaction = viewModel::onToggleReaction,
onCancelComposeAction = viewModel::onCancelComposeAction,
onLoadMore = viewModel::loadMore,
onPickMedia = { pickMediaLauncher.launch("*/*") },
onCapturePhoto = { takePhotoLauncher.launch(null) },
onCaptureVideo = {
val file = createTempCaptureFile(context = context, prefix = "camera_video_", suffix = ".mp4")
val uri = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
file,
)
}
},
onSendRemoteMedia = { fileName, mimeType, bytes ->
viewModel.onMediaPicked(
fileName = fileName,
mimeType = mimeType,
bytes = bytes,
)
},
onSendPresetMediaUrl = viewModel::onSendPresetMediaUrl,
onVoiceRecordStart = {
if (!hasAudioPermission) {
startRecordingAfterPermissionGrant = true
audioPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
} else {
startVoiceRecording()
}
},
onVoiceRecordTick = {
viewModel.onVoiceRecordTick(voiceRecorder.elapsedMillis())
},
onVoiceRecordLock = viewModel::onVoiceRecordLocked,
onVoiceRecordCancel = {
voiceRecorder.cancel()
AppAudioFocusCoordinator.release("voice-recording")
viewModel.onVoiceRecordCancelled()
},
onVoiceRecordSend = {
val duration = voiceRecorder.elapsedMillis()
val bytes = voiceRecorder.stopAndReadBytes()
AppAudioFocusCoordinator.release("voice-recording")
if (bytes != null && bytes.isNotEmpty()) {
viewModel.onVoiceRecordFinish(
fileName = "voice_${System.currentTimeMillis()}.m4a",
mimeType = "audio/mp4",
pendingCaptureVideoFile = file
pendingCaptureVideoUri = uri
captureVideoLauncher.launch(uri)
},
onCaptureCircleVideo = {
if (hasCameraPermission) {
showCircleRecorder = true
} else {
openCircleAfterPermissionGrant = true
circlePermissionLauncher.launch(
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
),
)
}
},
onSendRemoteMedia = { fileName, mimeType, bytes ->
viewModel.onMediaPicked(
fileName = fileName,
mimeType = mimeType,
bytes = bytes,
durationMs = duration,
)
} else {
},
onSendPresetMediaUrl = viewModel::onSendPresetMediaUrl,
onVoiceRecordStart = {
if (!hasAudioPermission) {
startRecordingAfterPermissionGrant = true
audioPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
} else {
startVoiceRecording()
}
},
onVoiceRecordTick = {
viewModel.onVoiceRecordTick(voiceRecorder.elapsedMillis())
},
onVoiceRecordLock = viewModel::onVoiceRecordLocked,
onVoiceRecordCancel = {
voiceRecorder.cancel()
AppAudioFocusCoordinator.release("voice-recording")
viewModel.onVoiceRecordCancelled()
}
},
onInlineSearchChanged = viewModel::onInlineSearchChanged,
onJumpInlineSearch = viewModel::jumpInlineSearch,
onVisibleIncomingMessageId = viewModel::onVisibleIncomingMessageId,
onToggleChatNotifications = viewModel::onToggleChatNotifications,
onClearHistory = viewModel::onClearHistory,
onDeleteChat = viewModel::onDeleteOrLeaveChat,
onPromoteMember = viewModel::promoteMember,
onDemoteMember = viewModel::demoteMember,
onBanMember = viewModel::banMember,
onKickMember = viewModel::kickMember,
onTransferOwnership = viewModel::transferOwnership,
onUnbanMember = viewModel::unbanMember,
},
onVoiceRecordSend = {
val duration = voiceRecorder.elapsedMillis()
val bytes = voiceRecorder.stopAndReadBytes()
AppAudioFocusCoordinator.release("voice-recording")
if (bytes != null && bytes.isNotEmpty()) {
viewModel.onVoiceRecordFinish(
fileName = "voice_${System.currentTimeMillis()}.m4a",
mimeType = "audio/mp4",
bytes = bytes,
durationMs = duration,
)
} else {
viewModel.onVoiceRecordCancelled()
}
},
onInlineSearchChanged = viewModel::onInlineSearchChanged,
onJumpInlineSearch = viewModel::jumpInlineSearch,
onVisibleIncomingMessageId = viewModel::onVisibleIncomingMessageId,
onToggleChatNotifications = viewModel::onToggleChatNotifications,
onClearHistory = viewModel::onClearHistory,
onDeleteChat = viewModel::onDeleteOrLeaveChat,
onPromoteMember = viewModel::promoteMember,
onDemoteMember = viewModel::demoteMember,
onBanMember = viewModel::banMember,
onKickMember = viewModel::kickMember,
onTransferOwnership = viewModel::transferOwnership,
onUnbanMember = viewModel::unbanMember,
),
)
if (showCircleRecorder) {
CircleVideoRecorderDialog(
@@ -422,50 +424,93 @@ fun ChatRoute(
}
}
private data class ChatScreenActions(
val onBack: () -> Unit,
val onInputChanged: (String) -> Unit,
val onSendClick: () -> Unit,
val onSelectMessage: (MessageItem?) -> Unit,
val onEnterMultiSelect: (MessageItem) -> Unit,
val onToggleMessageMultiSelection: (MessageItem) -> Unit,
val onClearSelection: () -> Unit,
val onReplySelected: (MessageItem) -> Unit,
val onEditSelected: (MessageItem) -> Unit,
val onDeleteSelected: (Boolean) -> Unit,
val onForwardSelected: () -> Unit,
val onForwardDismiss: () -> Unit,
val onForwardTargetSelected: (Long) -> Unit,
val onToggleReaction: (String) -> Unit,
val onCancelComposeAction: () -> Unit,
val onLoadMore: () -> Unit,
val onPickMedia: () -> Unit,
val onCapturePhoto: () -> Unit,
val onCaptureVideo: () -> Unit,
val onCaptureCircleVideo: () -> Unit,
val onSendRemoteMedia: (String, String, ByteArray) -> Unit,
val onSendPresetMediaUrl: (String) -> Unit,
val onVoiceRecordStart: () -> Unit,
val onVoiceRecordTick: () -> Unit,
val onVoiceRecordLock: () -> Unit,
val onVoiceRecordCancel: () -> Unit,
val onVoiceRecordSend: () -> Unit,
val onInlineSearchChanged: (String) -> Unit,
val onJumpInlineSearch: (Boolean) -> Unit,
val onVisibleIncomingMessageId: (Long?) -> Unit,
val onToggleChatNotifications: () -> Unit,
val onClearHistory: () -> Unit,
val onDeleteChat: () -> Unit,
val onPromoteMember: (Long) -> Unit,
val onDemoteMember: (Long) -> Unit,
val onBanMember: (Long) -> Unit,
val onKickMember: (Long) -> Unit,
val onTransferOwnership: (Long) -> Unit,
val onUnbanMember: (Long) -> Unit,
)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChatScreen(
private fun ChatScreen(
state: MessageUiState,
onBack: () -> Unit,
onInputChanged: (String) -> Unit,
onSendClick: () -> Unit,
onSelectMessage: (MessageItem?) -> Unit,
onEnterMultiSelect: (MessageItem) -> Unit,
onToggleMessageMultiSelection: (MessageItem) -> Unit,
onClearSelection: () -> Unit,
onReplySelected: (MessageItem) -> Unit,
onEditSelected: (MessageItem) -> Unit,
onDeleteSelected: (Boolean) -> Unit,
onForwardSelected: () -> Unit,
onForwardDismiss: () -> Unit,
onForwardTargetSelected: (Long) -> Unit,
onToggleReaction: (String) -> Unit,
onCancelComposeAction: () -> Unit,
onLoadMore: () -> Unit,
onPickMedia: () -> Unit,
onCapturePhoto: () -> Unit,
onCaptureVideo: () -> Unit,
onCaptureCircleVideo: () -> Unit,
onSendRemoteMedia: (String, String, ByteArray) -> Unit,
onSendPresetMediaUrl: (String) -> Unit,
onVoiceRecordStart: () -> Unit,
onVoiceRecordTick: () -> Unit,
onVoiceRecordLock: () -> Unit,
onVoiceRecordCancel: () -> Unit,
onVoiceRecordSend: () -> Unit,
onInlineSearchChanged: (String) -> Unit,
onJumpInlineSearch: (Boolean) -> Unit,
onVisibleIncomingMessageId: (Long?) -> Unit,
onToggleChatNotifications: () -> Unit,
onClearHistory: () -> Unit,
onDeleteChat: () -> Unit,
onPromoteMember: (Long) -> Unit,
onDemoteMember: (Long) -> Unit,
onBanMember: (Long) -> Unit,
onKickMember: (Long) -> Unit,
onTransferOwnership: (Long) -> Unit,
onUnbanMember: (Long) -> Unit,
actions: ChatScreenActions,
) {
val onBack = actions.onBack
val onInputChanged = actions.onInputChanged
val onSendClick = actions.onSendClick
val onSelectMessage = actions.onSelectMessage
val onEnterMultiSelect = actions.onEnterMultiSelect
val onToggleMessageMultiSelection = actions.onToggleMessageMultiSelection
val onClearSelection = actions.onClearSelection
val onReplySelected = actions.onReplySelected
val onEditSelected = actions.onEditSelected
val onDeleteSelected = actions.onDeleteSelected
val onForwardSelected = actions.onForwardSelected
val onForwardDismiss = actions.onForwardDismiss
val onForwardTargetSelected = actions.onForwardTargetSelected
val onToggleReaction = actions.onToggleReaction
val onCancelComposeAction = actions.onCancelComposeAction
val onLoadMore = actions.onLoadMore
val onPickMedia = actions.onPickMedia
val onCapturePhoto = actions.onCapturePhoto
val onCaptureVideo = actions.onCaptureVideo
val onCaptureCircleVideo = actions.onCaptureCircleVideo
val onSendRemoteMedia = actions.onSendRemoteMedia
val onSendPresetMediaUrl = actions.onSendPresetMediaUrl
val onVoiceRecordStart = actions.onVoiceRecordStart
val onVoiceRecordTick = actions.onVoiceRecordTick
val onVoiceRecordLock = actions.onVoiceRecordLock
val onVoiceRecordCancel = actions.onVoiceRecordCancel
val onVoiceRecordSend = actions.onVoiceRecordSend
val onInlineSearchChanged = actions.onInlineSearchChanged
val onJumpInlineSearch = actions.onJumpInlineSearch
val onVisibleIncomingMessageId = actions.onVisibleIncomingMessageId
val onToggleChatNotifications = actions.onToggleChatNotifications
val onClearHistory = actions.onClearHistory
val onDeleteChat = actions.onDeleteChat
val onPromoteMember = actions.onPromoteMember
val onDemoteMember = actions.onDemoteMember
val onBanMember = actions.onBanMember
val onKickMember = actions.onKickMember
val onTransferOwnership = actions.onTransferOwnership
val onUnbanMember = actions.onUnbanMember
val context = LocalContext.current
val view = LocalView.current
val listState = rememberLazyListState()