Skip to content

Create a reference widget AKA Smart Picker widget - #19088

Open
jospoortvliet wants to merge 3 commits into
nextcloud:mainfrom
jospoortvliet:feat/noid/reference-widget
Open

Create a reference widget AKA Smart Picker widget#19088
jospoortvliet wants to merge 3 commits into
nextcloud:mainfrom
jospoortvliet:feat/noid/reference-widget

Conversation

@jospoortvliet

@jospoortvliet jospoortvliet commented Aug 24, 2026

Copy link
Copy Markdown
Member

☑️ Resolves

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Claude Sonnet 5 to be exact.

Summary

Adds a real Talk widget for the Smart Picker (Reference Provider), replacing the generic open-graph card that a Talk conversation link now shows.

This means Talk conversation links render as a little conversation card: avatar, display name, conversation type, and the last message.

Still want to add room description too, as this got lost. And see what else we could show, making the widget a bit nicer. But first looking for some feedback.

This is read-only, and thus has no interactions like join a talk/chat. Maybe for a V2. But clicking of course opens the Talk room (link).

What changed

(Claude-generated description):

  • RenderReferenceEventListener (new, lib/Collaboration/Reference/, registered in Application.php): listens for OCP\Collaboration\Reference\RenderReferenceEvent and loads the new talk-reference script bundle wherever a reference is rendered (Text, comments, Collectives, etc.).
  • src/reference.ts (new entry point, added to rspack.config.js): registers a call widget for the Smart Picker with hasInteractiveView: false, fullWidth: false, isResizable: false.
  • CallReferenceWidget.vue (new): fetches the conversation via the existing authorized conversation endpoint and renders avatar/name/type/last-message. Falls back to metadata-only (title from the Reference payload) when the room isn't accessible or the fetch fails.
  • Small additive options param on fetchConversation() in conversationsService.ts — no behavior change for existing callers.
  • Frontend unit tests (CallReferenceWidget.spec.ts, 6 cases) and a PHP test for the event listener.

Why client-side fetch, not a fatter Reference

TalkReferenceProvider caches resolved references by room (getCachePrefix()/getCacheKey()). Last message, participant state, etc. are volatile and have no sensible cache-invalidation story — putting them in the Reference payload would mean the widget serves stale data forever between cache refreshes. So the widget fetches live data itself, the same way the Talk UI does; fetchReference() is untouched.

Access control

No new access checks were added or changed. The existing endpoint used by the widget enforces the same authorization as the rest of Talk (lobby, federation proxy-cache, room membership); the widget just renders what it's given and shows the inaccessible/fallback state when the fetch fails or accessible === false comes back from the provider.

Scope

Out of scope: message history/list rendering, sending messages, reactions, polls, joining calls, live updates. None of src/components/MessagesList/ is touched.

Testing done

  • npm run ts:check, eslint, stylelint — clean
  • npm run test (vitest) — new + existing suites pass
  • php -l, composer cs:fix, composer psalm — clean
  • npm run build — succeeds
  • PHP listener test (RenderReferenceEventListenerTest.php) — not run; this checkout isn't nested under a server install as tests/php/bootstrap.php requires. Needs to run in a proper dev environment before merge.

Open point for review

  • Bundle size. The new reference entry is ~617 KiB (JS+CSS) — smaller than deck/maps (~840 KiB) but still over rspack's size-warning threshold, consistent with Talk's other standalone bundles. Flagging in case reviewers want the ConversationIcon reuse traded for a lighter custom avatar to shrink it further.

🖌️ UI Checklist

🖼️ Screenshots / Screencasts

So I would like to make the widget higher - show a bit more of the image. Just not as crazy big as the original. And add a bit more info!

🏚️ Before 🏡 After
Screenshot before Screenshot after
Screenshot 2026-08-24 at 22 25 16 Screenshot 2026-08-24 at 21 53 50
Screenshot 2026-08-24 at 22 10 59 Screenshot 2026-08-24 at 22 07 53
Screenshot 2026-08-24 at 22 11 41 Screenshot 2026-08-24 at 21 55 06
☀️ Light theme 🌑 Dark Theme
Screenshot 2026-08-24 at 21 54 51 Screenshot 2026-08-24 at 22 09 11

🚧 Tasks

  • get general feedback
  • add description, increase avatar size and wrap the last message, add last message time and the type badge.
  • add unread count and call in progress. <- these have the issue that they are not live. Well, neither are the others, but it's something to at least be aware off ;-)

🏁 Checklist

  • 🌏 Tested with different browsers / clients:
    • Chromium (Chrome / Edge / Opera / Brave)
    • Firefox
    • Safari
    • Integrations with Files sidebar and other apps
    • Not risky to browser differences / client
  • 🖌️ Design was reviewed, approved or inspired by the design team
  • ⛑️ Tests are included or not possible
  • 📗 User documentation in https://github.com/nextcloud/documentation/tree/master/user_manual/talk has been updated or is not required

🛠️ API Checklist

🚧 Tasks

  • ...

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not possible
  • 📘 API documentation in docs/ has been updated or is not required
  • 🔖 Capability is added or not needed

Assisted-by: Claude Sonnet 5:claude-sonnet-5

Register a listener that calls Util::addScript() so other apps'
pages (Text, Collectives, comments, etc.) load Talk's reference
widget bundle whenever they render Smart Picker / link-preview
references, not only when Talk itself renders the page.

Assisted-by: Claude Sonnet 5:claude-sonnet-4.5
Register a 'call' Smart Picker reference widget that replaces the
generic open-graph card with a Talk-shaped one: avatar, conversation
type, display name and (when available) a non-expired last message.

Live conversation data is fetched client-side through the existing,
already-authorized room endpoint; the cached reference payload
produced by TalkReferenceProvider is left untouched so no volatile
data ends up in the reference cache.

hasInteractiveView is explicitly false: this widget is read-only,
with no composer, joining, or message history in this change.

Assisted-by: Claude Sonnet 5:claude-sonnet-4.5
Assisted-by: Claude Sonnet 5:claude-sonnet-4.5
@nickvergessen

nickvergessen commented Aug 27, 2026

Copy link
Copy Markdown
Member

Hi @jospoortvliet thanks for your contribution.

Regarding the actual changes:
I think it's a good to improve them in general and having them as 2-line bubbles is fine. However now it's no longer possible to distinguish if a message or conversation was shared. I think we should use:

  • Room link:
    • Title: Conversation name
    • Image: Conversation avatar
    • Subline: Conversation description
  • Message link:
    • Title: "Actor displayname" in "Conversation name" (like we have for search results)
    • Image: Actor avatar
    • Subline: Message text

Also there seems to be a problem with the avatars at least on Firefox:
grafik

@nickvergessen nickvergessen added this to the ☃️ Next Major (36) milestone Aug 27, 2026
@nickvergessen nickvergessen added enhancement feature: chat 💬 Chat and system messages feature: frontend 🖌️ "Web UI" client feature: integration 📦 Integration with 3rd party (chat) service AI assisted This PR contains AI-assisted commits labels Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI assisted This PR contains AI-assisted commits enhancement feature: chat 💬 Chat and system messages feature: frontend 🖌️ "Web UI" client feature: integration 📦 Integration with 3rd party (chat) service

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a reference widget AKA Smart Picker widget

2 participants