Skip to content

feat(pass): custom icon images for Pass items#476

Open
wiland99 wants to merge 1 commit intoProtonMail:mainfrom
wiland99:feat/custom-item-icons
Open

feat(pass): custom icon images for Pass items#476
wiland99 wants to merge 1 commit intoProtonMail:mainfrom
wiland99:feat/custom-item-icons

Conversation

@wiland99
Copy link

Summary

Proof of concept for allowing users to upload custom icon images on Proton Pass items, as proposed in #475.

Approach: Leverages the existing file attachments infrastructure — no backend API or protobuf schema changes needed. Custom icons are stored as encrypted file attachments with a filename convention (__pass_custom_icon__) to distinguish them from regular files.

What's included:

  • Image processing — uploaded images are resized to 64x64 PNG on the client before upload, keeping storage minimal
  • useCustomIcon hook — downloads and decrypts the icon attachment, providing an object URL for rendering
  • SafeItemIcon integration — custom icons display in both list and detail views, taking priority over domain favicons
  • CustomIconField form component — clickable icon area next to the title field for uploading/removing icons
  • Filtering — icon files are hidden from the regular file attachments list

Scope (PoC):

  • Currently integrated into Login item create/edit forms only
  • Extensible to all item types (note, credit card, identity, etc.)

Files changed:

File Change
packages/pass/lib/file-attachments/custom-icon.ts New — constants, predicates, image resize
packages/pass/hooks/files/useCustomIcon.ts New — hook for icon download/display
packages/pass/components/Form/Field/CustomIconField.tsx New — upload UI component
packages/pass/components/Layout/Icon/ItemIcon.tsx Modified — integrate custom icon display
packages/pass/components/Item/Login/Login.new.tsx Modified — add icon field to create form
packages/pass/components/Item/Login/Login.edit.tsx Modified — add icon field to edit form
packages/pass/components/FileAttachments/FileAttachmentsFieldEdit.tsx Modified — filter out icon files
packages/pass/components/FileAttachments/FileAttachmentsView.tsx Modified — filter out icon files

Test plan

  • Create a new Login item — icon upload area appears next to title
  • Upload a PNG/JPEG/WebP/SVG image — icon is resized, encrypted, and uploaded
  • View item in vault list — custom icon displayed instead of favicon/type icon
  • Edit item — existing custom icon is shown, can be replaced or removed
  • Regular file attachments list does not show the icon file
  • Items without custom icons behave unchanged

🤖 Generated with Claude Code

Allow users to upload custom icon images on login items, leveraging the
existing file attachments infrastructure with a filename convention
(__pass_custom_icon__) to distinguish icons from regular attachments.

- Add image processing helper (resize to 64x64 PNG)
- Add useCustomIcon hook to download and display icon attachments
- Integrate custom icon display in SafeItemIcon (list + detail views)
- Add CustomIconField upload component to Login create/edit forms
- Filter icon files from regular file attachments display

Closes ProtonMail#475

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nguyenkims
Copy link
Collaborator

Have you managed to run the code locally and if that's the case, can you put some screenshots of how the feature look here please?

@Willow0349
Copy link

Willow0349 commented Mar 2, 2026

It looks like the web client makes an extra API request to get file attachments for each item with them, which would quickly become a lot of request.

I think it would be better to store the icon as a item field instead, that way it would be retrieved in the same request as the rest item. A text field should be able to contain an SVG file, since it's just XML (and generally quite small, KB's), if people upload a png/jpeg/webp it could be base64 encoded and stored as an SVG, see https://en.wikipedia.org/wiki/Data_URI_scheme#SVG

For people who upload a SVG icon, keeping it as an vector image (SVG) would also avoid losing details, in the process of converting a vector image to a low resolution raster image.

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.

3 participants