forked from 77media/video-flow
修复角色输入框遇到特殊角色描述导致页面崩溃问题
This commit is contained in:
parent
5c049fe964
commit
3c5f2f6fe1
@ -131,36 +131,45 @@ export class TextToShotAdapter {
|
|||||||
public static parseHighlight(text: string, tags: TagValueObject[]): ContentNode[] {
|
public static parseHighlight(text: string, tags: TagValueObject[]): ContentNode[] {
|
||||||
const nodes: ContentNode[] = [];
|
const nodes: ContentNode[] = [];
|
||||||
let currentText = text;
|
let currentText = text;
|
||||||
// 按内容长度降序排序,避免短名称匹配到长名称的一部分
|
|
||||||
const sortedTags = [...tags].sort((a, b) => String(b.content).length - String(a.content).length);
|
// 1. 确保 tags 是有效的数组
|
||||||
|
if (!Array.isArray(tags)) {
|
||||||
while (currentText.length > 0) {
|
console.warn('Invalid tags:', tags);
|
||||||
|
return [{ type: 'text', text: currentText }];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 恢复排序逻辑,并添加安全检查
|
||||||
|
const sortedTags = [...tags]
|
||||||
|
.filter(tag => tag && tag.content) // 过滤无效的 tag
|
||||||
|
.sort((a, b) => String(b.content).length - String(a.content).length);
|
||||||
|
|
||||||
|
// 3. 添加安全检查,防止无限循环
|
||||||
|
let iterationCount = 0;
|
||||||
|
const MAX_ITERATIONS = 1000; // 设置一个合理的最大迭代次数
|
||||||
|
|
||||||
|
while (currentText.length > 0 && iterationCount < MAX_ITERATIONS) {
|
||||||
|
iterationCount++;
|
||||||
let matchFound = false;
|
let matchFound = false;
|
||||||
|
|
||||||
// 尝试匹配
|
|
||||||
for (const tag of sortedTags) {
|
for (const tag of sortedTags) {
|
||||||
if (currentText.startsWith(String(tag.content))) {
|
const tagContent = String(tag.content);
|
||||||
// 如果当前文本以tag内容开头
|
if (currentText.startsWith(tagContent)) {
|
||||||
if (currentText.length > String(tag.content).length) {
|
if (currentText.length > tagContent.length) {
|
||||||
// 添加标记节点
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
type: 'highlightText',
|
type: 'highlightText',
|
||||||
attrs: {
|
attrs: {
|
||||||
text: String(tag.content),
|
text: tagContent,
|
||||||
color: tag?.color || 'yellow'
|
color: tag?.color || 'yellow'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 移除已处理的tag内容
|
currentText = currentText.slice(tagContent.length);
|
||||||
currentText = currentText.slice(String(tag.content).length);
|
|
||||||
matchFound = true;
|
matchFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matchFound) {
|
if (!matchFound) {
|
||||||
// 如果没有找到tag匹配,处理普通文本
|
|
||||||
// 查找下一个可能的tag内容位置
|
|
||||||
let nextTagIndex = currentText.length;
|
let nextTagIndex = currentText.length;
|
||||||
for (const tag of sortedTags) {
|
for (const tag of sortedTags) {
|
||||||
const index = currentText.indexOf(String(tag.content));
|
const index = currentText.indexOf(String(tag.content));
|
||||||
@ -168,8 +177,7 @@ export class TextToShotAdapter {
|
|||||||
nextTagIndex = index;
|
nextTagIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加文本节点
|
|
||||||
const textContent = currentText.slice(0, nextTagIndex);
|
const textContent = currentText.slice(0, nextTagIndex);
|
||||||
if (textContent) {
|
if (textContent) {
|
||||||
nodes.push({
|
nodes.push({
|
||||||
@ -177,11 +185,18 @@ export class TextToShotAdapter {
|
|||||||
text: textContent
|
text: textContent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 移除已处理的文本
|
|
||||||
currentText = currentText.slice(nextTagIndex);
|
currentText = currentText.slice(nextTagIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. 如果达到最大迭代次数,处理剩余文本
|
||||||
|
if (currentText.length > 0) {
|
||||||
|
nodes.push({
|
||||||
|
type: 'text',
|
||||||
|
text: currentText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
private readonly ShotData: Shot;
|
private readonly ShotData: Shot;
|
||||||
|
|||||||
@ -46,11 +46,18 @@ export const CharacterEditor = forwardRef<any, CharacterEditorProps>(({
|
|||||||
const paragraphs = TextToShotAdapter.fromTextToRole(description, highlight);
|
const paragraphs = TextToShotAdapter.fromTextToRole(description, highlight);
|
||||||
console.log('-==========paragraphs===========-', paragraphs);
|
console.log('-==========paragraphs===========-', paragraphs);
|
||||||
setContent(paragraphs);
|
setContent(paragraphs);
|
||||||
setTimeout(() => {
|
|
||||||
|
// 保存定时器ID
|
||||||
|
const timerId = setTimeout(() => {
|
||||||
setIsInit(false);
|
setIsInit(false);
|
||||||
setIsOptimizing(false);
|
setIsOptimizing(false);
|
||||||
}, 100);
|
}, 100);
|
||||||
}, [highlight]);
|
|
||||||
|
// 清理函数:组件卸载时清理定时器
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timerId);
|
||||||
|
};
|
||||||
|
}, [description]);
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
React.useImperativeHandle(ref, () => ({
|
React.useImperativeHandle(ref, () => ({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user