Skip to content

feat: Allow image previews of Files image links - #2946

Open
enjeck wants to merge 5 commits into
mainfrom
image=preview
Open

enjeck wants to merge 5 commits into
mainfrom
image=preview

Conversation

@enjeck

@enjeck enjeck commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

You can create an Link column type and enable previews. Images in the Files app would be shown:

Capture d’écran 2026-09-02 à 07 19 55

Shown like so, and the size is customizable:

Capture d’écran 2026-09-02 à 07 12 23 Capture d’écran 2026-09-02 à 07 12 53

Fixes #580

@enjeck enjeck self-assigned this Sep 2, 2026
@enjeck
enjeck requested a review from blizzz as a code owner September 2, 2026 06:43
@enjeck enjeck added enhancement New feature or request 3. to review Waiting for reviews AI assisted labels Sep 2, 2026
@github-project-automation github-project-automation Bot moved this to 🧭 Planning evaluation (don't pick) in 📝 Productivity team Sep 2, 2026
@samin-z
samin-z self-requested a review September 2, 2026 15:07
@samin-z

samin-z commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@enjeck works like a charm :)
one small nitpick though, maybe for future follow-up we can have MIME-based detection for cases where there is no extension (if that is ever the case), otherwise all good to me.

@enjeck

enjeck commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author
  • check what happens when you share table to someone without access to the images. I expect broken link, but to confirm the UX is good

@AndyScherzinger AndyScherzinger added this to the v2.4.0 milestone Sep 3, 2026
@AndyScherzinger AndyScherzinger moved this from 🧭 Planning evaluation (don't pick) to 🏗️ In progress in 📝 Productivity team Sep 3, 2026
@AndyScherzinger

Copy link
Copy Markdown
Member

In theory you could do it like the files app and if it is an internal file link of any kind, check for a preview? Than you could also show previews for documents for example 🚀 Could of course also just be a follow-up or a thing "for later". In any case, love the feature 🎉

@samin-z

samin-z commented Sep 4, 2026

Copy link
Copy Markdown
Contributor
  • check what happens when you share table to someone without access to the images. I expect broken link, but to confirm the UX is good
    @enjeck yes it is a broken link redirecting user to files
Screenshot 2026-09-04 at 10 07 39

@enjeck

enjeck commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Now, we preview other files like Markdown and PDF:
Capture d’écran 2026-09-08 à 08 30 59

@AndyScherzinger

Copy link
Copy Markdown
Member

Woohoo 🎉

@samin-z

samin-z commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@enjeck i pulled all your latest changes and when i upload a pdf this is how the is shown for me still, is there something im missing?
Screenshot 2026-09-08 at 16 21 04

@AndyScherzinger

Copy link
Copy Markdown
Member

@samin-z did you enable the preview provider in the config.php? (If you also only see the mimetype icon in the files view, than the provider is turner off)

@samin-z

samin-z commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@samin-z did you enable the preview provider in the config.php? (If you also only see the mimetype icon in the files view, than the provider is turner off)

@AndyScherzinger yeah i noticed that and that's what im currently doing

@samin-z

samin-z commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@enjeck all good

@blizzz blizzz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had in a conversation before. If the URL is not a local one, then the browser will do an outreach to an external site. This should not be a security issue… but it can be a privacy issue, as you could leak IP or browser details to a foreign website. Whether this is an issue, it depends… if the field is set from outside (e.g. via public link share) than it would not be trustworthy. If from a user on the instance, it depends on the relationship there. In this hindsight, I am not sure whether we should or have to nail this down a little. (The scenario could also be a user on the instance sharing bad links to outside people).

If we align on having only internal images anyway we can validate against the domain or or just strip it and use a relative path.

  • otherwise, ColumnService::validateCustomSettings() could also guard showPreview/imagePreviewSize.
  • also changing the setting goes not update exisitng rows.
  • ResponseDefinitions needs to have customSettings updated
  • All previews are fetched at once, this could lead to 100 requests at towards /core/preview. Claude suggests Adding loading="lazy" and decoding="async" to the <img> is a one-line change that makes this safe on large tables.
  • It also suggested to limit the preview sizes to 32/64/96/128/192 which is generated by NC.

@enjeck

enjeck commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author
  • It also suggested to limit the preview sizes to 32/64/96/128/192 which is generated by NC.

@blizzz I addressed all except this last point. I don't see why it's better to have these fixed sizes as opposed to a number range between 32 and 192

@enjeck
enjeck requested a review from blizzz September 14, 2026 07:01
@blizzz

blizzz commented Sep 14, 2026

Copy link
Copy Markdown
Member
  • It also suggested to limit the preview sizes to 32/64/96/128/192 which is generated by NC.

@blizzz I addressed all except this last point. I don't see why it's better to have these fixed sizes as opposed to a number range between 32 and 192

The previews themselves will be normalized to match those: https://github.com/nextcloud/server/blob/master/lib/private/Preview/Generator.php#L457-L462. Actually 64 is the lowest number, not 32. Of course it is still possible to render them in different size, they will be then re-scaled again, but in the browser.

I am fine to leave it as is.

@AndyScherzinger

Copy link
Copy Markdown
Member

I'd vote for merge/ship expecting (community) feedback on it which may or may not lead to further improvements on the feature itself.

@blizzz blizzz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's two items open about TextLinkForm.vue, but do not sound blocking to me. Not sure how likely the first could be, the second could be a papercut, but nothing terrible either.

  • a failed /search/providers request leaves providers = [], and mounted() then forces showPreview = false, writing it into customSettings. canSave stays true, so a transient network blip silently discards the user's setting on save.
  • isImagePreviewSizeInvalid only renders a NoteCard; it never sets this.error, so Save stays enabled. The component already owns that channel for the "no provider selected" case.

@enjeck

enjeck commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

The previews themselves will be normalized to match those: https://github.com/nextcloud/server/blob/master/lib/private/Preview/Generator.php#L457-L462. Actually 64 is the lowest number, not 32. Of course it is still possible to render them in different size, they will be then re-scaled again, but in the browser.

Not even sure what the UI would look like if we have a fixed set of sizes. Radio buttons? Dropdown? 🤔

@enjeck

enjeck commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

There's two items open about TextLinkForm.vue, but do not sound blocking to me. Not sure how likely the first could be, the second could be a papercut, but nothing terrible either.

  • a failed /search/providers request leaves providers = [], and mounted() then forces showPreview = false, writing it into customSettings. canSave stays true, so a transient network blip silently discards the user's setting on save.
  • isImagePreviewSizeInvalid only renders a NoteCard; it never sets this.error, so Save stays enabled. The component already owns that channel for the "no provider selected" case.

i fixed these

Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
@blizzz

blizzz commented Sep 15, 2026

Copy link
Copy Markdown
Member

The previews themselves will be normalized to match those: https://github.com/nextcloud/server/blob/master/lib/private/Preview/Generator.php#L457-L462. Actually 64 is the lowest number, not 32. Of course it is still possible to render them in different size, they will be then re-scaled again, but in the browser.

Not even sure what the UI would look like if we have a fixed set of sizes. Radio buttons? Dropdown? 🤔

My gut feeling would have been a drop down, maybe design would have an opinion on that, too.

@blizzz

blizzz commented Sep 15, 2026

Copy link
Copy Markdown
Member

Just a sign-off missing at 4d53e34

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

Labels

3. to review Waiting for reviews AI assisted enhancement New feature or request

Projects

Status: 🏗️ In progress

Development

Successfully merging this pull request may close these issues.

Add column types File/Image/Filelist/Imagelist

4 participants