diff --git a/services/web/frontend/js/features/chat/components/chat-pane.tsx b/services/web/frontend/js/features/chat/components/chat-pane.tsx index 2d965c4228..ff928fb769 100644 --- a/services/web/frontend/js/features/chat/components/chat-pane.tsx +++ b/services/web/frontend/js/features/chat/components/chat-pane.tsx @@ -94,7 +94,6 @@ const ChatPane = React.memo(function ChatPane() { {shouldDisplayPlaceholder && } diff --git a/services/web/frontend/js/features/chat/components/message-list.tsx b/services/web/frontend/js/features/chat/components/message-list.tsx index 410cd255f2..bf3515719d 100644 --- a/services/web/frontend/js/features/chat/components/message-list.tsx +++ b/services/web/frontend/js/features/chat/components/message-list.tsx @@ -1,7 +1,7 @@ import moment from 'moment' import Message from './message' -import { UserId } from '../../../../../types/user' import type { Message as MessageType } from '@/features/chat/context/chat-context' +import { useUserContext } from '@/shared/context/user-context' const FIVE_MINUTES = 5 * 60 * 1000 @@ -16,14 +16,11 @@ function formatTimestamp(date: moment.MomentInput) { interface MessageListProps { messages: MessageType[] resetUnreadMessages(...args: unknown[]): unknown - userId: UserId | null } -function MessageList({ - messages, - resetUnreadMessages, - userId, -}: MessageListProps) { +function MessageList({ messages, resetUnreadMessages }: MessageListProps) { + const user = useUserContext() + function shouldRenderDate(messageIndex: number) { if (messageIndex === 0) { return true @@ -61,7 +58,10 @@ function MessageList({ )} - + ))} diff --git a/services/web/frontend/js/features/chat/components/message.tsx b/services/web/frontend/js/features/chat/components/message.tsx index 87fbb8dbd3..a0cf769129 100644 --- a/services/web/frontend/js/features/chat/components/message.tsx +++ b/services/web/frontend/js/features/chat/components/message.tsx @@ -1,42 +1,40 @@ -import { getHueForUserId } from '../../../shared/utils/colors' +import { getHueForUserId } from '@/shared/utils/colors' import MessageContent from './message-content' import type { Message as MessageType } from '@/features/chat/context/chat-context' import { User } from '../../../../../types/user' interface MessageProps { message: MessageType - userId: string | null + fromSelf: boolean } -function Message({ message, userId }: MessageProps) { - function hue(user?: User) { - return user ? getHueForUserId(user.id, userId) : 0 +function hue(user?: User) { + return user ? getHueForUserId(user.id) : 0 +} + +function getMessageStyle(user?: User) { + return { + borderColor: `hsl(${hue(user)}, 85%, 40%)`, + backgroundColor: `hsl(${hue(user)}, 85%, 40%`, } +} - function getMessageStyle(user?: User) { - return { - borderColor: `hsl(${hue(user)}, 85%, 40%)`, - backgroundColor: `hsl(${hue(user)}, 85%, 40%`, - } +function getArrowStyle(user?: User) { + return { + borderColor: `hsl(${hue(user)}, 85%, 40%)`, } +} - function getArrowStyle(user?: User) { - return { - borderColor: `hsl(${hue(user)}, 85%, 40%)`, - } - } - - const isMessageFromSelf = message.user ? message.user.id === userId : false - +function Message({ message, fromSelf }: MessageProps) { return (
- {!isMessageFromSelf && message.user.id && ( + {!fromSelf && (
{message.user.first_name || message.user.email}
)}
- {!isMessageFromSelf && ( + {!fromSelf && (
)}
diff --git a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.jsx b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.jsx index e1c32bcc85..75d0f99bb9 100644 --- a/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.jsx +++ b/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.jsx @@ -10,7 +10,7 @@ import { DropdownToggle, } from '@/features/ui/components/bootstrap-5/dropdown-menu' import Icon from '../../../shared/components/icon' -import { getHueForUserId } from '../../../shared/utils/colors' +import { getBackgroundColorForUserId } from '@/shared/utils/colors' import ControlledDropdown from '../../../shared/components/controlled-dropdown' import OLTooltip from '@/features/ui/components/ol/ol-tooltip' import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher' @@ -107,7 +107,7 @@ OnlineUsersWidget.propTypes = { } function UserIcon({ user, showName, onClick }) { - const backgroundColor = `hsl(${getHueForUserId(user.user_id)}, 70%, 50%)` + const backgroundColor = getBackgroundColorForUserId(user.user_id) function handleOnClick() { onClick?.(user) diff --git a/services/web/frontend/js/features/history/components/change-list/metadata-users-list.tsx b/services/web/frontend/js/features/history/components/change-list/metadata-users-list.tsx index 73d079a598..5b1ba94eef 100644 --- a/services/web/frontend/js/features/history/components/change-list/metadata-users-list.tsx +++ b/services/web/frontend/js/features/history/components/change-list/metadata-users-list.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next' -import { getUserColor } from '../../utils/history-details' import { LoadedUpdate } from '../../services/types/update' import UserNameWithColoredBadge from './user-name-with-colored-badge' +import { getBackgroundColorForUserId } from '@/shared/utils/colors' type MetadataUsersListProps = { currentUserId: string @@ -28,7 +28,7 @@ function MetadataUsersList({
  • {origin?.kind === 'history-resync' || origin?.kind === 'history-migration' diff --git a/services/web/frontend/js/features/history/components/change-list/user-name-with-colored-badge.tsx b/services/web/frontend/js/features/history/components/change-list/user-name-with-colored-badge.tsx index 9a82dd62ea..ed1da6e757 100644 --- a/services/web/frontend/js/features/history/components/change-list/user-name-with-colored-badge.tsx +++ b/services/web/frontend/js/features/history/components/change-list/user-name-with-colored-badge.tsx @@ -1,7 +1,8 @@ import { useTranslation } from 'react-i18next' -import { formatUserName, getUserColor } from '../../utils/history-details' +import { formatUserName } from '../../utils/history-details' import { User } from '../../services/types/shared' import { Nullable } from '../../../../../../types/utils' +import { getBackgroundColorForUserId } from '@/shared/utils/colors' type UserNameWithColoredBadgeProps = { currentUserId: string @@ -29,7 +30,7 @@ function UserNameWithColoredBadge({ <> {userName} diff --git a/services/web/frontend/js/features/history/context/history-context.tsx b/services/web/frontend/js/features/history/context/history-context.tsx index 262eaf7c73..7dc2c996c5 100644 --- a/services/web/frontend/js/features/history/context/history-context.tsx +++ b/services/web/frontend/js/features/history/context/history-context.tsx @@ -17,7 +17,6 @@ import { isFileRenamed } from '../utils/file-diff' import { loadLabels } from '../utils/label' import { autoSelectFile } from '../utils/auto-select-file' import usePersistedState from '../../../shared/hooks/use-persisted-state' -import ColorManager from '../../../ide/colors/ColorManager' import moment from 'moment' import { cloneDeep } from 'lodash' import { @@ -28,6 +27,7 @@ import { import { Selection } from '../services/types/selection' import { useErrorHandler } from 'react-error-boundary' import { getUpdateForVersion } from '../utils/history-details' +import { getHueForUserId } from '@/shared/utils/colors' // Allow testing of infinite scrolling by providing query string parameters to // limit the number of updates returned in a batch and apply a delay @@ -120,7 +120,7 @@ function useHistory() { for (const [index, update] of loadedUpdates.entries()) { for (const user of update.meta.users) { if (user) { - user.hue = ColorManager.getHueForUserId(user.id) + user.hue = getHueForUserId(user.id) } } if ( diff --git a/services/web/frontend/js/features/history/utils/highlights-from-diff-response.ts b/services/web/frontend/js/features/history/utils/highlights-from-diff-response.ts index bdcc087ab1..e9b9d533bd 100644 --- a/services/web/frontend/js/features/history/utils/highlights-from-diff-response.ts +++ b/services/web/frontend/js/features/history/utils/highlights-from-diff-response.ts @@ -1,8 +1,8 @@ import moment from 'moment/moment' -import ColorManager from '../../../ide/colors/ColorManager' import { DocDiffChunk, Highlight } from '../services/types/doc' import { TFunction } from 'i18next' import displayNameForUser from './display-name-for-user' +import { getHueForUserId } from '@/shared/utils/colors' export function highlightsFromDiffResponse( chunks: DocDiffChunk[], @@ -37,7 +37,7 @@ export function highlightsFromDiffResponse( // There doesn't seem to be a convenient way to make this translatable label: t('added_by_on', { name, date }), range, - hue: ColorManager.getHueForUserId(user?.id), + hue: getHueForUserId(user?.id), }) } else if (isDeletion) { highlights.push({ @@ -45,7 +45,7 @@ export function highlightsFromDiffResponse( // There doesn't seem to be a convenient way to make this translatable label: t('deleted_by_on', { name, date }), range, - hue: ColorManager.getHueForUserId(user?.id), + hue: getHueForUserId(user?.id), }) } } diff --git a/services/web/frontend/js/features/history/utils/history-details.ts b/services/web/frontend/js/features/history/utils/history-details.ts index bdd89167c1..27f9cfdbc9 100644 --- a/services/web/frontend/js/features/history/utils/history-details.ts +++ b/services/web/frontend/js/features/history/utils/history-details.ts @@ -1,15 +1,7 @@ -import ColorManager from '../../../ide/colors/ColorManager' -import { Nullable } from '../../../../../types/utils' import { User } from '../services/types/shared' import { LoadedUpdate, ProjectOp, Version } from '../services/types/update' import { Selection } from '../services/types/selection' -export const getUserColor = (user?: Nullable<{ id: string }>) => { - const hue = ColorManager.getHueForUserId(user?.id) || 100 - - return `hsl(${hue}, 70%, 50%)` -} - export const formatUserName = (user: User) => { let name = [user.first_name, user.last_name] .filter(n => n != null) diff --git a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx index 2da9df438f..137e0f7157 100644 --- a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx @@ -11,7 +11,6 @@ import { ReactScopeValueStore } from '@/features/ide-react/scope-value-store/rea import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context' import { useConnectionContext } from '@/features/ide-react/context/connection-context' import useScopeValue from '@/shared/hooks/use-scope-value' -import ColorManager from '@/ide/colors/ColorManager' import { CursorPosition } from '@/features/ide-react/types/cursor-position' import { omit } from 'lodash' import { Doc } from '../../../../../types/doc' @@ -20,6 +19,7 @@ import { findDocEntityById } from '@/features/ide-react/util/find-doc-entity-by- import useSocketListener from '@/features/ide-react/hooks/use-socket-listener' import { debugConsole } from '@/utils/debugging' import { IdeEvents } from '@/features/ide-react/create-ide-event-emitter' +import { getHueForUserId } from '@/shared/utils/colors' type OnlineUser = { id: string @@ -139,7 +139,7 @@ export const OnlineUsersProvider: FC = ({ children }) => { row: user.row, column: user.column, }, - hue: ColorManager.getHueForUserId(user.user_id), + hue: getHueForUserId(user.user_id), }) } diff --git a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts index 082f466824..e95eba51fd 100644 --- a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts +++ b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts @@ -25,7 +25,6 @@ import { } from '@/features/ide-react/context/editor-manager-context' import { debugConsole } from '@/utils/debugging' import { deleteJSON, getJSON, postJSON } from '@/infrastructure/fetch-json' -import ColorManager from '@/ide/colors/ColorManager' import RangesTracker from '@overleaf/ranges-tracker' import type * as ReviewPanel from '@/features/source-editor/context/review-panel/types/review-panel-state' import { @@ -66,6 +65,7 @@ import { import { RangesTrackerWithResolvedThreadIds } from '@/features/ide-react/editor/document-container' import getMeta from '@/utils/meta' import { useEditorContext } from '@/shared/context/editor-context' +import { getHueForUserId } from '@/shared/utils/colors' const dispatchReviewPanelEvent = (type: string, payload?: any) => { window.dispatchEvent( @@ -86,7 +86,7 @@ const formatUser = (user: any): any => { email: null, name: 'Anonymous', isSelf: false, - hue: ColorManager.ANONYMOUS_HUE, + hue: getHueForUserId(), avatar_text: 'A', } } @@ -108,7 +108,7 @@ const formatUser = (user: any): any => { email: user.email, name, isSelf, - hue: ColorManager.getHueForUserId(id), + hue: getHueForUserId(id), avatar_text: [user.first_name, user.last_name] .filter(n => n != null) .map(n => n[0]) diff --git a/services/web/frontend/js/features/project-list/util/tag.ts b/services/web/frontend/js/features/project-list/util/tag.ts index c0069d18e7..74ed1cbcb3 100644 --- a/services/web/frontend/js/features/project-list/util/tag.ts +++ b/services/web/frontend/js/features/project-list/util/tag.ts @@ -1,5 +1,5 @@ import { Tag } from '../../../../../app/src/Features/Tags/types' -import ColorManager from '../../../ide/colors/ColorManager' +import { getHueForId } from '@/shared/utils/colors' export const MAX_TAG_LENGTH = 50 @@ -7,5 +7,5 @@ export function getTagColor(tag?: Tag): string | undefined { if (!tag) { return undefined } - return tag.color || `hsl(${ColorManager.getHueForTagId(tag._id)}, 70%, 45%)` + return tag.color || `hsl(${getHueForId(tag._id)}, 70%, 45%)` } diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx index 2c606c3b23..932813faef 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx @@ -2,7 +2,7 @@ import { memo } from 'react' import { buildName } from '../utils/build-name' import { ReviewPanelUser } from '../../../../../types/review-panel/review-panel' import { ChangesUser } from '../context/changes-users-context' -import ColorManager from '@/ide/colors/ColorManager' +import { getBackgroundColorForUserId } from '@/shared/utils/colors' const ReviewPanelEntryUser = ({ user, @@ -10,13 +10,14 @@ const ReviewPanelEntryUser = ({ user?: ReviewPanelUser | ChangesUser }) => { const userName = buildName(user) - const hue = ColorManager.getHueForUserId(user?.id) || 100 return (
    {userName}
    diff --git a/services/web/frontend/js/ide/colors/ColorManager.js b/services/web/frontend/js/ide/colors/ColorManager.js deleted file mode 100644 index bc63e8474f..0000000000 --- a/services/web/frontend/js/ide/colors/ColorManager.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable - camelcase, - max-len, - no-return-assign, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ - -// NOTE: this file is being refactored over to frontend/js/shared/utils/colors.js - -import { generateMD5Hash } from './../../shared/utils/md5' -import getMeta from '@/utils/meta' - -let ColorManager - -export default ColorManager = { - getColorScheme(hue, element) { - if (this.isDarkTheme(element)) { - return { - cursor: `hsl(${hue}, 70%, 50%)`, - labelBackgroundColor: `hsl(${hue}, 70%, 50%)`, - highlightBackgroundColor: `hsl(${hue}, 100%, 28%);`, - strikeThroughBackgroundColor: `hsl(${hue}, 100%, 20%);`, - strikeThroughForegroundColor: `hsl(${hue}, 100%, 60%);`, - } - } else { - return { - cursor: `hsl(${hue}, 70%, 50%)`, - labelBackgroundColor: `hsl(${hue}, 70%, 50%)`, - highlightBackgroundColor: `hsl(${hue}, 70%, 85%);`, - strikeThroughBackgroundColor: `hsl(${hue}, 70%, 95%);`, - strikeThroughForegroundColor: `hsl(${hue}, 70%, 40%);`, - } - } - }, - - isDarkTheme(element) { - const rgb = element.find('.ace_editor').css('background-color') - let [m, r, g, b] = Array.from( - rgb.match(/rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)/) - ) - r = parseInt(r, 10) - g = parseInt(g, 10) - b = parseInt(b, 10) - return r + g + b < 3 * 128 - }, - - ANONYMOUS_HUE: 100, - OWN_HUE: 200, // We will always appear as this color to ourselves - OWN_HUE_BLOCKED_SIZE: 20, // no other user should havea HUE in this range - TOTAL_HUES: 360, // actually 361, but 360 for legacy reasons - getHueForUserId(user_id) { - if (user_id == null || user_id === 'anonymous-user') { - return this.ANONYMOUS_HUE - } - - if (getMeta('ol-user').id === user_id) { - return this.OWN_HUE - } - - let hue = this.getHueForId(user_id) - - // if `hue` is within `OWN_HUE_BLOCKED_SIZE` degrees of the personal hue - // (`OWN_HUE`), shift `hue` to the end of available hues by adding - if ( - hue > this.OWN_HUE - this.OWN_HUE_BLOCKED_SIZE && - hue < this.OWN_HUE + this.OWN_HUE_BLOCKED_SIZE - ) { - hue = hue - this.OWN_HUE // `hue` now at 0 +/- `OWN_HUE_BLOCKED_SIZE` - hue = hue + this.TOTAL_HUES - this.OWN_HUE_BLOCKED_SIZE - } - - return hue - }, - - getHueForTagId(tag_id) { - return this.getHueForId(tag_id) - }, - - getHueForId(id) { - const hash = generateMD5Hash(id) - const hue = - parseInt(hash.toString().slice(0, 8), 16) % - (this.TOTAL_HUES - this.OWN_HUE_BLOCKED_SIZE * 2) - return hue - }, -} diff --git a/services/web/frontend/js/shared/utils/colors.ts b/services/web/frontend/js/shared/utils/colors.ts index 27fb1c9203..346a52d03a 100644 --- a/services/web/frontend/js/shared/utils/colors.ts +++ b/services/web/frontend/js/shared/utils/colors.ts @@ -1,16 +1,17 @@ import { generateMD5Hash } from './md5' +import getMeta from '@/utils/meta' const ANONYMOUS_HUE = 100 const OWN_HUE = 200 // We will always appear as this color to ourselves const OWN_HUE_BLOCKED_SIZE = 20 // no other user should have a HUE in this range const TOTAL_HUES = 360 // actually 361, but 360 for legacy reasons -export function getHueForUserId(userId: string, currentUserId: string | null) { +export function getHueForUserId(userId?: string): number { if (userId == null || userId === 'anonymous-user') { return ANONYMOUS_HUE } - if (currentUserId === userId) { + if (getMeta('ol-user_id') === userId) { return OWN_HUE } @@ -29,10 +30,23 @@ export function getHueForUserId(userId: string, currentUserId: string | null) { return hue } -function getHueForId(id: string) { +export function getBackgroundColorForUserId(userId?: string) { + return `hsl(${getHueForUserId(userId)}, 70%, 50%)` +} + +const cachedHues = new Map() + +export function getHueForId(id: string) { + if (cachedHues.has(id)) { + return cachedHues.get(id) + } + const hash = generateMD5Hash(id) + const hue = - parseInt(hash.toString().slice(0, 8), 16) % - (TOTAL_HUES - OWN_HUE_BLOCKED_SIZE * 2) + parseInt(hash.slice(0, 8), 16) % (TOTAL_HUES - OWN_HUE_BLOCKED_SIZE * 2) + + cachedHues.set(id, hue) + return hue } diff --git a/services/web/frontend/js/shared/utils/md5.js b/services/web/frontend/js/shared/utils/md5.ts similarity index 85% rename from services/web/frontend/js/shared/utils/md5.js rename to services/web/frontend/js/shared/utils/md5.ts index b6c3961daa..c5a9dd19e2 100644 --- a/services/web/frontend/js/shared/utils/md5.js +++ b/services/web/frontend/js/shared/utils/md5.ts @@ -8,9 +8,9 @@ * See http://pajhome.org.uk/crypt/md5 for more info. */ -export function generateMD5Hash(inputString) { +export function generateMD5Hash(inputString: string): string { const hc = '0123456789abcdef' - function rh(n) { + function rh(n: number) { let j let s = '' for (j = 0; j <= 3; j++) @@ -18,30 +18,69 @@ export function generateMD5Hash(inputString) { hc.charAt((n >> (j * 8 + 4)) & 0x0f) + hc.charAt((n >> (j * 8)) & 0x0f) return s } - function ad(x, y) { + function ad(x: number, y: number) { const l = (x & 0xffff) + (y & 0xffff) const m = (x >> 16) + (y >> 16) + (l >> 16) return (m << 16) | (l & 0xffff) } - function rl(n, c) { + function rl(n: number, c: number) { return (n << c) | (n >>> (32 - c)) } - function cm(q, a, b, x, s, t) { + function cm( + q: number, + a: number, + b: number, + x: number, + s: number, + t: number + ) { return ad(rl(ad(ad(a, q), ad(x, t)), s), b) } - function ff(a, b, c, d, x, s, t) { + function ff( + a: number, + b: number, + c: number, + d: number, + x: number, + s: number, + t: number + ) { return cm((b & c) | (~b & d), a, b, x, s, t) } - function gg(a, b, c, d, x, s, t) { + function gg( + a: number, + b: number, + c: number, + d: number, + x: number, + s: number, + t: number + ) { return cm((b & d) | (c & ~d), a, b, x, s, t) } - function hh(a, b, c, d, x, s, t) { + function hh( + a: number, + b: number, + c: number, + d: number, + x: number, + s: number, + t: number + ) { return cm(b ^ c ^ d, a, b, x, s, t) } - function ii(a, b, c, d, x, s, t) { + function ii( + a: number, + b: number, + c: number, + d: number, + x: number, + s: number, + t: number + ) { return cm(c ^ (b | ~d), a, b, x, s, t) } - function sb(x) { + function sb(x: string) { let i const nblk = ((x.length + 8) >> 6) + 1 const blks = new Array(nblk * 16) diff --git a/services/web/frontend/stories/chat.stories.jsx b/services/web/frontend/stories/chat.stories.jsx index 9b6bd73121..72c9455eaf 100644 --- a/services/web/frontend/stories/chat.stories.jsx +++ b/services/web/frontend/stories/chat.stories.jsx @@ -3,6 +3,7 @@ import useFetchMock from './hooks/use-fetch-mock' import { generateMessages } from './fixtures/chat-messages' import { ScopeDecorator } from './decorators/scope' import { bsVersionDecorator } from '../../.storybook/utils/with-bootstrap-switcher' +import { UserProvider } from '@/shared/context/user-context' export const Conversation = args => { useFetchMock(fetchMock => { @@ -48,5 +49,12 @@ export default { args: { resetUnreadMessages: () => {}, }, - decorators: [ScopeDecorator], + decorators: [ + ScopeDecorator, + Story => ( + + + + ), + ], } diff --git a/services/web/test/frontend/features/chat/components/message-list.test.jsx b/services/web/test/frontend/features/chat/components/message-list.test.jsx index fa7e62da1c..a1016edd60 100644 --- a/services/web/test/frontend/features/chat/components/message-list.test.jsx +++ b/services/web/test/frontend/features/chat/components/message-list.test.jsx @@ -4,6 +4,7 @@ import { screen, render, fireEvent } from '@testing-library/react' import MessageList from '../../../../../frontend/js/features/chat/components/message-list' import { stubMathJax, tearDownMathJaxStubs } from './stubs' +import { UserProvider } from '@/shared/context/user-context' describe('', function () { const currentUser = { @@ -37,13 +38,25 @@ describe('', function () { tearDownMathJaxStubs() }) + let olUser + beforeEach(function () { + olUser = window.metaAttributesCache.get('ol-user') + window.metaAttributesCache.set('ol-user', currentUser) + }) + + afterEach(function () { + window.metaAttributesCache.set('ol-user', olUser) + }) + it('renders multiple messages', function () { render( - {}} - /> + + {}} + /> + ) screen.getByText('a message') @@ -56,11 +69,13 @@ describe('', function () { msgs[1].timestamp = new Date(2019, 6, 3, 4, 27).getTime() render( - {}} - /> + + {}} + /> + ) screen.getByText('4:23 am Wed, 3rd Jul 19') @@ -73,11 +88,13 @@ describe('', function () { msgs[1].timestamp = new Date(2019, 6, 3, 4, 31).getTime() render( - {}} - /> + + {}} + /> + ) screen.getByText('4:23 am Wed, 3rd Jul 19') @@ -87,11 +104,13 @@ describe('', function () { it('resets the number of unread messages after clicking on the input', function () { const resetUnreadMessages = sinon.stub() render( - + + + ) fireEvent.click(screen.getByRole('list')) diff --git a/services/web/test/frontend/features/chat/components/message.test.jsx b/services/web/test/frontend/features/chat/components/message.test.jsx index 4f32f7254c..a3b4574242 100644 --- a/services/web/test/frontend/features/chat/components/message.test.jsx +++ b/services/web/test/frontend/features/chat/components/message.test.jsx @@ -26,7 +26,7 @@ describe('', function () { user: currentUser, } - render() + render() screen.getByText('a message') }) @@ -37,7 +37,7 @@ describe('', function () { user: currentUser, } - render() + render() screen.getByText('a message') screen.getByText('another message') @@ -51,7 +51,7 @@ describe('', function () { user: currentUser, } - render() + render() screen.getByRole('link', { name: 'https://overleaf.com' }) }) @@ -63,7 +63,7 @@ describe('', function () { } it('does not render the user name nor the email', function () { - render() + render() expect(screen.queryByText(currentUser.first_name)).to.not.exist expect(screen.queryByText(currentUser.email)).to.not.exist @@ -82,7 +82,7 @@ describe('', function () { } it('should render the other user name', function () { - render() + render() screen.getByText(otherUser.first_name) }) @@ -96,7 +96,7 @@ describe('', function () { }, } - render() + render() expect(screen.queryByText(otherUser.first_name)).to.not.exist screen.getByText(msg.user.email) diff --git a/services/web/test/frontend/features/project-list/helpers/render-with-context.tsx b/services/web/test/frontend/features/project-list/helpers/render-with-context.tsx index deda37a2fa..c28dcd0c94 100644 --- a/services/web/test/frontend/features/project-list/helpers/render-with-context.tsx +++ b/services/web/test/frontend/features/project-list/helpers/render-with-context.tsx @@ -6,6 +6,7 @@ import { ProjectListProvider } from '../../../../../frontend/js/features/project import { Project } from '../../../../../types/project/dashboard/api' import { projectsData } from '../fixtures/projects-data' import { SplitTestProvider } from '@/shared/context/split-test-context' +import { UserProvider } from '@/shared/context/user-context' type Options = { projects?: Project[] @@ -31,16 +32,24 @@ export function renderWithProjectListContext( body: [], }) + window.metaAttributesCache.set('ol-user', { + id: 'fake_user', + first_name: 'fake_user_first_name', + email: 'fake@example.com', + }) + const ProjectListProviderWrapper = ({ children, }: { children: React.ReactNode }) => ( - - - {children} - - + + + + {children} + + + ) return render(component, { diff --git a/services/web/test/frontend/shared/utils/colors.test.js b/services/web/test/frontend/shared/utils/colors.test.js index 896c9d5c8f..3b0f28cddd 100644 --- a/services/web/test/frontend/shared/utils/colors.test.js +++ b/services/web/test/frontend/shared/utils/colors.test.js @@ -3,11 +3,15 @@ import { expect } from 'chai' import { getHueForUserId } from '@/shared/utils/colors' describe('colors', function () { - const currentUser = '5bf7dab7a18b0b7a1cf6738c' + const currentUserId = '5bf7dab7a18b0b7a1cf6738c' + + beforeEach(function () { + window.metaAttributesCache.set('ol-user_id', currentUserId) + }) describe('getHueForUserId', function () { it('returns the OWN_HUE for the current user', function () { - expect(getHueForUserId(currentUser, currentUser)).to.equal(200) + expect(getHueForUserId(currentUserId)).to.equal(200) }) it('returns the ANONYMOUS_HUE for an anonymous user', function () { @@ -16,18 +20,16 @@ describe('colors', function () { }) it('generates a hue based on user id', function () { - expect(getHueForUserId('59ad79f46337430b3d37cb9e', currentUser)).to.equal( - 146 - ) + expect( + getHueForUserId('59ad79f46337430b3d37cb9e', currentUserId) + ).to.equal(146) }) it('shifts the hue away from the OWN_HUE if it is within a threshold', function () { // Ordinarily, this user id would generate a hue of 183. However, this is // visually "too close" to the OWN_HUE, meaning that it could be // misinterpreted. Therefore we shift it away - expect(getHueForUserId('20ad79f46337430b3d37cb9f', currentUser)).to.equal( - 323 - ) + expect(getHueForUserId('20ad79f46337430b3d37cb9f')).to.equal(323) }) }) }) diff --git a/services/web/test/frontend/shared/utils/md5.test.js b/services/web/test/frontend/shared/utils/md5.test.js index 89c0f40f14..a47a9d5cd4 100644 --- a/services/web/test/frontend/shared/utils/md5.test.js +++ b/services/web/test/frontend/shared/utils/md5.test.js @@ -1,6 +1,6 @@ import { expect } from 'chai' -import { generateMD5Hash } from '../../../../frontend/js/shared/utils/md5' +import { generateMD5Hash } from '@/shared/utils/md5' describe('md5', function () { describe('generateSHA1Hash', function () {