From feebefcdd7b40af665bded0b6a6c5edd80aec3b5 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Wed, 17 Jun 2026 18:27:55 +0000 Subject: [PATCH] Fix close icon hidden by long file name in compose file preview (#7077) A long file name took all the row width and squeezed the cancel (X) icon to zero, so the file could not be dismissed before sending. Give the file-name text the layout weight and a single line (Compose), and lineLimit(1) on iOS, so it truncates and the close icon keeps its space. Affects Android, Desktop and iOS. --- .../Chat/ComposeMessage/ComposeFileView.swift | 1 + .../common/views/chat/ComposeFileView.kt | 3 +- plans/2026-06-15-fix-file-upload-long-name.md | 77 +++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 plans/2026-06-15-fix-file-upload-long-name.md diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift index 1ec46816f5..4b9169c72a 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift @@ -23,6 +23,7 @@ struct ComposeFileView: View { .foregroundColor(Color(uiColor: .tertiaryLabel)) .padding(.leading, 4) Text(fileName) + .lineLimit(1) Spacer() if cancelEnabled { Button { cancelFile() } label: { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt index 7ab7963547..26e069c739 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeFileView.kt @@ -33,8 +33,7 @@ fun ComposeFileView(fileName: String, cancelFile: () -> Unit, cancelEnabled: Boo .size(36.dp), tint = if (isInDarkTheme()) FileDark else FileLight ) - Text(fileName) - Spacer(Modifier.weight(1f)) + Text(fileName, maxLines = 1, modifier = Modifier.weight(1f)) if (cancelEnabled) { IconButton(onClick = cancelFile, modifier = Modifier.padding(0.dp)) { Icon( diff --git a/plans/2026-06-15-fix-file-upload-long-name.md b/plans/2026-06-15-fix-file-upload-long-name.md new file mode 100644 index 0000000000..f0917783bd --- /dev/null +++ b/plans/2026-06-15-fix-file-upload-long-name.md @@ -0,0 +1,77 @@ +# Fix: long file name hides the close icon in the compose file preview + +Date: 2026-06-15 +Branch: `nd/fix-file-upload-with-long-name` +Platforms affected: Android, Desktop, iOS + +## Problem + +When a file is attached for sending, the compose area shows a preview row with the +file icon, the file name, and a close (X) icon to cancel/remove the file before +sending. If the file name is long, the close icon is not shown, so the user cannot +dismiss the attachment. + +## Cause + +The bug is the same layout defect on both codebases: the file-name text is +unconstrained, so a long name consumes all horizontal space and squeezes the +trailing close button to zero width. + +### Android / Desktop — `ComposeFileView.kt` + +The row was laid out as: + +``` +Icon(fixed) | Text(fileName) | Spacer(weight 1f) | IconButton(close) + ^ unweighted, no maxLines +``` + +In a Compose `Row`, unweighted children are measured first and take the remaining +width before weighted children get anything. The unweighted `Text` therefore grabbed +the whole remaining width on a long name, leaving the weighted `Spacer` — and the +`IconButton` after it — with ~0 width. The flexible element was the `Spacer`, but a +`Spacer` can only distribute the space the rigid `Text` did not already eat. + +### iOS — `ComposeFileView.swift` + +``` +Image(fixed) | Text(fileName) | Spacer() | Button(close) + ^ no lineLimit +``` + +A `Text` with no `lineLimit` reports its full single-line ideal width and refuses to +truncate, so a long name collapses the `Spacer` and pushes the `Button` past the +`.frame(maxWidth: .infinity)` edge, off-screen. + +## Fix + +Make the file name the element that yields space and let it truncate, so the +fixed-size close control's space is always reserved. + +- **Kotlin:** give the `Text` the `weight(1f)` (instead of the `Spacer`) and + `maxLines = 1`, and drop the now-redundant `Spacer`. This matches the existing + idiom — `ComposeImageView` puts `weight(1f)` on its content, and `CIFileView` + caps file-name text with `maxLines = 1`. +- **Swift:** add `.lineLimit(1)` to the `Text`, so it truncates instead of + overflowing, matching how file names are shown elsewhere on iOS. + +## Why this is the right fix (not a workaround) + +`ComposeFileView` was the only compose preview that gave the weight to a `Spacer` +rather than to its content; every sibling preview (`ComposeImageView`, +`ContextItemView`) reserves space for the trailing close control by weighting the +content. The change brings the file preview in line with the established pattern +rather than adding a special case. It is purely structural — no behavior changes +beyond layout. + +## Scope / risk + +- One-spot edit per file; no API or behavior change. +- Android and Desktop share the Kotlin file, so both are fixed together; iOS is the + separate Swift file. +- No string/translation keys touched. + +## Verification + +- Visual: attach a file with a very long name on Android, Desktop, and iOS; confirm + the name truncates and the close (X) icon stays visible and tappable.