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