1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import { useAppDispatch } from '$app/stores/store';
- import React, { useCallback, useEffect, useMemo } from 'react';
- import { slashCommandActions } from '$app_reducers/document/slice';
- import { useSubscribeNode } from '$app/components/document/_shared/SubscribeNode.hooks';
- import { Op } from 'quill-delta';
- import { useSubscribeDocument } from '$app/components/document/_shared/SubscribeDoc.hooks';
- import { useSubscribeSlashState } from '$app/components/document/_shared/SubscribeSlash.hooks';
- export function useBlockSlash() {
- const dispatch = useAppDispatch();
- const { docId } = useSubscribeDocument();
- const { blockId, visible, slashText, hoverOption } = useSubscribeSlash();
- const [anchorPosition, setAnchorPosition] = React.useState<{
- top: number;
- left: number;
- }>();
- useEffect(() => {
- if (blockId && visible) {
- const blockEl = document.querySelector(`[data-block-id="${blockId}"]`) as HTMLElement;
- const el = blockEl.querySelector(`[role="textbox"]`) as HTMLElement;
- if (el) {
- const rect = el.getBoundingClientRect();
- setAnchorPosition({
- top: rect.top + rect.height,
- left: rect.left,
- });
- return;
- }
- }
- setAnchorPosition(undefined);
- }, [blockId, visible]);
- useEffect(() => {
- if (!slashText) {
- dispatch(slashCommandActions.closeSlashCommand(docId));
- }
- }, [dispatch, docId, slashText]);
- const searchText = useMemo(() => {
- if (!slashText) return '';
- if (slashText[0] !== '/') return slashText;
- return slashText.slice(1, slashText.length);
- }, [slashText]);
- const onClose = useCallback(() => {
- dispatch(slashCommandActions.closeSlashCommand(docId));
- }, [dispatch, docId]);
- const open = Boolean(anchorPosition);
- return {
- open,
- anchorPosition,
- onClose,
- blockId,
- searchText,
- hoverOption,
- };
- }
- export function useSubscribeSlash() {
- const slashCommandState = useSubscribeSlashState();
- const visible = slashCommandState.isSlashCommand;
- const blockId = slashCommandState.blockId;
- const { node } = useSubscribeNode(blockId || '');
- const slashText = useMemo(() => {
- if (!node) return '';
- const delta = node.data.delta || [];
- return delta
- .map((op: Op) => {
- if (typeof op.insert === 'string') {
- return op.insert;
- } else {
- return '';
- }
- })
- .join('');
- }, [node]);
- return {
- visible,
- blockId,
- slashText,
- hoverOption: slashCommandState.hoverOption,
- };
- }
|