fix: paste text can not overwrite the selection
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: var(--ant-color-fill-secondary);
|
background-color: rgba(0, 0, 0, 30%);
|
||||||
|
|
||||||
.ant-progress-text {
|
.ant-progress-text {
|
||||||
color: var(--color-white-secondary);
|
color: var(--color-white-secondary);
|
||||||
|
|||||||
@@ -490,22 +490,20 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
|
|||||||
await drawImage();
|
await drawImage();
|
||||||
setImgLoaded(true);
|
setImgLoaded(true);
|
||||||
console.log('Image Loaded:', imageStatus, strokesRef.current);
|
console.log('Image Loaded:', imageStatus, strokesRef.current);
|
||||||
// if (strokeCache.current[imguid]) {
|
if (strokeCache.current[imguid]) {
|
||||||
// strokesRef.current = strokeCache.current[imguid];
|
strokeCache.current[preImguid.current] = strokesRef.current;
|
||||||
// } else if (preImguid.current !== imguid) {
|
strokesRef.current = strokeCache.current[imguid];
|
||||||
// strokeCache.current[preImguid.current] = strokesRef.current;
|
} else if (preImguid.current !== imguid) {
|
||||||
// onReset();
|
strokeCache.current[preImguid.current] = strokesRef.current;
|
||||||
// resetCanvas();
|
|
||||||
// preImguid.current = imguid;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (imageStatus.isOriginal) {
|
|
||||||
redrawStrokes(strokesRef.current, 'initialize');
|
|
||||||
} else if (imageStatus.isResetNeeded) {
|
|
||||||
onReset();
|
onReset();
|
||||||
resetCanvas();
|
resetCanvas();
|
||||||
}
|
}
|
||||||
}, [drawImage, onReset, redrawStrokes, imageStatus]);
|
preImguid.current = imguid;
|
||||||
|
|
||||||
|
if (strokesRef.current.length) {
|
||||||
|
redrawStrokes(strokesRef.current);
|
||||||
|
}
|
||||||
|
}, [drawImage, onReset, redrawStrokes, imguid, imageStatus]);
|
||||||
|
|
||||||
const updateZoom = (scaleChange: number, mouseX: number, mouseY: number) => {
|
const updateZoom = (scaleChange: number, mouseX: number, mouseY: number) => {
|
||||||
const newScale = _.round(autoScale.current + scaleChange, 2);
|
const newScale = _.round(autoScale.current + scaleChange, 2);
|
||||||
|
|||||||
@@ -13,10 +13,24 @@ interface SystemMessageProps {
|
|||||||
height?: number;
|
height?: number;
|
||||||
onChange: (e: any) => void;
|
onChange: (e: any) => void;
|
||||||
onPaste?: (e: any) => void;
|
onPaste?: (e: any) => void;
|
||||||
|
onSelect?: (data: {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
beforeText: string;
|
||||||
|
afterText: string;
|
||||||
|
}) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
||||||
const { value, onChange, style, label, placeholder, height = 46 } = props;
|
const {
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
onSelect,
|
||||||
|
style,
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
height = 46
|
||||||
|
} = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const rowTextAreaRef = React.useRef<any>(null);
|
const rowTextAreaRef = React.useRef<any>(null);
|
||||||
const [autoSize, setAutoSize] = useState<{
|
const [autoSize, setAutoSize] = useState<{
|
||||||
@@ -57,6 +71,21 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
props.onPaste?.(e);
|
props.onPaste?.(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOnSelect = (e: any) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const start = e.target.selectionStart;
|
||||||
|
const end = e.target.selectionEnd;
|
||||||
|
|
||||||
|
const beforeText = value.substring(0, start);
|
||||||
|
const afterText = value.substring(end, value.length);
|
||||||
|
onSelect?.({
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
beforeText,
|
||||||
|
afterText
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames('row-textarea', {
|
className={classNames('row-textarea', {
|
||||||
@@ -87,6 +116,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
onBlur={handleBlur}
|
onBlur={handleBlur}
|
||||||
allowClear={false}
|
allowClear={false}
|
||||||
onChange={handleOnChange}
|
onChange={handleOnChange}
|
||||||
|
onSelect={handleOnSelect}
|
||||||
onPaste={handleOnPaste}
|
onPaste={handleOnPaste}
|
||||||
></Input.TextArea>
|
></Input.TextArea>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { queryCatalogItemSpec } from '../apis';
|
|||||||
import {
|
import {
|
||||||
backendOptionsMap,
|
backendOptionsMap,
|
||||||
modelCategoriesMap,
|
modelCategoriesMap,
|
||||||
modelSourceMap,
|
|
||||||
sourceOptions
|
sourceOptions
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import { CatalogSpec, FormData, ListItem } from '../config/types';
|
import { CatalogSpec, FormData, ListItem } from '../config/types';
|
||||||
@@ -51,7 +50,7 @@ const quantiCapitMap: Record<string, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const defaultQuant = ['Q4_K_M'];
|
const defaultQuant = ['Q4_K_M'];
|
||||||
const EmbeddingRerankFirstQuant = ['FP16'];
|
const EmbeddingRerankFirstQuant = ['FP16', 'F16'];
|
||||||
const AddModal: React.FC<AddModalProps> = (props) => {
|
const AddModal: React.FC<AddModalProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
@@ -85,39 +84,9 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
|||||||
data.category === modelCategoriesMap.embedding ||
|
data.category === modelCategoriesMap.embedding ||
|
||||||
data.category === modelCategoriesMap.reranker
|
data.category === modelCategoriesMap.reranker
|
||||||
) {
|
) {
|
||||||
return EmbeddingRerankFirstQuant.includes(data.quantOption);
|
return EmbeddingRerankFirstQuant.includes(_.toUpper(data.quantOption));
|
||||||
}
|
}
|
||||||
return defaultQuant.includes(data.quantOption);
|
return defaultQuant.includes(_.toUpper(data.quantOption));
|
||||||
};
|
|
||||||
|
|
||||||
const getModelFile = (spec: CatalogSpec) => {
|
|
||||||
let modelInfo = {};
|
|
||||||
if (spec.source === modelSourceMap.huggingface_value) {
|
|
||||||
modelInfo = {
|
|
||||||
huggingface_repo_id: spec?.huggingface_repo_id,
|
|
||||||
huggingface_filename: spec?.huggingface_filename
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spec.source === modelSourceMap.modelscope_value) {
|
|
||||||
modelInfo = {
|
|
||||||
model_scope_model_id: spec?.model_scope_model_id,
|
|
||||||
model_scope_file_path: spec?.model_scope_file_path
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spec.source === modelSourceMap.ollama_library_value) {
|
|
||||||
modelInfo = {
|
|
||||||
ollama_library_model_name: spec?.ollama_library_model_name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spec.source === modelSourceMap.local_path_value) {
|
|
||||||
modelInfo = {
|
|
||||||
local_path: spec?.local_path
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return modelInfo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getModelSpec = (data: {
|
const getModelSpec = (data: {
|
||||||
@@ -190,7 +159,8 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
|||||||
|
|
||||||
const quantizationList = _.map(sizeGroup, (item: CatalogSpec) => {
|
const quantizationList = _.map(sizeGroup, (item: CatalogSpec) => {
|
||||||
return {
|
return {
|
||||||
label: quantiCapitMap[item.quantization] ?? item.quantization,
|
label:
|
||||||
|
quantiCapitMap[item.quantization] ?? _.toUpper(item.quantization),
|
||||||
value: item.quantization
|
value: item.quantization
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -304,9 +274,12 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
|||||||
return groupList[item.value];
|
return groupList[item.value];
|
||||||
});
|
});
|
||||||
|
|
||||||
const list72B = _.filter(res.items, (item: CatalogSpec) => {
|
const list72B =
|
||||||
return item.size === 72;
|
_.toLower(current.name) === 'qwen2.5'
|
||||||
});
|
? _.filter(res.items, (item: CatalogSpec) => {
|
||||||
|
return item.size === 72;
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
|
||||||
let defaultSpec: any = {};
|
let defaultSpec: any = {};
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
});
|
});
|
||||||
const [lessTwoInput, setLessTwoInput] = useState<boolean>(false);
|
const [lessTwoInput, setLessTwoInput] = useState<boolean>(false);
|
||||||
const multiplePasteEnable = useRef<boolean>(true);
|
const multiplePasteEnable = useRef<boolean>(true);
|
||||||
|
const selectionTextRef = useRef<any>(null);
|
||||||
|
|
||||||
const [textList, setTextList] = useState<
|
const [textList, setTextList] = useState<
|
||||||
{ text: string; uid: number | string; name: string }[]
|
{ text: string; uid: number | string; name: string }[]
|
||||||
@@ -303,6 +304,19 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
setTextList(list);
|
setTextList(list);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleonSelect = useCallback(
|
||||||
|
(data: {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
beforeText: string;
|
||||||
|
afterText: string;
|
||||||
|
index: number;
|
||||||
|
}) => {
|
||||||
|
selectionTextRef.current = data;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const handleOnPaste = useCallback(
|
const handleOnPaste = useCallback(
|
||||||
(e: any, index: number) => {
|
(e: any, index: number) => {
|
||||||
if (!multiplePasteEnable.current) return;
|
if (!multiplePasteEnable.current) return;
|
||||||
@@ -316,7 +330,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
name: ''
|
name: ''
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
dataLlist[0].text = currentContent + dataLlist[0].text;
|
dataLlist[0].text = `${selectionTextRef.current?.beforeText || ''}${dataLlist[0].text}${selectionTextRef.current?.afterText || ''}`;
|
||||||
const result = [
|
const result = [
|
||||||
...textList.slice(0, index),
|
...textList.slice(0, index),
|
||||||
...dataLlist,
|
...dataLlist,
|
||||||
@@ -527,6 +541,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
ref={inputListRef}
|
ref={inputListRef}
|
||||||
textList={textList}
|
textList={textList}
|
||||||
onChange={handleTextListChange}
|
onChange={handleTextListChange}
|
||||||
|
onSelect={handleonSelect}
|
||||||
onPaste={handleOnPaste}
|
onPaste={handleOnPaste}
|
||||||
></InputList>
|
></InputList>
|
||||||
<div style={{ marginTop: 8 }}>
|
<div style={{ marginTop: 8 }}>
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
]);
|
]);
|
||||||
const [sortIndexMap, setSortIndexMap] = useState<number[]>([]);
|
const [sortIndexMap, setSortIndexMap] = useState<number[]>([]);
|
||||||
const [queryValue, setQueryValue] = useState<string>('');
|
const [queryValue, setQueryValue] = useState<string>('');
|
||||||
|
const selectionTextRef = useRef<any>(null);
|
||||||
|
|
||||||
const { initialize, updateScrollerPosition: updateDocumentScrollerPosition } =
|
const { initialize, updateScrollerPosition: updateDocumentScrollerPosition } =
|
||||||
useOverlayScroller();
|
useOverlayScroller();
|
||||||
@@ -364,6 +365,19 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleonSelect = useCallback(
|
||||||
|
(data: {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
beforeText: string;
|
||||||
|
afterText: string;
|
||||||
|
index: number;
|
||||||
|
}) => {
|
||||||
|
selectionTextRef.current = data;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const handleOnPaste = useCallback(
|
const handleOnPaste = useCallback(
|
||||||
(e: any, index: number) => {
|
(e: any, index: number) => {
|
||||||
if (!multiplePasteEnable.current) return;
|
if (!multiplePasteEnable.current) return;
|
||||||
@@ -377,7 +391,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
name: ''
|
name: ''
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
dataLlist[0].text = currentContent + dataLlist[0].text;
|
dataLlist[0].text = `${selectionTextRef.current?.beforeText || ''}${dataLlist[0].text}${selectionTextRef.current?.afterText || ''}`;
|
||||||
const result = [
|
const result = [
|
||||||
...textList.slice(0, index),
|
...textList.slice(0, index),
|
||||||
...dataLlist,
|
...dataLlist,
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ interface InputListProps {
|
|||||||
onSort?: (
|
onSort?: (
|
||||||
textList: { text: string; uid: number | string; name: string }[]
|
textList: { text: string; uid: number | string; name: string }[]
|
||||||
) => void;
|
) => void;
|
||||||
|
onSelect?: (data: {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
beforeText: string;
|
||||||
|
afterText: string;
|
||||||
|
}) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputList: React.FC<InputListProps> = forwardRef(
|
const InputList: React.FC<InputListProps> = forwardRef(
|
||||||
@@ -44,7 +50,8 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
onSort,
|
onSort,
|
||||||
onChange,
|
onChange,
|
||||||
extra,
|
extra,
|
||||||
onPaste
|
onPaste,
|
||||||
|
onSelect
|
||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
@@ -244,6 +251,7 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
})}
|
})}
|
||||||
onChange={(e) => handleTextChange(e.target.value, text)}
|
onChange={(e) => handleTextChange(e.target.value, text)}
|
||||||
onPaste={(e) => onPaste?.(e, index)}
|
onPaste={(e) => onPaste?.(e, index)}
|
||||||
|
onSelect={(data) => onSelect?.({ ...data, index })}
|
||||||
></RowTextarea>
|
></RowTextarea>
|
||||||
</div>
|
</div>
|
||||||
<span className="btn-group">
|
<span className="btn-group">
|
||||||
|
|||||||
Reference in New Issue
Block a user