mirror of
https://github.com/infinilabs/coco-app.git
synced 2026-09-01 19:51:52 +02:00
chore: message icon update & message history (#239)
This commit is contained in:
@@ -554,6 +554,7 @@ const ChatAI = memo(
|
||||
...chat,
|
||||
messages: hits,
|
||||
};
|
||||
console.log("id_history2", updatedChat)
|
||||
setActiveChat(updatedChat);
|
||||
callback && callback(updatedChat)
|
||||
} catch (error) {
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface ISource {
|
||||
message?: any;
|
||||
title?: string;
|
||||
question?: string;
|
||||
details?: any[];
|
||||
}
|
||||
export interface Chat {
|
||||
_id: string;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { ChevronDown, ChevronUp, Loader, BadgeCheck } from "lucide-react";
|
||||
import { ChevronDown, ChevronUp, Loader } from "lucide-react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { IChunkData } from "@/components/Assistant/types";
|
||||
import ReadingIcon from "@/icons/Reading";
|
||||
|
||||
interface DeepReadeProps {
|
||||
Detail?: any;
|
||||
ChunkData?: IChunkData;
|
||||
}
|
||||
|
||||
export const DeepRead = ({ ChunkData }: DeepReadeProps) => {
|
||||
export const DeepRead = ({ Detail, ChunkData }: DeepReadeProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isThinkingExpanded, setIsThinkingExpanded] = useState(false);
|
||||
@@ -18,6 +20,12 @@ export const DeepRead = ({ ChunkData }: DeepReadeProps) => {
|
||||
|
||||
const [Data, setData] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!Detail?.description) return;
|
||||
setData(Detail?.description);
|
||||
setLoading(false);
|
||||
}, [Detail?.description]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ChunkData?.message_chunk) return;
|
||||
const timerID = setTimeout(() => {
|
||||
@@ -47,7 +55,7 @@ export const DeepRead = ({ ChunkData }: DeepReadeProps) => {
|
||||
}, [ChunkData?.message_chunk]);
|
||||
|
||||
// Must be after hooks !!!
|
||||
if (!ChunkData) return null;
|
||||
if (!ChunkData && !Detail) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-2 mb-3 w-full">
|
||||
@@ -64,7 +72,7 @@ export const DeepRead = ({ ChunkData }: DeepReadeProps) => {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<BadgeCheck className="w-4 h-4 text-[#38C200]" />
|
||||
<ReadingIcon className="w-4 h-4 text-[#38C200]" />
|
||||
<span className="text-xs text-[#999999]">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`, {
|
||||
count: Number(Data.length),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
Search,
|
||||
ChevronUp,
|
||||
ChevronDown,
|
||||
SquareArrowOutUpRight,
|
||||
@@ -10,8 +9,10 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { OpenURLWithBrowser } from "@/utils/index";
|
||||
import type { IChunkData } from "@/components/Assistant/types";
|
||||
import RetrieveIcon from "@/icons/Retrieve";
|
||||
|
||||
interface FetchSourceProps {
|
||||
Detail?: any;
|
||||
ChunkData?: IChunkData;
|
||||
}
|
||||
|
||||
@@ -32,13 +33,18 @@ interface ISourceData {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export const FetchSource = ({ ChunkData }: FetchSourceProps) => {
|
||||
export const FetchSource = ({ Detail, ChunkData }: FetchSourceProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [isSourceExpanded, setIsSourceExpanded] = useState(false);
|
||||
|
||||
const [total, setTotal] = useState(0);
|
||||
const [data, setData] = useState<ISourceData[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!Detail?.payload) return;
|
||||
setData(Detail?.payload);
|
||||
}, [Detail?.payload]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ChunkData?.message_chunk) return;
|
||||
|
||||
@@ -61,7 +67,7 @@ export const FetchSource = ({ ChunkData }: FetchSourceProps) => {
|
||||
}, [ChunkData?.message_chunk]);
|
||||
|
||||
// Must be after hooks !!!
|
||||
if (!ChunkData) return null;
|
||||
if (!ChunkData && !Detail) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -80,7 +86,7 @@ export const FetchSource = ({ ChunkData }: FetchSourceProps) => {
|
||||
}`}
|
||||
>
|
||||
<div className="flex-1 min-w-0 flex items-center gap-2">
|
||||
<Search className="w-4 h-4 text-[#38C200] flex-shrink-0" />
|
||||
<RetrieveIcon className="w-4 h-4 text-[#38C200] flex-shrink-0" />
|
||||
<span className="text-xs text-[#999999]">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`, {
|
||||
count: Number(total),
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ChevronDown, ChevronUp, Loader, BadgeCheck } from "lucide-react";
|
||||
import { ChevronDown, ChevronUp, Loader } from "lucide-react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { IChunkData } from "@/components/Assistant/types";
|
||||
import SelectionIcon from "@/icons/Selection";
|
||||
|
||||
interface PickSourceProps {
|
||||
Detail?: any;
|
||||
ChunkData?: IChunkData;
|
||||
}
|
||||
|
||||
@@ -14,7 +16,7 @@ interface IData {
|
||||
title: string;
|
||||
}
|
||||
|
||||
export const PickSource = ({ ChunkData }: PickSourceProps) => {
|
||||
export const PickSource = ({ Detail, ChunkData }: PickSourceProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isThinkingExpanded, setIsThinkingExpanded] = useState(false);
|
||||
@@ -24,6 +26,12 @@ export const PickSource = ({ ChunkData }: PickSourceProps) => {
|
||||
|
||||
const [Data, setData] = useState<IData[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!Detail?.payload) return;
|
||||
setData(Detail?.payload);
|
||||
setLoading(false)
|
||||
}, [Detail?.payload]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ChunkData?.message_chunk) return;
|
||||
|
||||
@@ -78,7 +86,7 @@ export const PickSource = ({ ChunkData }: PickSourceProps) => {
|
||||
}, [ChunkData?.message_chunk]);
|
||||
|
||||
// Must be after hooks !!!
|
||||
if (!ChunkData) return null;
|
||||
if (!ChunkData && !Detail) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-2 mb-3 w-full">
|
||||
@@ -95,7 +103,7 @@ export const PickSource = ({ ChunkData }: PickSourceProps) => {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<BadgeCheck className="w-4 h-4 text-[#38C200]" />
|
||||
<SelectionIcon className="w-4 h-4 text-[#38C200]" />
|
||||
<span className="text-xs text-[#999999]">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`, {
|
||||
count: Data?.length,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ChevronDown, ChevronUp, Loader, BadgeCheck } from "lucide-react";
|
||||
import { ChevronDown, ChevronUp, Loader } from "lucide-react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import type { IChunkData } from "@/components/Assistant/types";
|
||||
import UnderstandIcon from "@/icons/Understand";
|
||||
|
||||
interface QueryIntentProps {
|
||||
Detail?: any;
|
||||
ChunkData?: IChunkData;
|
||||
getSuggestion?: (suggestion: string[]) => void;
|
||||
}
|
||||
@@ -17,7 +19,11 @@ interface IQueryData {
|
||||
suggestion: string[];
|
||||
}
|
||||
|
||||
export const QueryIntent = ({ ChunkData, getSuggestion }: QueryIntentProps) => {
|
||||
export const QueryIntent = ({
|
||||
Detail,
|
||||
ChunkData,
|
||||
getSuggestion,
|
||||
}: QueryIntentProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isThinkingExpanded, setIsThinkingExpanded] = useState(false);
|
||||
@@ -27,6 +33,12 @@ export const QueryIntent = ({ ChunkData, getSuggestion }: QueryIntentProps) => {
|
||||
|
||||
const [Data, setData] = useState<IQueryData | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!Detail?.payload) return;
|
||||
setData(Detail?.payload);
|
||||
setLoading(false);
|
||||
}, [Detail?.payload]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ChunkData?.message_chunk) return;
|
||||
const timerID = setTimeout(() => {
|
||||
@@ -39,7 +51,7 @@ export const QueryIntent = ({ ChunkData, getSuggestion }: QueryIntentProps) => {
|
||||
const data = JSON.parse(jsonString);
|
||||
// console.log("QueryIntent", data);
|
||||
if (data?.suggestion && getSuggestion) {
|
||||
getSuggestion(data?.suggestion)
|
||||
getSuggestion(data?.suggestion);
|
||||
}
|
||||
setData(data);
|
||||
}
|
||||
@@ -62,7 +74,7 @@ export const QueryIntent = ({ ChunkData, getSuggestion }: QueryIntentProps) => {
|
||||
}, [ChunkData?.message_chunk]);
|
||||
|
||||
// Must be after hooks !!!
|
||||
if (!ChunkData) return null;
|
||||
if (!ChunkData && !Detail) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-2 mb-3 w-full">
|
||||
@@ -74,14 +86,14 @@ export const QueryIntent = ({ ChunkData, getSuggestion }: QueryIntentProps) => {
|
||||
<>
|
||||
<Loader className="w-4 h-4 animate-spin text-[#1990FF]" />
|
||||
<span className="text-xs text-[#999999] italic">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`)}
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type || Detail.type}`)}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<BadgeCheck className="w-4 h-4 text-[#38C200]" />
|
||||
<UnderstandIcon className="w-4 h-4 text-[#38C200]" />
|
||||
<span className="text-xs text-[#999999]">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`)}
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type || Detail.type}`)}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -5,16 +5,23 @@ import { useTranslation } from "react-i18next";
|
||||
import type { IChunkData } from "@/components/Assistant/types";
|
||||
|
||||
interface ThinkProps {
|
||||
Detail?: any;
|
||||
ChunkData?: IChunkData;
|
||||
}
|
||||
|
||||
export const Think = ({ ChunkData }: ThinkProps) => {
|
||||
export const Think = ({ Detail, ChunkData }: ThinkProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [isThinkingExpanded, setIsThinkingExpanded] = useState(true);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [Data, setData] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
if (!Detail?.description) return;
|
||||
setData(Detail?.description);
|
||||
setLoading(false);
|
||||
}, [Detail?.description]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ChunkData?.message_chunk) return;
|
||||
const timerID = setTimeout(() => {
|
||||
@@ -30,7 +37,7 @@ export const Think = ({ ChunkData }: ThinkProps) => {
|
||||
}, [ChunkData?.message_chunk, Data, loading]);
|
||||
|
||||
// Must be after hooks !!!
|
||||
if (!ChunkData) return null;
|
||||
if (!ChunkData && !Detail) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-2 mb-3 w-full">
|
||||
@@ -40,7 +47,7 @@ export const Think = ({ ChunkData }: ThinkProps) => {
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Brain className="w-4 h-4 animate-pulse text-[#999999]" />
|
||||
<Brain className="w-4 h-4 animate-pulse text-[#1990FF]" />
|
||||
<span className="text-xs text-[#999999] italic">
|
||||
{t(`assistant.message.steps.${ChunkData?.chunk_type}`)}
|
||||
</span>
|
||||
|
||||
@@ -39,6 +39,7 @@ export const ChatMessage = memo(function ChatMessage({
|
||||
|
||||
const isAssistant = message?._source?.type === "assistant";
|
||||
const messageContent = message?._source?.message || "";
|
||||
const details = message?._source?.details || [];
|
||||
const question = message?._source?.question || "";
|
||||
|
||||
const showActions =
|
||||
@@ -47,9 +48,8 @@ export const ChatMessage = memo(function ChatMessage({
|
||||
const [suggestion, setSuggestion] = useState<string[]>([]);
|
||||
|
||||
const getSuggestion = (suggestion: string[]) => {
|
||||
setSuggestion(suggestion)
|
||||
}
|
||||
|
||||
setSuggestion(suggestion);
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
if (!isAssistant) {
|
||||
@@ -62,11 +62,27 @@ export const ChatMessage = memo(function ChatMessage({
|
||||
|
||||
return (
|
||||
<>
|
||||
<QueryIntent ChunkData={query_intent} getSuggestion={getSuggestion}/>
|
||||
<FetchSource ChunkData={fetch_source} />
|
||||
<PickSource ChunkData={pick_source} />
|
||||
<DeepRead ChunkData={deep_read} />
|
||||
<Think ChunkData={think} />
|
||||
<QueryIntent
|
||||
Detail={details.find((item) => item.type === "query_intent")}
|
||||
ChunkData={query_intent}
|
||||
getSuggestion={getSuggestion}
|
||||
/>
|
||||
<FetchSource
|
||||
Detail={details.find((item) => item.type === "fetch_source")}
|
||||
ChunkData={fetch_source}
|
||||
/>
|
||||
<PickSource
|
||||
Detail={details.find((item) => item.type === "pick_source")}
|
||||
ChunkData={pick_source}
|
||||
/>
|
||||
<DeepRead
|
||||
Detail={details.find((item) => item.type === "deep_read")}
|
||||
ChunkData={deep_read}
|
||||
/>
|
||||
<Think
|
||||
Detail={details.find((item) => item.type === "think")}
|
||||
ChunkData={think}
|
||||
/>
|
||||
<Markdown
|
||||
content={messageContent || response?.message_chunk || ""}
|
||||
loading={isTyping}
|
||||
@@ -85,10 +101,12 @@ export const ChatMessage = memo(function ChatMessage({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!isTyping && <SuggestionList
|
||||
suggestions={suggestion}
|
||||
onSelect={(text) => onResend && onResend(text)}
|
||||
/>}
|
||||
{!isTyping && (
|
||||
<SuggestionList
|
||||
suggestions={suggestion}
|
||||
onSelect={(text) => onResend && onResend(text)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
104
src/icons/Reading.tsx
Normal file
104
src/icons/Reading.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import SVGWrap from "./SVGWrap";
|
||||
|
||||
export default function Reading(props: I.SVG) {
|
||||
return (
|
||||
<SVGWrap {...props} viewBox="0 0 16 16">
|
||||
<g
|
||||
id="deading"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<circle
|
||||
id="椭圆形"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="8"
|
||||
cy="3"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<circle
|
||||
id="椭圆形备份-2"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="3"
|
||||
cy="5"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<circle
|
||||
id="椭圆形备份-4"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="13"
|
||||
cy="5"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<circle
|
||||
id="椭圆形备份"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="8"
|
||||
cy="13"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<circle
|
||||
id="椭圆形备份-3"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="3"
|
||||
cy="11"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<circle
|
||||
id="椭圆形备份-5"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
cx="13"
|
||||
cy="11"
|
||||
r="1.375"
|
||||
></circle>
|
||||
<path
|
||||
d="M8.0070039,4.03345364 L8.0070039,8.50590493 L4.1923477,10.2855921"
|
||||
id="路径-13"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
></path>
|
||||
<line
|
||||
x1="11.7924093"
|
||||
y1="8.47550067"
|
||||
x2="8"
|
||||
y2="10.2754456"
|
||||
id="路径-13备份"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
transform="translate(9.8962, 9.3755) scale(-1, 1) translate(-9.8962, -9.3755)"
|
||||
></line>
|
||||
<path
|
||||
d="M4.17568738,4.53038288 L6.65384701,3.54050563 M9.35480875,3.53987819 L11.7283558,4.49062879"
|
||||
id="形状"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
></path>
|
||||
<line
|
||||
x1="3"
|
||||
y1="6.06946104"
|
||||
x2="3"
|
||||
y2="9.97988046"
|
||||
id="路径-14"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
></line>
|
||||
<line
|
||||
x1="13"
|
||||
y1="6.06946104"
|
||||
x2="13"
|
||||
y2="9.97988046"
|
||||
id="路径-14备份"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
></line>
|
||||
</g>
|
||||
</SVGWrap>
|
||||
);
|
||||
}
|
||||
37
src/icons/Retrieve.tsx
Normal file
37
src/icons/Retrieve.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import SVGWrap from "./SVGWrap";
|
||||
|
||||
export default function Retrieve(props: I.SVG) {
|
||||
return (
|
||||
<SVGWrap {...props} viewBox="0 0 16 16">
|
||||
<g
|
||||
id="Retrieve"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line
|
||||
x1="10.8977456"
|
||||
y1="14.5"
|
||||
x2="14"
|
||||
y2="10.9204757"
|
||||
id="路径"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
transform="translate(12.4489, 12.7102) scale(-1, 1) translate(-12.4489, -12.7102)"
|
||||
></line>
|
||||
<circle
|
||||
id="椭圆形"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
transform="translate(7.5, 7) scale(-1, 1) translate(-7.5, -7)"
|
||||
cx="7.5"
|
||||
cy="7"
|
||||
r="5"
|
||||
></circle>
|
||||
</g>
|
||||
</SVGWrap>
|
||||
);
|
||||
}
|
||||
108
src/icons/Selection.tsx
Normal file
108
src/icons/Selection.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import SVGWrap from "./SVGWrap";
|
||||
|
||||
export default function Selection(props: I.SVG) {
|
||||
return (
|
||||
<SVGWrap {...props} viewBox="0 0 16 16">
|
||||
<g
|
||||
id="selection"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g
|
||||
id="编组"
|
||||
transform="translate(1.4813, 1)"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
>
|
||||
<line
|
||||
x1="6.7986538"
|
||||
y1="2.8"
|
||||
x2="6.7986538"
|
||||
y2="2.07241631e-17"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
></line>
|
||||
<circle
|
||||
id="椭圆形"
|
||||
fill="#000000"
|
||||
cx="6.7986538"
|
||||
cy="6.72"
|
||||
r="1"
|
||||
></circle>
|
||||
<line
|
||||
x1="2.17440858e-17"
|
||||
y1="13.5186538"
|
||||
x2="4.62042688"
|
||||
y2="8.89822692"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
></line>
|
||||
<line
|
||||
x1="10.1008425"
|
||||
y1="4.16781133"
|
||||
x2="10.1008425"
|
||||
y2="2.66781133"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(10.1008, 3.4178) rotate(45) translate(-10.1008, -3.4178)"
|
||||
></line>
|
||||
<line
|
||||
x1="12.1186538"
|
||||
y1="8.12"
|
||||
x2="12.1186538"
|
||||
y2="5.32"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(12.1187, 6.72) rotate(90) translate(-12.1187, -6.72)"
|
||||
></line>
|
||||
<line
|
||||
x1="10.1008425"
|
||||
y1="10.7721887"
|
||||
x2="10.1008425"
|
||||
y2="9.27218867"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(10.1008, 10.0222) rotate(135) translate(-10.1008, -10.0222)"
|
||||
></line>
|
||||
<line
|
||||
x1="6.7986538"
|
||||
y1="13.44"
|
||||
x2="6.7986538"
|
||||
y2="10.64"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(6.7987, 12.04) rotate(180) translate(-6.7987, -12.04)"
|
||||
></line>
|
||||
<line
|
||||
x1="1.4786538"
|
||||
y1="8.12"
|
||||
x2="1.4786538"
|
||||
y2="5.32"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(1.4787, 6.72) rotate(270) translate(-1.4787, -6.72)"
|
||||
></line>
|
||||
<line
|
||||
x1="3.49646513"
|
||||
y1="4.16781133"
|
||||
x2="3.49646513"
|
||||
y2="2.66781133"
|
||||
id="路径"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
transform="translate(3.4965, 3.4178) rotate(315) translate(-3.4965, -3.4178)"
|
||||
></line>
|
||||
</g>
|
||||
</g>
|
||||
</SVGWrap>
|
||||
);
|
||||
}
|
||||
103
src/icons/Understand.tsx
Normal file
103
src/icons/Understand.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import SVGWrap from "./SVGWrap";
|
||||
|
||||
export default function Understand(props: I.SVG) {
|
||||
return (
|
||||
<SVGWrap {...props} viewBox="0 0 16 16">
|
||||
<g
|
||||
id="Understand"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<g
|
||||
id="编组"
|
||||
transform="translate(0.5, 0.5)"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.25"
|
||||
>
|
||||
<path
|
||||
d="M7.44444444,3 C9.89904333,3 11.8888889,4.95366655 11.8888889,7.36363636 C11.8888889,9.06711551 10.8946979,10.5426108 9.44492275,11.2613085 L9.44444444,12.2727273 C9.44444444,13.3772968 8.54901394,14.2727273 7.44444444,14.2727273 C6.33987494,14.2727273 5.44444444,13.3772968 5.44444444,12.2727273 L5.44396614,11.2613085 C3.99419095,10.5426108 3,9.06711551 3,7.36363636 C3,4.95366655 4.98984556,3 7.44444444,3 Z"
|
||||
id="形状结合"
|
||||
></path>
|
||||
<line
|
||||
x1="5.5"
|
||||
y1="11.2156017"
|
||||
x2="9.5"
|
||||
y2="11.2156017"
|
||||
id="路径-11"
|
||||
></line>
|
||||
<line
|
||||
x1="7.44444444"
|
||||
y1="10.6363636"
|
||||
x2="7.44444444"
|
||||
y2="8.45454545"
|
||||
id="路径-12"
|
||||
></line>
|
||||
<line
|
||||
x1="7.44444444"
|
||||
y1="0.818181818"
|
||||
x2="7.44444444"
|
||||
y2="0.272727273"
|
||||
id="路径-12备份"
|
||||
></line>
|
||||
<line
|
||||
x1="12.352383"
|
||||
y1="2.81770629"
|
||||
x2="12.3574335"
|
||||
y2="2.26720124"
|
||||
id="路径-12备份"
|
||||
transform="translate(12.3549, 2.5425) rotate(45) translate(-12.3549, -2.5425)"
|
||||
></line>
|
||||
<line
|
||||
x1="14.3888889"
|
||||
y1="7.64141414"
|
||||
x2="14.3888889"
|
||||
y2="7.08585859"
|
||||
id="路径-12备份"
|
||||
transform="translate(14.3889, 7.3636) rotate(90) translate(-14.3889, -7.3636)"
|
||||
></line>
|
||||
<line
|
||||
x1="12.3574335"
|
||||
y1="12.4600715"
|
||||
x2="12.352383"
|
||||
y2="11.9095664"
|
||||
id="路径-12备份"
|
||||
transform="translate(12.3549, 12.1848) rotate(135) translate(-12.3549, -12.1848)"
|
||||
></line>
|
||||
<line
|
||||
x1="2.53145543"
|
||||
y1="12.4600715"
|
||||
x2="2.53650594"
|
||||
y2="11.9095664"
|
||||
id="路径-12备份"
|
||||
transform="translate(2.534, 12.1848) rotate(225) translate(-2.534, -12.1848)"
|
||||
></line>
|
||||
<line
|
||||
x1="0.5"
|
||||
y1="7.64141414"
|
||||
x2="0.5"
|
||||
y2="7.08585859"
|
||||
id="路径-12备份"
|
||||
transform="translate(0.5, 7.3636) rotate(270) translate(-0.5, -7.3636)"
|
||||
></line>
|
||||
<line
|
||||
x1="2.53650594"
|
||||
y1="2.81770629"
|
||||
x2="2.53145543"
|
||||
y2="2.26720124"
|
||||
id="路径-12备份"
|
||||
transform="translate(2.534, 2.5425) rotate(315) translate(-2.534, -2.5425)"
|
||||
></line>
|
||||
<polyline
|
||||
id="路径-15"
|
||||
transform="translate(7.4398, 6.7308) rotate(-45) translate(-7.4398, -6.7308)"
|
||||
points="6.33632897 5.60310185 6.3568375 7.83853192 8.5432888 7.85859111"
|
||||
></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</SVGWrap>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user