Skip to content

Commit

Permalink
Merge branch 'master' into chore/remove-our-avatar
Browse files Browse the repository at this point in the history
  • Loading branch information
gbalint committed Jan 25, 2024
2 parents 6bb4bca + cf3c150 commit e18c805
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 83 deletions.
2 changes: 1 addition & 1 deletion editor/liveblocks.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export type ConnectionInfo = {
id: number
startedAt: number
lastSeen: number
colorIndex: number | null
}

// Optionally, UserMeta represents static/readonly metadata on each user, as
Expand All @@ -83,7 +84,6 @@ export type UserMeta = {
id: string // Accessible through `user.id`
name: string | null
avatar: string | null
colorIndex: number | null
}

// Optionally, the type of custom events broadcast and listened to in this
Expand Down
38 changes: 15 additions & 23 deletions editor/src/components/canvas/controls/comment-indicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ CommentIndicators.displayName = 'CommentIndicators'

interface TemporaryCommentIndicatorProps {
position: CanvasPoint
bgColor: string
fgColor: string
avatarUrl: string | null
initials: string
}
Expand Down Expand Up @@ -123,14 +121,12 @@ function useCommentBeingComposed(): TemporaryCommentIndicatorProps | null {
if (collaborator == null) {
return {
initials: 'AN',
color: multiplayerColorFromIndex(null),
avatar: null,
}
}

return {
initials: multiplayerInitialsFromName(normalizeMultiplayerName(collaborator.name)),
color: multiplayerColorFromIndex(collaborator.colorIndex),
avatar: collaborator.avatar,
}
}, [collabs, myUserId])
Expand All @@ -141,8 +137,6 @@ function useCommentBeingComposed(): TemporaryCommentIndicatorProps | null {

return {
position: location,
bgColor: collaboratorInfo.color.background,
fgColor: collaboratorInfo.color.foreground,
avatarUrl: collaboratorInfo.avatar,
initials: collaboratorInfo.initials,
}
Expand All @@ -161,8 +155,6 @@ const CommentIndicatorsInner = React.memo(() => {
<CommentIndicatorUI
position={temporaryIndicatorData.position}
resolved={false}
bgColor={temporaryIndicatorData.bgColor}
fgColor={temporaryIndicatorData.fgColor}
avatarUrl={temporaryIndicatorData.avatarUrl}
avatarInitials={temporaryIndicatorData.initials}
isActive={true}
Expand All @@ -177,8 +169,6 @@ CommentIndicatorsInner.displayName = 'CommentIndicatorInner'
interface CommentIndicatorUIProps {
position: CanvasPoint
resolved: boolean
bgColor: string
fgColor: string
avatarInitials: string
avatarUrl?: string | null
isActive: boolean
Expand Down Expand Up @@ -232,8 +222,7 @@ function useIndicatorStyle(
}

export const CommentIndicatorUI = React.memo<CommentIndicatorUIProps>((props) => {
const { position, bgColor, fgColor, avatarUrl, avatarInitials, resolved, isActive, isRead } =
props
const { position, avatarUrl, avatarInitials, resolved, isActive, isRead } = props

const style = useIndicatorStyle(position, {
isRead: isRead ?? true,
Expand All @@ -246,7 +235,7 @@ export const CommentIndicatorUI = React.memo<CommentIndicatorUIProps>((props) =>
return (
<div style={style}>
<MultiplayerAvatar
color={{ background: bgColor, foreground: fgColor }}
color={multiplayerColorFromIndex(null)}
picture={avatarUrl}
name={avatarInitials}
/>
Expand Down Expand Up @@ -347,10 +336,6 @@ const CommentIndicator = React.memo(({ thread }: CommentIndicatorProps) => {
],
)

// This is a hack: when the comment is unread, we show a dark background, so we need light foreground colors.
// So we trick the Liveblocks Comment component and lie to it that the theme is dark mode.
const dataThemeProp = isRead ? {} : { 'data-theme': 'dark' }

const style = useIndicatorStyle(dragPosition ?? location, {
isRead: isRead,
resolved: thread.metadata.resolved,
Expand All @@ -377,7 +362,7 @@ const CommentIndicator = React.memo(({ thread }: CommentIndicatorProps) => {
overflow: 'auto',
background: 'transparent',
}}
{...dataThemeProp}
forceDarkMode={!isRead}
/>
</div>
)
Expand Down Expand Up @@ -584,10 +569,11 @@ type CommentIndicatorWrapper = {
thread: ThreadData<ThreadMetadata>
user: UserMeta | null
expanded: boolean
forceDarkMode: boolean
} & CommentProps

const CommentIndicatorWrapper = React.memo((props: CommentIndicatorWrapper) => {
const { thread, expanded, user, ...commentProps } = props
const { thread, expanded, user, forceDarkMode, ...commentProps } = props

const [avatarRef, animateAvatar] = useAnimate()

Expand All @@ -606,8 +592,14 @@ const CommentIndicatorWrapper = React.memo((props: CommentIndicatorWrapper) => {
)
}, [expanded, avatarRef, animateAvatar])

// This is a hack: when the comment is unread, we show a dark background, so we need light foreground colors.
// So we trick the Liveblocks Comment component and lie to it that the theme is dark mode.
const updatedCommentProps = forceDarkMode
? { ...commentProps, 'data-theme': 'dark' }
: commentProps

if (user == null) {
return <Comment {...commentProps} />
return <Comment {...updatedCommentProps} />
}

return (
Expand All @@ -627,7 +619,7 @@ const CommentIndicatorWrapper = React.memo((props: CommentIndicatorWrapper) => {
>
<MultiplayerAvatar
name={multiplayerInitialsFromName(normalizeMultiplayerName(user.name))}
color={multiplayerColorFromIndex(user.colorIndex)}
color={multiplayerColorFromIndex(null)}
picture={user.avatar}
style={{ outline: 'none' }}
/>
Expand Down Expand Up @@ -655,8 +647,8 @@ const CommentIndicatorWrapper = React.memo((props: CommentIndicatorWrapper) => {
}}
transition={{ duration: animDuration }}
>
<Comment {...commentProps} />
<CommentRepliesCounter thread={thread} />
<Comment {...updatedCommentProps} />
<CommentRepliesCounter thread={thread} forceDarkMode={forceDarkMode} />
</motion.div>,
)}
</AnimatePresence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,39 @@ import React from 'react'
import type { ThreadData } from '@liveblocks/client'
import type { ThreadMetadata } from '../../../../liveblocks.config'
import { useColorTheme } from '../../../uuiui'
import { darkColorThemeCssVariables } from '../../../uuiui/styles/theme/utopia-theme'
import { dark } from '../../../uuiui/styles/theme/dark'
import { useTheme } from '@emotion/react'
import { Substores, useEditorState } from '../../editor/store/store-hook'
import { getCurrentTheme } from '../../editor/store/editor-state'

interface CommentRepliesCounterProps {
thread: ThreadData<ThreadMetadata>
forceDarkMode?: boolean
}

export const CommentRepliesCounter = React.memo((props: CommentRepliesCounterProps) => {
const colorTheme = useColorTheme()

const theme = useEditorState(
Substores.userState,
(store) => getCurrentTheme(store.userState),
'CommentRepliesCounter theme',
)

const color = React.useMemo(() => {
// If we don't force dark mode because of a blue background, we can just use foreground color
if (!props.forceDarkMode) {
return colorTheme.fg6.value
}
// In dark mode we need a lighter foreground which is visible well on blue background
if (theme === 'dark') {
return colorTheme.fg2.value
}
// In light mode we need a light background color, so it is visible on blue background
return colorTheme.bg3.value
}, [colorTheme, theme, props.forceDarkMode])

const repliesCount = props.thread.comments.filter((c) => c.deletedAt == null).length - 1

if (repliesCount <= 0) {
Expand All @@ -21,7 +46,7 @@ export const CommentRepliesCounter = React.memo((props: CommentRepliesCounterPro
style={{
paddingLeft: 44,
fontSize: 9,
color: colorTheme.fg6.value,
color: color,
marginBottom: 8,
}}
>
Expand Down
36 changes: 28 additions & 8 deletions editor/src/components/canvas/multiplayer-presence.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import {
} from '../../../liveblocks.config'
import {
getCollaborator,
getConnectionById,
useAddMyselfToCollaborators,
useCanComment,
useMyUserAndPresence,
useConnections,
} from '../../core/commenting/comment-hooks'
import { MetadataUtils } from '../../core/model/element-metadata-utils'
import { mapDropNulls } from '../../core/shared/array-utils'
Expand All @@ -32,7 +34,9 @@ import {
windowPoint,
zeroRectIfNullOrInfinity,
} from '../../core/shared/math-utils'
import type { MultiplayerColor } from '../../core/shared/multiplayer'
import {
excludeMyConnection,
isPlayerOnAnotherRemixRoute,
multiplayerColorFromIndex,
normalizeOthersList,
Expand Down Expand Up @@ -173,13 +177,15 @@ const MultiplayerCursors = React.memo(() => {
const me = useSelf()
const collabs = useStorage((store) => store.collaborators)
const others = useOthers((list) => {
const presences = normalizeOthersList(me.id, list)
const presences = excludeMyConnection(me.id, me.connectionId, list)
return presences.map((p) => ({
presenceInfo: p,
userInfo: getCollaborator(collabs, p),
}))
})

const connections = useConnections()

return (
<div
style={{
Expand All @@ -206,7 +212,10 @@ const MultiplayerCursors = React.memo(() => {
<MultiplayerCursor
key={`cursor-${other.presenceInfo.id}`}
name={other.userInfo.name}
colorIndex={other.userInfo.colorIndex}
colorIndex={
getConnectionById(connections, other.userInfo.id, other.presenceInfo.connectionId)
?.colorIndex ?? null
}
position={position}
userId={other.userInfo.id}
/>
Expand Down Expand Up @@ -433,12 +442,19 @@ const FollowingOverlay = React.memo(() => {
dispatch([switchEditorMode(EditorModes.selectMode(null, false, 'none'))])
}, [dispatch])

const followedUserColor = React.useMemo(() => {
return multiplayerColorFromIndex(followedUser?.colorIndex ?? null)
}, [followedUser])
const connections = useConnections()

const followedUserColor: MultiplayerColor = React.useMemo(() => {
if (followed == null) {
return multiplayerColorFromIndex(null)
} else {
return multiplayerColorFromIndex(
getConnectionById(connections, followed.id, followed.connectionId)?.colorIndex ?? null,
)
}
}, [connections, followed])

const collabs = useStorage((store) => store.collaborators)
const connections = useStorage((store) => store.connections)

const { user: myUser, presence: myPresence } = useMyUserAndPresence()
const others = useOthers((list) =>
Expand Down Expand Up @@ -564,15 +580,19 @@ const MultiplayerShadows = React.memo(() => {
}))
})

const connections = useConnections()

const shadows = React.useMemo(() => {
return others.flatMap(
(other) =>
other.presenceInfo.presence.activeFrames?.map((activeFrame) => ({
activeFrame: activeFrame,
colorIndex: other.userInfo.colorIndex,
colorIndex:
getConnectionById(connections, other.userInfo.id, other.presenceInfo.connectionId)
?.colorIndex ?? null,
})) ?? [],
)
}, [others])
}, [connections, others])

const myActiveFrames = useEditorState(
Substores.restOfEditor,
Expand Down
Loading

0 comments on commit e18c805

Please sign in to comment.