From c5cb542d7e205e9a8f0d6d89156a2b11cc3603fc Mon Sep 17 00:00:00 2001 From: Chen-I Lim Date: Tue, 19 Jan 2021 15:12:54 -0800 Subject: [PATCH] Look up comment username from userId --- webapp/src/components/comment.tsx | 18 +++++++++++++--- webapp/src/components/commentsList.tsx | 4 +--- webapp/src/octoClient.ts | 12 ++++++++++- webapp/src/userCache.ts | 29 ++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 webapp/src/userCache.ts diff --git a/webapp/src/components/comment.tsx b/webapp/src/components/comment.tsx index 07a15b70d..0a49e692e 100644 --- a/webapp/src/components/comment.tsx +++ b/webapp/src/components/comment.tsx @@ -1,6 +1,6 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {FC} from 'react' +import React, {FC, useEffect, useState} from 'react' import {injectIntl, IntlShape} from 'react-intl' import {IBlock} from '../blocks/block' @@ -11,18 +11,30 @@ import DeleteIcon from '../widgets/icons/delete' import OptionsIcon from '../widgets/icons/options' import Menu from '../widgets/menu' import MenuWrapper from '../widgets/menuWrapper' +import {UserCache} from '../userCache' import './comment.scss' type Props = { comment: IBlock - username: string + userId: string userImageUrl: string intl: IntlShape } const Comment: FC = (props: Props) => { - const {comment, username, userImageUrl, intl} = props + const {comment, userId, userImageUrl, intl} = props const html = Utils.htmlFromMarkdown(comment.title) + + const [username, setUsername] = useState('') + + useEffect(() => { + UserCache.shared.getUser(userId).then((user) => { + if (user) { + setUsername(user.username) + } + }) + }, []) + return (
{ key={comment.id} comment={comment} userImageUrl={userImageUrl} - - // TODO: Look up user name from userId - username={comment.userId} + userId={comment.userId} /> ))} diff --git a/webapp/src/octoClient.ts b/webapp/src/octoClient.ts index 5ed837902..cd0e69ba3 100644 --- a/webapp/src/octoClient.ts +++ b/webapp/src/octoClient.ts @@ -88,8 +88,18 @@ class OctoClient { return user } + async getUser(userId: string): Promise { + const path = `/api/v1/users/${encodeURIComponent(userId)}` + const response = await fetch(this.serverUrl + path, {headers: this.headers()}) + if (response.status !== 200) { + return undefined + } + const user = (await this.getJson(response)) as IUser + return user + } + async getSubtree(rootId?: string, levels = 2): Promise { - let path = `/api/v1/blocks/${rootId}/subtree?l=${levels}` + let path = `/api/v1/blocks/${encodeURIComponent(rootId || '')}/subtree?l=${levels}` if (this.readToken) { path += `&read_token=${this.readToken}` } diff --git a/webapp/src/userCache.ts b/webapp/src/userCache.ts new file mode 100644 index 000000000..73af39178 --- /dev/null +++ b/webapp/src/userCache.ts @@ -0,0 +1,29 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import octoClient from './octoClient' +import {IUser} from './user' + +class UserCache { + static shared = new UserCache() + + private cache = new Map() + + async getUser(userId: string): Promise { + let user = this.cache.get(userId) + if (!user) { + user = await octoClient.getUser(userId) + if (user) { + this.cache.set(userId, user) + } + } + + return user || undefined + } + + clear(): void { + this.cache.clear() + } +} + +export {UserCache}