add display/hide collaborator cursors

This commit is contained in:
hjlarry 2025-09-23 17:32:23 +08:00
parent f49476a206
commit 05a67f4716
5 changed files with 41 additions and 3 deletions

View File

@ -0,0 +1,11 @@
import { create } from 'zustand'
type UserCursorsState = {
showUserCursors: boolean
toggleUserCursors: () => void
}
export const useUserCursorsState = create<UserCursorsState>(set => ({
showUserCursors: true,
toggleUserCursors: () => set(state => ({ showUserCursors: !state.showUserCursors })),
}))

View File

@ -13,6 +13,7 @@ import { WorkflowWithInnerContext } from '@/app/components/workflow'
import type { WorkflowProps } from '@/app/components/workflow'
import WorkflowChildren from './workflow-children'
import UserCursors from '@/app/components/workflow/collaboration/components/user-cursors'
import { useUserCursorsState } from './user-cursors-state'
import {
useAvailableNodesMetaData,
@ -46,8 +47,9 @@ const WorkflowMain = ({
const reactFlow = useReactFlow()
const store = useStoreApi()
const { startCursorTracking, stopCursorTracking, onlineUsers, cursors, isConnected } = useCollaboration(appId, store)
const { startCursorTracking, stopCursorTracking, onlineUsers, cursors, isConnected } = useCollaboration(appId || '', store)
const [myUserId, setMyUserId] = useState<string | null>(null)
const { showUserCursors } = useUserCursorsState()
useEffect(() => {
if (isConnected)
@ -300,7 +302,7 @@ const WorkflowMain = ({
>
<WorkflowChildren />
</WorkflowWithInnerContext>
<UserCursors cursors={filteredCursors} myUserId={myUserId} onlineUsers={onlineUsers} />
<UserCursors cursors={showUserCursors ? filteredCursors : {}} myUserId={myUserId} onlineUsers={onlineUsers} />
</div>
)
}

View File

@ -5,6 +5,7 @@ import ZoomInOut from './zoom-in-out'
import VariableTrigger from '../variable-inspect/trigger'
import VariableInspectPanel from '../variable-inspect'
import { useStore } from '../store'
import { useUserCursorsState } from '@/app/components/workflow-app/components/user-cursors-state'
export type OperatorProps = {
handleUndo: () => void
@ -14,6 +15,7 @@ export type OperatorProps = {
const Operator = ({ handleUndo, handleRedo }: OperatorProps) => {
const bottomPanelRef = useRef<HTMLDivElement>(null)
const [showMiniMap, setShowMiniMap] = useState(true)
const { showUserCursors, toggleUserCursors } = useUserCursorsState()
const handleToggleMiniMap = useCallback(() => {
setShowMiniMap(prev => !prev)
@ -79,6 +81,8 @@ const Operator = ({ handleUndo, handleRedo }: OperatorProps) => {
<ZoomInOut
showMiniMap={showMiniMap}
onToggleMiniMap={handleToggleMiniMap}
showUserCursors={showUserCursors}
onToggleUserCursors={toggleUserCursors}
/>
</div>
</div>

View File

@ -39,17 +39,22 @@ enum ZoomType {
zoomTo75 = 'zoomTo75',
zoomTo100 = 'zoomTo100',
zoomTo200 = 'zoomTo200',
toggleUserCursors = 'toggleUserCursors',
toggleMiniMap = 'toggleMiniMap',
}
type ZoomInOutProps = {
showMiniMap?: boolean
onToggleMiniMap?: () => void
showUserCursors?: boolean
onToggleUserCursors?: () => void
}
const ZoomInOut: FC<ZoomInOutProps> = ({
showMiniMap = true,
onToggleMiniMap,
showUserCursors = true,
onToggleUserCursors,
}) => {
const { t } = useTranslation()
const {
@ -94,6 +99,10 @@ const ZoomInOut: FC<ZoomInOutProps> = ({
},
],
[
{
key: ZoomType.toggleUserCursors,
text: t('workflow.operator.showUserCursors'),
},
{
key: ZoomType.toggleMiniMap,
text: t('workflow.operator.showMiniMap'),
@ -123,6 +132,11 @@ const ZoomInOut: FC<ZoomInOutProps> = ({
if (type === ZoomType.zoomTo200)
zoomTo(2)
if (type === ZoomType.toggleUserCursors) {
onToggleUserCursors?.()
return
}
if (type === ZoomType.toggleMiniMap) {
onToggleMiniMap?.()
return
@ -211,10 +225,16 @@ const ZoomInOut: FC<ZoomInOutProps> = ({
options.map(option => (
<div
key={option.key}
className='system-md-regular flex h-8 cursor-pointer items-center justify-between space-x-1 rounded-lg py-1.5 pl-3 pr-2 text-text-secondary hover:bg-state-base-hover'
className='system-md-regular flex h-8 cursor-pointer items-center justify-between space-x-1 rounded-lg px-2 py-1.5 text-text-secondary hover:bg-state-base-hover'
onClick={() => handleZoom(option.key)}
>
<div className='flex items-center space-x-2'>
{option.key === ZoomType.toggleUserCursors && showUserCursors && (
<RiCheckLine className='h-4 w-4 text-text-primary' />
)}
{option.key === ZoomType.toggleUserCursors && !showUserCursors && (
<div className='h-4 w-4' />
)}
{option.key === ZoomType.toggleMiniMap && showMiniMap && (
<RiCheckLine className='h-4 w-4 text-text-primary' />
)}

View File

@ -326,6 +326,7 @@ const translation = {
zoomTo50: 'Zoom to 50%',
zoomTo100: 'Zoom to 100%',
zoomToFit: 'Zoom to Fit',
showUserCursors: 'Collaborator cursors',
showMiniMap: 'Minimap',
alignNodes: 'Align Nodes',
alignLeft: 'Left',