From f091868b7c83f1ceb7b845d67ff3f3c6773b7a92 Mon Sep 17 00:00:00 2001 From: hjlarry Date: Wed, 10 Sep 2025 15:15:31 +0800 Subject: [PATCH] use new get avatar api --- api/controllers/console/workspace/account.py | 12 +++++ .../workflow/header/online-users.tsx | 44 +++++++++++++++++-- web/service/common.ts | 4 ++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/api/controllers/console/workspace/account.py b/api/controllers/console/workspace/account.py index 1f22e3fd01..17f917793b 100644 --- a/api/controllers/console/workspace/account.py +++ b/api/controllers/console/workspace/account.py @@ -33,6 +33,7 @@ from controllers.console.wraps import ( only_edition_cloud, setup_required, ) +from core.file import helpers as file_helpers from extensions.ext_database import db from fields.member_fields import account_fields from libs.helper import TimestampField, email, extract_remote_ip, timezone @@ -124,6 +125,17 @@ class AccountNameApi(Resource): class AccountAvatarApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + parser = reqparse.RequestParser() + parser.add_argument("avatar", type=str, required=True, location="args") + args = parser.parse_args() + + avatar_url = file_helpers.get_signed_file_url(args["avatar"]) + return {"avatar_url": avatar_url} + @setup_required @login_required @account_initialization_required diff --git a/web/app/components/workflow/header/online-users.tsx b/web/app/components/workflow/header/online-users.tsx index 36556b2242..d75bc4887f 100644 --- a/web/app/components/workflow/header/online-users.tsx +++ b/web/app/components/workflow/header/online-users.tsx @@ -1,5 +1,5 @@ 'use client' -import { useState } from 'react' +import { useEffect, useState } from 'react' import Avatar from '@/app/components/base/avatar' import { useCollaboration } from '../collaboration/hooks/use-collaboration' import { useStore } from '../store' @@ -13,12 +13,46 @@ import { PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' import { useAppContext } from '@/context/app-context' +import { getAvatar } from '@/service/common' + +const useAvatarUrls = (users: any[]) => { + const [avatarUrls, setAvatarUrls] = useState>({}) + + useEffect(() => { + const fetchAvatars = async () => { + const newAvatarUrls: Record = {} + + await Promise.all( + users.map(async (user) => { + if (user.avatar) { + try { + const response = await getAvatar({ avatar: user.avatar }) + newAvatarUrls[user.sid] = response.avatar_url + } + catch (error) { + console.error('Failed to fetch avatar:', error) + newAvatarUrls[user.sid] = user.avatar + } + } + }), + ) + + setAvatarUrls(newAvatarUrls) + } + + if (users.length > 0) + fetchAvatars() + }, [users]) + + return avatarUrls +} const OnlineUsers = () => { const appId = useStore(s => s.appId) const { onlineUsers } = useCollaboration(appId) const { userProfile } = useAppContext() const [dropdownOpen, setDropdownOpen] = useState(false) + const avatarUrls = useAvatarUrls(onlineUsers || []) const currentUserId = userProfile?.id @@ -33,6 +67,10 @@ const OnlineUsers = () => { const visibleUsers = onlineUsers.slice(0, maxVisible) const remainingCount = onlineUsers.length - maxVisible + const getAvatarUrl = (user: any) => { + return avatarUrls[user.sid] || user.avatar + } + return (
@@ -59,7 +97,7 @@ const OnlineUsers = () => { > { > diff --git a/web/service/common.ts b/web/service/common.ts index 99eb58e2a0..90ec3d99b5 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -397,3 +397,7 @@ export const resetEmail = (body: { new_email: string; token: string }) => export const checkEmailExisted = (body: { email: string }) => post('/account/change-email/check-email-unique', { body }, { silent: true }) + +export const getAvatar: Fetcher<{ avatar_url: string }, { avatar: string }> = ({ avatar }) => { + return get<{ avatar_url: string }>(`/account/avatar?avatar=${avatar}`) +}