Skip to content

fix: remove visual gap between truncated filename and extension - #4406

Open
feather2222 wants to merge 1 commit into
nextcloud:masterfrom
feather2222:fix/filename-truncation-gap
Open

feather2222 wants to merge 1 commit into
nextcloud:masterfrom
feather2222:fix/filename-truncation-gap

Conversation

@feather2222

Copy link
Copy Markdown

Summary

In the list layout, the basename label is middle-truncated by UIKit but keeps the full remaining width. The extension label is then positioned after the label frame rather than after the last rendered glyph, and the unused width looks like a space inside the filename (e.g. Combo 01x01...manuale .avi).

This PR introduces NCFilenameView, a small container that keeps basename and extension in two separate labels — preserving the Unicode bidi-control isolation provided by setBidiSafeFilename — but measures the truncated basename itself, shrinks the title label to the rendered text width and positions the extension label immediately after the last visible glyph.

Changes

  • New NCFilenameView (iOSClient/Extensions/NCFilenameView.swift): lays out the two labels manually, middle-truncates the basename with the available width (binary search, TextKit measurement), keeps the extension untruncated and logically isolated. Forwards forFirstBaselineLayout so baseline alignment in the existing stack view is preserved.
  • NCListCell.xib: the two filename labels are wrapped in an NCFilenameView; the existing labelTitle / labelExtension outlets are unchanged, so no call site changes were needed.
  • setBidiSafeFilename: asks the labels' superview for a layout pass after updating the text.
  • Unit tests (NCFilenameViewTests): cover the truncation helper (untouched short text, fits/maximality, ellipsis fallback) and the tight extension placement.

Notes

  • The security property is unchanged: basename and extension remain in two separate UILabel instances.
  • Only the list layout adopts the new view for now; the same view can be applied to the grid layout and other two-label cells in follow-ups.
  • I could not run the Xcode build locally; CI should verify. Happy to adjust anything.

Closes #4282

AI assistance

  • This PR was created with AI assistance (Kimi).

Signed-off-by: feather2222 1402479908@qq.com

@mpivchev

Copy link
Copy Markdown
Collaborator

Hi @feather2222, thanks for this :) I will test this and get back to you

@feather2222
feather2222 force-pushed the fix/filename-truncation-gap branch 4 times, most recently from b1738a5 to d3a35b1 Compare November 1, 2026 14:32
In the list layout the basename label is middle-truncated by UIKit but
keeps the full remaining width, so the extension label is positioned
after the label frame instead of after the last rendered glyph. The
varying unused width looks like a space inside the filename.

Introduce NCFilenameView, a small container that keeps basename and
extension in two separate labels (preserving the bidi isolation from
setBidiSafeFilename) but measures the truncated basename itself and
shrinks the title label to the rendered text width, placing the
extension immediately after the last visible glyph.

Adopt it in NCListCell and cover the truncation logic with unit tests.

Assisted-by: Kimi:K2

Signed-off-by: feather2222 <1402479908@qq.com>
Signed-off-by: feather2222 <41533380+feather2222@users.noreply.github.com>
@feather2222
feather2222 force-pushed the fix/filename-truncation-gap branch from d3a35b1 to f51056d Compare November 1, 2026 15:21
@feather2222

Copy link
Copy Markdown
Author

Verified on iPhone 17 Pro simulator (iOS 26.2) with a local test server: long filenames now middle-truncate and the extension sits immediately after the last visible glyph, no visual gap.

Test files: Combo 01x01 very long filename manuale.avi, Combo 02x02 another very long name here manuale.avi — both render tight in list layout.

Note: while iterating I reworked the approach — NCFilenameView now performs the middle truncation itself (binary search with TextKit measurement) and writes the truncated string into the label, which renders it as-is. This keeps basename and extension in two separate labels (bidi isolation unchanged) while making the extension position exact by construction. Unit tests updated accordingly.

pr4406-verification

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Avoid visual gap between truncated filename and its extension

2 participants