All files / webview hooks.tsx

95.45% Statements 21/22
87.5% Branches 7/8
88.88% Functions 8/9
94.73% Lines 18/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                                16x 16x 16x   16x 8x 9x 8x 8x 8x       8x   8x     16x               12x   4x 4x 4x     3x               1x                
import { useState, useEffect, useMemo } from 'react';
import { resolveImageSrc } from '../src/utils';
import { getVsCodeApi } from './vscodeApi';
import { subscribe } from './messageBus';
import { useIsDark } from './ThemeContext';
 
export type FileType = 'markdown' | 'excalidraw' | 'csv';
 
export interface VsCodeMessage {
  type: string;
  content?: string;
  baseUri?: string;
  fileType?: FileType;
}
 
export function useVsCodeMessages() {
  const [content, setContent] = useState('');
  const [baseUri, setBaseUri] = useState('');
  const [fileType, setFileType] = useState<FileType>('markdown');
 
  useEffect(() => {
    const unsub = subscribe('update', (msg: VsCodeMessage) => {
      if (msg.content !== undefined) {
        setContent(msg.content);
        if (msg.baseUri) setBaseUri(msg.baseUri);
        if (msg.fileType) setFileType(msg.fileType);
      }
    });
 
    getVsCodeApi()?.postMessage({ type: 'ready' });
 
    return unsub;
  }, []);
 
  return { content, baseUri, fileType };
}
 
export function useVsCodeTheme() {
  return useIsDark();
}
 
export function useMarkdownComponents(baseUri: string) {
  return useMemo(() => ({
    img: (props: React.ImgHTMLAttributes<HTMLImageElement>) => {
      const src = resolveImageSrc(props.src || '', baseUri);
      const { src: _original, ...rest } = props;
      return <img {...rest} src={src} loading="lazy" />;
    },
    a: (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => (
      <a
        {...props}
        className="markdown-link"
        target="_blank"
        rel="noopener noreferrer"
      />
    ),
    table: (props: React.TableHTMLAttributes<HTMLTableElement>) => (
      <div className="markdown-table-container">
        <div className="markdown-table-wrapper">
          <table className="markdown-table" {...props} />
        </div>
      </div>
    ),
  }), [baseUri]);
}