47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
import React, { useCallback } from "react";
|
|
import { HighlightConfig, HighlightTarget } from "@/training/TrainingInterfaces";
|
|
|
|
interface HighlightedContentProps {
|
|
html: string;
|
|
highlightConfigs: HighlightConfig[];
|
|
contentType: HighlightTarget;
|
|
currentSegmentIndex?: number;
|
|
}
|
|
|
|
const HighlightedContent: React.FC<HighlightedContentProps> = ({
|
|
html,
|
|
highlightConfigs,
|
|
contentType,
|
|
currentSegmentIndex
|
|
}) => {
|
|
const createHighlightedContent = useCallback(() => {
|
|
let highlightedHtml = html;
|
|
highlightConfigs.forEach(config => {
|
|
if (config.targets.includes(contentType) || config.targets.includes('all')) {
|
|
const escapeRegExp = (string: string) => {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
};
|
|
|
|
const regex = new RegExp(config.phrases.map(escapeRegExp).join('|'), 'g');
|
|
|
|
if (contentType === 'segment' && currentSegmentIndex !== undefined) {
|
|
const segments = highlightedHtml.split('</div>');
|
|
segments[currentSegmentIndex] = segments[currentSegmentIndex].replace(regex, (match) => {
|
|
return `<span style="background-color: #FFFACD;">${match}</span>`;
|
|
});
|
|
highlightedHtml = segments.join('</div>');
|
|
} else {
|
|
highlightedHtml = highlightedHtml.replace(regex, (match) => {
|
|
return `<span style="background-color: #FFFACD;">${match}</span>`;
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
return { __html: highlightedHtml };
|
|
}, [html, highlightConfigs, contentType, currentSegmentIndex]);
|
|
|
|
return <div dangerouslySetInnerHTML={createHighlightedContent()} />;
|
|
};
|
|
|
|
export default HighlightedContent; |