Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
5.4 kB · 169 lines
TSX
at strict
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169import { ClientOnly, CodeBlock, IconButton } from "@chakra-ui/react";import { type ComponentProps, useMemo } from "react";import type { MarkOptional } from "ts-essentials";import { safeStringify } from "../../core/StringUtils";import { shikiAdapter } from "./shikiAdapter";
// const shikiAdapter = createShikiAdapter<HighlighterGeneric<any, any>>({// async load() {// const { createHighlighter } = await import("shiki")// return createHighlighter({// langs: ["json", "plaintext"],// themes: ["github-dark", "github-light"],// })// },// theme: {// light: "github-light",// dark: "github-dark",// },// });
export interface ChakraCodeBaseProps { language?: string title?: string maxHeight?: string maxLines?: number collapsedMaxHeight?: string}
export type ChakraCodelessBlock = Omit<ComponentProps<typeof CodeBlock.Root>, 'code'>
export type ChakraCodeBlockProps = Omit<ChakraCodelessBlock, 'children'> & ChakraCodeBaseProps & { code: string | object}
const DEFAULT_MAX_HEIGHT = '70vh', DEFAULT_COLLAPSED_MAX_HEIGHT = '320px', DEFAULT_LANGUAGE = 'json';
export const ChakraCodeBlock = (props: ChakraCodeBlockProps) => { const { maxHeight = DEFAULT_MAX_HEIGHT, maxLines, collapsedMaxHeight = DEFAULT_COLLAPSED_MAX_HEIGHT, language = DEFAULT_LANGUAGE, code = '', ...rest } = props;
const contentProps: ComponentProps<typeof CodeBlock.Content> = maxLines === undefined ? { maxHeight, overflowY: 'auto' } : { css: { "--code-block-max-height": collapsedMaxHeight } };
const codeVal = useMemo(() => { if (typeof code === 'string') { return code; } return safeStringify(code); }, [code]);
return ( <CodeBlock.AdapterProvider value={shikiAdapter}> <ClientOnly fallback={<div>Loading...</div>}> {() => ( <CodeBlock.Root code={codeVal} language={language ?? 'json'} maxLines={maxLines} meta={{ wordWrap: true }} {...rest} > <CodeBlock.Header> <CodeBlock.Title>{props.title ?? ' '}</CodeBlock.Title> <CodeBlock.Control> <CodeBlock.CollapseTrigger asChild> <IconButton variant="ghost" size="2xs"> <CodeBlock.CollapseIndicator /> </IconButton> </CodeBlock.CollapseTrigger> <CodeBlock.CopyTrigger asChild> <IconButton variant="ghost" size="2xs"> <CodeBlock.CopyIndicator /> </IconButton> </CodeBlock.CopyTrigger> </CodeBlock.Control> </CodeBlock.Header> <CodeBlock.Content {...contentProps}> <CodeBlock.Code> <CodeBlock.CodeText /> </CodeBlock.Code>
<CodeBlock.Overlay> <CodeBlock.CollapseTrigger> <CodeBlock.CollapseText textStyle="sm" /> </CodeBlock.CollapseTrigger> </CodeBlock.Overlay> </CodeBlock.Content> </CodeBlock.Root> )} </ClientOnly> </CodeBlock.AdapterProvider> )}
export const ChakraCodeBlockShort = (props: ChakraCodeBlockProps) => <ChakraCodeBlock maxLines={6} collapsedMaxHeight="10em" hideBelow="sm" {...props} />;
export type ChakraPlainBlockProps = MarkOptional<ChakraCodelessBlock, 'children'> & ChakraCodeBaseProps & {code?: string | object};
export const ChakraPlainBlock = (props: ChakraPlainBlockProps) => { const { maxHeight = DEFAULT_MAX_HEIGHT, maxLines, collapsedMaxHeight = DEFAULT_COLLAPSED_MAX_HEIGHT, code, ...rest } = props;
const contentProps: ComponentProps<typeof CodeBlock.Content> = maxLines === undefined ? { maxHeight, overflowY: 'auto' } : { css: { "--code-block-max-height": collapsedMaxHeight } };
const codeVal = useMemo(() => { if(code === undefined) { return ' '; } if (typeof code === 'string') { return code; } return safeStringify(code); }, [code]);
let header: React.JSX.Element | null; if(props.title === undefined && maxLines === undefined) { header = null; } else { header = ( <CodeBlock.Header> <CodeBlock.Title>{props.title}</CodeBlock.Title> <CodeBlock.Control> {maxLines !== undefined ? ( <CodeBlock.CollapseTrigger asChild> <IconButton variant="ghost" size="2xs"> <CodeBlock.CollapseIndicator /> </IconButton> </CodeBlock.CollapseTrigger> ) : null} </CodeBlock.Control> </CodeBlock.Header> ); }
return ( <CodeBlock.Root code={codeVal} language="plaintext" maxLines={maxLines} {...rest} > {header} <CodeBlock.Content {...contentProps}> <CodeBlock.Code> {props.children ?? <CodeBlock.CodeText />} </CodeBlock.Code> <CodeBlock.Overlay> <CodeBlock.CollapseTrigger> <CodeBlock.CollapseText textStyle="sm" /> </CodeBlock.CollapseTrigger> </CodeBlock.Overlay> </CodeBlock.Content> </CodeBlock.Root> );}
export const ChakraPlainBlockShort = (props: ChakraPlainBlockProps) => <ChakraPlainBlock maxLines={6} collapsedMaxHeight="10em" hideBelow="sm" {...props} />;