Skip to content

perf(utils): ensure only 64px or 512px avatars are loaded #6749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

susnux
Copy link
Contributor

@susnux susnux commented Apr 7, 2025

☑️ Resolves

The backend only supports those values,
so loading any other size will result in one of them but will be cached under a different URL by the browser. This should reduce the avatar queries of the browser to only max. 2 per user.

🏁 Checklist

  • ⛑️ Tests are included or are not applicable
  • 📘 Component documentation has been extended, updated or is not applicable
  • 2️⃣ Backport bugfixes to stable8 for maintained Vue 2 version.

@susnux susnux added bug Something isn't working 3. to review Waiting for reviews feature: avatar Related to the avatar component labels Apr 7, 2025
@susnux susnux added this to the v9.0.0-rc.0 milestone Apr 7, 2025
@susnux
Copy link
Contributor Author

susnux commented Apr 7, 2025

/backport to stable8

Comment on lines +425 to +426
const root = useTemplateRef('main')
const isDarkTheme = useIsDarkThemeElement(root)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a need to check specifically main and not body and thus use shared composable?

If so, I would at least go with props.menuContainer, so it inherits it from container

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes otherwise it does not work if you use the avatar within a forced theme.
This can not be influenced by the app developer so we need to do this here.

(how does talk handle this currently? IIRC you use force dark theme during calls?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a need to check specifically main and not body and thus use shared composable?

To avoid misunderstanding, main here is template ref key, not <main> query selector

Copy link
Contributor

@Antreesy Antreesy Apr 7, 2025

Choose a reason for hiding this comment

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

how does talk handle this currently?

<div class="top-bar__wrapper" :data-theme-dark="isInCall"> 🙈

But we do not rewrite avatars in call, if I'm not mistaken, only rely on useIsDarkTheme() composable from the lib

Copy link
Contributor

Choose a reason for hiding this comment

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

We remount the conversation avatar in the top bar

The backend only supports those values,
so loading any other size will result in one of them but will be cached
under a different URL by the browser. This should reduce the avatar
queries of the browser to only max. 2 per user.

Signed-off-by: Ferdinand Thiessen <[email protected]>

setup() {
const root = useTemplateRef('root')
const isDarkTheme = useIsDarkThemeElement(root)
Copy link
Contributor

Choose a reason for hiding this comment

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

In 99% of cases we need only the entire document dark theme. And in rare cases we need to check the avatar itself (for example, in the top bar in Talk during a call, because the call view is always aka dark).

What about using useIsDarkTheme by default and useIsDarkThemeElement only if specified explicitly?

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for other components

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe instead of [data-theme-dark] for override theme we provide <NcThemeProvider /> or useDarkTheme that provides the overridden dark theme?

In this case we don't need a mutation observer and can rely on JS only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

provide inject in the composable?

Copy link
Contributor

Choose a reason for hiding this comment

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

Or in the component provider, both are fine for me.

<!-- before -->
<div data-theme-dark>
  ...content...
</div>

<!-- after -->
<NcThemeProvider dark>
  ...content...
</NcThemeProvider>

Only for the cases when we override the theme.

I worry about it because overriding the theme is quite a rare case, but to support it this PR adds observer for every avatar instance, and we may have a lot.

Comment on lines +32 to +33
// Watch for element changes
watch(element, updateIsDarkTheme)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a use case for this watch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Element updated?

Comment on lines +33 to +47
export function getAvatarUrl(user: string, options?: AvatarUrlOptions): string {
// backend only supports 64 and 512px
// so we only requrest the needed size for better caching of the request.
const size = (options?.size || 64) <= 64
? 64
: 512

const guestUrl = options?.isGuest
? '/guest'
: ''
const themeUrl = options?.isDarkTheme ?? checkIfDarkTheme(document.body)
? '/dark'
: ''

return generateUrl(`/avatar${guestUrl}/{user}/{size}${themeUrl}`, {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be in nextcloud/router?

Co-authored-by: Grigorii K. Shartsev <[email protected]>
Signed-off-by: Ferdinand Thiessen <[email protected]>
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 backport-request bug Something isn't working feature: avatar Related to the avatar component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants