Skip to content

feat: show recent people on contact icon - #62930

Open
kristian-zendato wants to merge 1 commit into
masterfrom
feat/people-menu
Open

feat: show recent people on contact icon#62930
kristian-zendato wants to merge 1 commit into
masterfrom
feat/people-menu

Conversation

@kristian-zendato

@kristian-zendato kristian-zendato commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes the People (contacts) header menu more inviting by showing a stack of up to 3 overlapping avatars of recent contacts on the menu trigger, instead of only the contacts icon.

  • Adds GET /contactsmenu/preview-avatars which returns the first 3 entries from the same unfiltered contacts list as the menu (Manager::getEntries with an empty filter), with optional team filtering matching the existing index endpoint.
  • Frontend loads those contacts on mount and shows an NcAvatar stack when at least 2 are available; otherwise keeps the existing contacts icon.
  • Widens the header trigger (width: fit-content) so the stack does not overlap notifications/profile and remains fully clickable.
  • Adds PHP and Vue unit tests for the new endpoint and trigger behavior.

Screenshot

🏚️ Before

image

🏡 After

image

Checklist

AI (if applicable)

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

@kristian-zendato kristian-zendato added the 3. to review Waiting for reviews label Aug 5, 2026
@kristian-zendato
kristian-zendato requested review from Altahrim, nfebe, provokateurin, skjnldsv and sorbaugh and removed request for a team August 5, 2026 10:00
@SebastianKrupinski

Copy link
Copy Markdown
Contributor

Any chance we can get a couple of screen captures for the visual changes?

Comment on lines +63 to +64
$entries = $this->store->getContacts($user, '', $limit);
return array_slice($this->sortEntries($entries), 0, $limit);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is the idea to get any 3 contacts? Or just the last 3 recent contacts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is to get last 3 recent contacts.

@jancborchardt jancborchardt moved this to 🏗️ At engineering in 🖍 Design team Aug 6, 2026

@kra-mo kra-mo 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.

The border should be consistent with that of the user's avatar. The rest seems good from the screenshot.

@kra-mo kra-mo 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.

Oops, meant to do "Request changes".

Signed-off-by: root <root@srv1582549.hstgr.cloud>
@kristian-zendato

Copy link
Copy Markdown
Contributor Author

@kra-mo I updated the UI. Please check the screenshot from the description above.

Comment on lines +87 to +89
#[NoAdminRequired]
#[FrontpageRoute(verb: 'GET', url: '/contactsmenu/preview-avatars')]
public function previewAvatars(?string $teamId = null): array {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add rate limiting

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

UserRateLimit(limit: 60, period: 120) would be enough for it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tbh, I don't know what a reasonable threshold might be... I can't see a regular user reloading the page every 2s?

Make the span 5min, and the limit 30 times... even that is over kill i think

Comment on lines +95 to +98
$cache = $this->cacheFactory->createDistributed('contactsmenu-preview');
$cacheKey = $user->getUID();
$cached = $cache->get($cacheKey);
if (!is_array($cached)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am not sure if the caching is worth it here. The cache TTL is 5min, which means most likely the cache will never get utilized that much.

Most users will not flip between the apps that frequently, they will click on mail work there for 10min then maybe change over the calendar extra. Power users will just open each app in a separate window, so not sure this will really help any.

@kesselb @DerDreschner what do you think?

Comment on lines +27 to +32
interface IPreviewUser {
uid: string
fullName: string
isUser: boolean
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Interfaces should be extracted in to a separate types file "src/types"

@kra-mo kra-mo 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.

Looks good now :)

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

Projects

Status: 🏗️ At engineering

Development

Successfully merging this pull request may close these issues.

Make People menu more inviting

4 participants