feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import {
|
||||
PluginName,
|
||||
useWriteablePlugin,
|
||||
type CustomTextMessageInnerTopSlot,
|
||||
} from '@coze-common/chat-area';
|
||||
|
||||
import { type GrabPluginBizContext } from '../../types/plugin-biz-context';
|
||||
import { RemoteQuoteInnerTopSlot } from './remote-slot';
|
||||
import { LocalQuoteInnerTopSlot } from './local-slot';
|
||||
|
||||
export const QuoteMessageInnerTopSlot: CustomTextMessageInnerTopSlot = ({
|
||||
message,
|
||||
}) => {
|
||||
const localMessageId = message.extra_info.local_message_id;
|
||||
|
||||
const plugin = useWriteablePlugin<GrabPluginBizContext>(
|
||||
PluginName.MessageGrab,
|
||||
);
|
||||
|
||||
const { useQuoteStore } = plugin.pluginBizContext.storeSet;
|
||||
|
||||
// 优先用本地映射的
|
||||
const hasLocal = useQuoteStore(
|
||||
useShallow(state => !!state.quoteContentMap[localMessageId]),
|
||||
);
|
||||
|
||||
if (hasLocal) {
|
||||
return <LocalQuoteInnerTopSlot message={message} />;
|
||||
}
|
||||
|
||||
return <RemoteQuoteInnerTopSlot message={message} />;
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import {
|
||||
PluginName,
|
||||
useWriteablePlugin,
|
||||
type CustomTextMessageInnerTopSlot,
|
||||
} from '@coze-common/chat-area';
|
||||
|
||||
import { QuoteNode } from '../quote-node';
|
||||
import { type GrabPluginBizContext } from '../../types/plugin-biz-context';
|
||||
import { QuoteTopUI } from './quote-top-ui';
|
||||
|
||||
export const LocalQuoteInnerTopSlot: CustomTextMessageInnerTopSlot = ({
|
||||
message,
|
||||
}) => {
|
||||
const localMessageId = message.extra_info.local_message_id;
|
||||
|
||||
const plugin = useWriteablePlugin<GrabPluginBizContext>(
|
||||
PluginName.MessageGrab,
|
||||
);
|
||||
|
||||
const { useQuoteStore } = plugin.pluginBizContext.storeSet;
|
||||
|
||||
// 优先用本地映射的
|
||||
const localNodeList = useQuoteStore(
|
||||
useShallow(state => state.quoteContentMap[localMessageId]),
|
||||
);
|
||||
|
||||
if (localNodeList) {
|
||||
return (
|
||||
<QuoteTopUI>
|
||||
<QuoteNode nodeList={localNodeList} theme="white" />
|
||||
</QuoteTopUI>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC, type PropsWithChildren } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { useShowBackGround } from '@coze-common/chat-area';
|
||||
import { IconCozQuotation } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { typeSafeQuoteNodeColorVariants } from '../variants';
|
||||
|
||||
export const QuoteTopUI: FC<PropsWithChildren> = ({ children }) => {
|
||||
const showBackground = useShowBackGround();
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
['h-auto', 'py-4px'],
|
||||
'flex flex-row items-center select-none w-m-0',
|
||||
)}
|
||||
>
|
||||
<IconCozQuotation
|
||||
className={classNames(
|
||||
typeSafeQuoteNodeColorVariants({ showBackground }),
|
||||
'mr-[8px] shrink-0 w-[12px] h-[12px]',
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={classNames('flex-1 min-w-0 truncate text-[12px]', [
|
||||
'leading-[16px]',
|
||||
typeSafeQuoteNodeColorVariants({ showBackground }),
|
||||
])}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { parseMarkdownToGrabNode } from '@coze-common/text-grab';
|
||||
import {
|
||||
ContentType,
|
||||
type CustomTextMessageInnerTopSlot,
|
||||
} from '@coze-common/chat-area';
|
||||
|
||||
import { QuoteNode } from '../quote-node';
|
||||
import { getReferFromMessage } from '../../utils/get-refer-from-message';
|
||||
import { QuoteTopUI } from './quote-top-ui';
|
||||
|
||||
export const RemoteQuoteInnerTopSlot: CustomTextMessageInnerTopSlot = ({
|
||||
message,
|
||||
}) => {
|
||||
// 本地没有用服务端下发的
|
||||
const refer = getReferFromMessage(message);
|
||||
|
||||
if (!refer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (refer.type === ContentType.Image) {
|
||||
return (
|
||||
<QuoteTopUI>
|
||||
<img className="w-[24px] h-[24px] rounded-[4px]" src={refer.url} />
|
||||
</QuoteTopUI>
|
||||
);
|
||||
}
|
||||
|
||||
// 尝试解析ast
|
||||
const nodeList = parseMarkdownToGrabNode(refer.text);
|
||||
|
||||
return (
|
||||
<QuoteTopUI>
|
||||
<QuoteNode nodeList={nodeList} theme="white" />
|
||||
</QuoteTopUI>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user