Changeset View
Changeset View
Standalone View
Standalone View
web/utils/tooltip-action-utils.js
// @flow | // @flow | ||||
import invariant from 'invariant'; | import invariant from 'invariant'; | ||||
import _debounce from 'lodash/debounce.js'; | import _debounce from 'lodash/debounce.js'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { useModalContext } from 'lib/components/modal-provider.react.js'; | import { useModalContext } from 'lib/components/modal-provider.react.js'; | ||||
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; | |||||
import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; | import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js'; | ||||
import { useCanEditMessage } from 'lib/shared/edit-messages-utils.js'; | |||||
import { createMessageReply } from 'lib/shared/message-utils.js'; | import { createMessageReply } from 'lib/shared/message-utils.js'; | ||||
import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; | import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils.js'; | ||||
import { | import { | ||||
threadHasPermission, | threadHasPermission, | ||||
useSidebarExistsOrCanBeCreated, | useSidebarExistsOrCanBeCreated, | ||||
} from 'lib/shared/thread-utils.js'; | } from 'lib/shared/thread-utils.js'; | ||||
import { messageTypes } from 'lib/types/message-types-enum.js'; | import { messageTypes } from 'lib/types/message-types-enum.js'; | ||||
import { isComposableMessageType } from 'lib/types/message-types.js'; | import { isComposableMessageType } from 'lib/types/message-types.js'; | ||||
import { threadPermissions } from 'lib/types/thread-permission-types.js'; | import { threadPermissions } from 'lib/types/thread-permission-types.js'; | ||||
import type { ThreadInfo } from 'lib/types/thread-types.js'; | import type { ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import { longAbsoluteDate } from 'lib/utils/date-utils.js'; | import { longAbsoluteDate } from 'lib/utils/date-utils.js'; | ||||
import { | import { | ||||
type MessageTooltipAction, | type MessageTooltipAction, | ||||
findTooltipPosition, | findTooltipPosition, | ||||
getMessageActionTooltipStyle, | getMessageActionTooltipStyle, | ||||
calculateTooltipSize, | calculateTooltipSize, | ||||
type TooltipSize, | type TooltipSize, | ||||
type TooltipPosition, | type TooltipPosition, | ||||
} from './tooltip-utils.js'; | } from './tooltip-utils.js'; | ||||
import { useEditModalContext } from '../chat/edit-message-provider.js'; | |||||
import MessageTooltip from '../chat/message-tooltip.react.js'; | import MessageTooltip from '../chat/message-tooltip.react.js'; | ||||
import type { PositionInfo } from '../chat/position-types.js'; | import type { PositionInfo } from '../chat/position-types.js'; | ||||
import { useTooltipContext } from '../chat/tooltip-provider.js'; | import { useTooltipContext } from '../chat/tooltip-provider.js'; | ||||
import CommIcon from '../CommIcon.react.js'; | import CommIcon from '../CommIcon.react.js'; | ||||
import { InputStateContext } from '../input/input-state.js'; | import { InputStateContext } from '../input/input-state.js'; | ||||
import TogglePinModal from '../modals/chat/toggle-pin-modal.react.js'; | import TogglePinModal from '../modals/chat/toggle-pin-modal.react.js'; | ||||
import { | import { | ||||
useOnClickPendingSidebar, | useOnClickPendingSidebar, | ||||
▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | return React.useMemo(() => { | ||||
return { | return { | ||||
actionButtonContent: buttonContent, | actionButtonContent: buttonContent, | ||||
onClick: onClickTogglePin, | onClick: onClickTogglePin, | ||||
label: isPinned ? 'Unpin' : 'Pin', | label: isPinned ? 'Unpin' : 'Pin', | ||||
}; | }; | ||||
}, [canTogglePin, inputState, isPinned, pushModal, item, threadInfo]); | }, [canTogglePin, inputState, isPinned, pushModal, item, threadInfo]); | ||||
} | } | ||||
function useMessageEditAction( | |||||
item: ChatMessageInfoItem, | |||||
threadInfo: ThreadInfo, | |||||
): ?MessageTooltipAction { | |||||
const { messageInfo } = item; | |||||
const canEditMessage = useCanEditMessage(threadInfo, messageInfo); | |||||
const { renderEditModal } = useEditModalContext(); | |||||
const { clearTooltip } = useTooltipContext(); | |||||
return React.useMemo(() => { | |||||
if (!canEditMessage) { | |||||
return null; | |||||
} | |||||
const buttonContent = ( | |||||
<SWMansionIcon icon="edit-1" size={18} disableFill={false} /> | |||||
); | |||||
const onClickEdit = () => { | |||||
clearTooltip(); | |||||
renderEditModal({ | |||||
messageInfo: item, | |||||
threadInfo, | |||||
isError: false, | |||||
editedMessageDraft: messageInfo.text, | |||||
}); | |||||
}; | |||||
return { | |||||
actionButtonContent: buttonContent, | |||||
onClick: onClickEdit, | |||||
label: 'Edit', | |||||
}; | |||||
}, [ | |||||
canEditMessage, | |||||
clearTooltip, | |||||
item, | |||||
messageInfo.text, | |||||
renderEditModal, | |||||
threadInfo, | |||||
]); | |||||
} | |||||
function useMessageTooltipActions( | function useMessageTooltipActions( | ||||
item: ChatMessageInfoItem, | item: ChatMessageInfoItem, | ||||
threadInfo: ThreadInfo, | threadInfo: ThreadInfo, | ||||
): $ReadOnlyArray<MessageTooltipAction> { | ): $ReadOnlyArray<MessageTooltipAction> { | ||||
const sidebarAction = useMessageTooltipSidebarAction(item, threadInfo); | const sidebarAction = useMessageTooltipSidebarAction(item, threadInfo); | ||||
const replyAction = useMessageTooltipReplyAction(item, threadInfo); | const replyAction = useMessageTooltipReplyAction(item, threadInfo); | ||||
const copyAction = useMessageCopyAction(item); | const copyAction = useMessageCopyAction(item); | ||||
const reactAction = useMessageReactAction(item, threadInfo); | const reactAction = useMessageReactAction(item, threadInfo); | ||||
const togglePinAction = useMessageTogglePinAction(item, threadInfo); | const togglePinAction = useMessageTogglePinAction(item, threadInfo); | ||||
const editAction = useMessageEditAction(item, threadInfo); | |||||
return React.useMemo( | return React.useMemo( | ||||
() => | () => | ||||
[ | [ | ||||
replyAction, | replyAction, | ||||
sidebarAction, | sidebarAction, | ||||
copyAction, | copyAction, | ||||
reactAction, | reactAction, | ||||
togglePinAction, | togglePinAction, | ||||
editAction, | |||||
].filter(Boolean), | ].filter(Boolean), | ||||
[replyAction, sidebarAction, copyAction, reactAction, togglePinAction], | [ | ||||
replyAction, | |||||
sidebarAction, | |||||
copyAction, | |||||
reactAction, | |||||
togglePinAction, | |||||
editAction, | |||||
], | |||||
); | ); | ||||
} | } | ||||
type UseMessageTooltipArgs = { | type UseMessageTooltipArgs = { | ||||
+availablePositions: $ReadOnlyArray<TooltipPosition>, | +availablePositions: $ReadOnlyArray<TooltipPosition>, | ||||
+item: ChatMessageInfoItem, | +item: ChatMessageInfoItem, | ||||
+threadInfo: ThreadInfo, | +threadInfo: ThreadInfo, | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 187 Lines • Show Last 20 Lines |