Skip to content

Add custom project icons with an in-app image picker - #425

Merged
Tryanks merged 8 commits into
Tryanks:mainfrom
guivieiras:topic/project-icons
Sep 16, 2026
Merged

Tryanks merged 8 commits into
Tryanks:mainfrom
guivieiras:topic/project-icons

Conversation

@guivieiras

@guivieiras guivieiras commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Projects can use custom images through the project menu or command palette. The picker browses the attached host and keeps a normalized copy there, so removing the original does not break a manual icon. Use project default clears the choice and refreshes every connected client, including an already selected default.

Defaults come from iconPath in the project-root tcode.json, or t3.json only when the primary file is absent. Project configuration documents file selection, host-relative and absolute paths, unknown fields, invalid JSON/types, image limits, overrides and refresh behavior. The dedicated configuration reader owns these rules. The document also records requirements for a future preserving, atomic editor; configuration writing is not added here.

The host owns thumbnail and display-size raster generation in one implementation. Source pixel limits bound the floating-point resize allocation in addition to decoder limits. Clients return complete host paths unchanged, so a client OS cannot introduce its own separators into a remote path. Icon cache entries refresh after reconnect and reset, and the picker exposes selection to accessibility clients. Icons appear across project views; compact thread status indicators take precedence.

Tests retain the existing persistence/copy/replacement/reset, old-index compatibility and Enter-key regression coverage. The two transparent-edge tests are consolidated at the shared host raster owner. Added cases protect foreign host paths, cached successes/errors across reconnect/reset, resource rejection, map-only configuration and cleanup only after successful index persistence (without deleting external files). UI fixtures use asynchronous protocol replies, keeping file validation at the host owner and exercising the same image-loading path as production. This removes the browse-query synchronous branch and the Windows file-handle cleanup race from the former live-host cache fixture. The existing live-host sidebar/shell fixtures still need a test-only image-query scheduling adapter; the new icon fixtures exercise the asynchronous path. The cache regression establishes an initial Index baseline before reconnecting, and also fails when reconnect baseline clearing is temporarily removed.

Thread lists with matching sample data before and after.

Desktop · Ungrouped

Before After
Desktop · Ungrouped before project icons Desktop · Ungrouped with project icons

Desktop · Grouped

Before After
Desktop · Grouped before project icons Desktop · Grouped with project icons

Mobile · Ungrouped

Before After
Mobile · Ungrouped before project icons Mobile · Ungrouped with project icons

Mobile · Grouped

Before After
Mobile · Grouped before project icons Mobile · Grouped with project icons

Change icon from the command palette

Change icon from the command palette

Change project icon from the project menu

Change project icon from the project menu

Choose an image in the in-app file picker

Choose an image in the in-app file picker

Validation

Passed on macOS in an isolated worktree and build directory:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --locked -- -D warnings
  • cargo build --workspace --locked
  • cargo test --workspace --locked
  • cargo-machete . (CI version 0.9.2)
  • RUSTFLAGS='-D warnings' IPHONEOS_DEPLOYMENT_TARGET=26.0 cargo check -p tcode-ios --target aarch64-apple-ios-sim --locked
  • RUSTFLAGS='-D warnings' cargo check -p tcode-web --target wasm32-unknown-unknown --locked
  • RUSTFLAGS='-D warnings' CARGO_NDK_PLATFORM=26 cargo ndk -t arm64-v8a check -p tcode-android --locked (NDK 27.1.12297006)

Temporarily removing the fixes made four regressions fail: oversized image conversion, positional-array config, foreign host paths and cached icon recovery. Restoring the final source made them pass. The existing transparent-edge regression now covers thumbnail and display sizes through the same host implementation.

Manual validation used a disposable profile: light/dark, wide/compact windows, command-palette entry, directory navigation, path Enter without dismissal, filtering, scrolling, focus outlines, selecting/saving and resetting. Reset removed the managed PNG and cleared the persisted override. The screenshots above illustrate the feature; the refactor retains its layout.

An initial shared-cache run hit the existing terminal burst throughput threshold; the complete isolated rerun passed. That independently reproduced runtime issue is fixed separately in #448. The macOS debug link emitted an unwind-table size warning, and Cargo reports the existing block dependency future-compatibility notice. Native Windows/Linux execution remains for CI; mobile/Web checks above are compilation checks.

@guivieiras
guivieiras marked this pull request as ready for review September 13, 2026 20:02
@Tryanks
Tryanks force-pushed the topic/project-icons branch from b0f4d4d to e193aa3 Compare September 14, 2026 17:12
@Tryanks

Tryanks commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Hey @guivieiras, thanks — I've decided to take this feature.

This PR introduces a new project-level config file, tcode.json. I'd like a doc that records everything about it (something like docs/project-config.md): where it lives, the iconPath field, how relative paths resolve, the t3.json fallback, and how unknown fields and bad JSON are handled. I'd also like Tcode to be able to manage or generate tcode.json down the line.

Once all of these PRs are merged I plan to tackle #409 and then cut a new release.

@Tryanks
Tryanks merged commit 54e296c into Tryanks:main Sep 16, 2026
6 checks passed
@guivieiras

Copy link
Copy Markdown
Contributor Author

@Tryanks nice, thanks!

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.

2 participants