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 () {