style: 调整
This commit is contained in:
@ -10,7 +10,7 @@ import type { BubbleProps, BubbleContentType, SlotInfoType } from './types';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Bubble',
|
name: 'Bubble',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {} as any,
|
props: {},
|
||||||
setup(_, { attrs, slots, expose }) {
|
setup(_, { attrs, slots, expose }) {
|
||||||
const props = attrs as unknown as BubbleProps<BubbleContentType> & { style?: any; class?: any };
|
const props = attrs as unknown as BubbleProps<BubbleContentType> & { style?: any; class?: any };
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export default defineComponent({
|
|||||||
watch(
|
watch(
|
||||||
() => props.content,
|
() => props.content,
|
||||||
(val) => {
|
(val) => {
|
||||||
content.value = val as any;
|
content.value = val;
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
@ -27,13 +27,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const [typingEnabled, typingStep, typingInterval, typingSuffix] = useTypingConfig(() => props.typing);
|
const [typingEnabled, typingStep, typingInterval, typingSuffix] = useTypingConfig(() => props.typing);
|
||||||
const abortRef = ref(false);
|
const abortRef = ref(false);
|
||||||
const [typedContent, isTyping] = useTypedEffect(
|
const [typedContent, isTyping] = useTypedEffect(content, typingEnabled, typingStep, typingInterval, abortRef);
|
||||||
content as any,
|
|
||||||
typingEnabled,
|
|
||||||
typingStep,
|
|
||||||
typingInterval,
|
|
||||||
abortRef,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 提供中止打字的能力:关闭typing并立即展示完整内容
|
// 提供中止打字的能力:关闭typing并立即展示完整内容
|
||||||
const abortTyping = () => {
|
const abortTyping = () => {
|
||||||
@ -73,10 +67,8 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mergedContent = computed(() => {
|
const mergedContent = computed(() => {
|
||||||
if (slots.message) return slots.message({ content: typedContent.value as any }) as any;
|
if (slots.message) return slots.message({ content: typedContent.value });
|
||||||
return props.messageRender
|
return props.messageRender ? props.messageRender(typedContent.value) : typedContent.value;
|
||||||
? (props.messageRender(typedContent.value as any) as any)
|
|
||||||
: (typedContent.value as any);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentNode = computed(() => {
|
const contentNode = computed(() => {
|
||||||
@ -89,7 +81,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{mergedContent.value as any}
|
{mergedContent.value}
|
||||||
{isTyping.value && unref(typingSuffix)}
|
{isTyping.value && unref(typingSuffix)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -97,16 +89,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
const info: SlotInfoType = { key: props._key };
|
const info: SlotInfoType = { key: props._key };
|
||||||
if (slots.header) return slots.header({ content: typedContent.value as any, info, item: props }) as any;
|
if (slots.header) return slots.header({ content: typedContent.value, info, item: props });
|
||||||
const h = props.header;
|
const h = props.header;
|
||||||
return typeof h === 'function' ? h({ content: typedContent.value as any, info, item: props }) : h;
|
return typeof h === 'function' ? h({ content: typedContent.value, info, item: props }) : h;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderFooter = () => {
|
const renderFooter = () => {
|
||||||
const info: SlotInfoType = { key: props._key };
|
const info: SlotInfoType = { key: props._key };
|
||||||
if (slots.footer) return slots.footer({ content: typedContent.value as any, info, item: props }) as any;
|
if (slots.footer) return slots.footer({ content: typedContent.value, info, item: props });
|
||||||
const f = props.footer;
|
const f = props.footer;
|
||||||
return typeof f === 'function' ? f({ content: typedContent.value as any, info, item: props }) : f;
|
return typeof f === 'function' ? f({ content: typedContent.value, info, item: props }) : f;
|
||||||
};
|
};
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
@ -117,7 +109,7 @@ export default defineComponent({
|
|||||||
<div class={mergedCls.value} style={{ ...(props.style || {}) }}>
|
<div class={mergedCls.value} style={{ ...(props.style || {}) }}>
|
||||||
{(slots.avatar || props.avatar) && (
|
{(slots.avatar || props.avatar) && (
|
||||||
<div class={[`${prefixCls}-avatar`, props.classNames?.avatar]} style={props.styles?.avatar}>
|
<div class={[`${prefixCls}-avatar`, props.classNames?.avatar]} style={props.styles?.avatar}>
|
||||||
{avatarNode.value as any}
|
{avatarNode.value}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -135,7 +127,7 @@ export default defineComponent({
|
|||||||
{renderHeader()}
|
{renderHeader()}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{contentNode.value as any}
|
{contentNode.value}
|
||||||
{renderFooter() ? (
|
{renderFooter() ? (
|
||||||
<div class={[`${prefixCls}-footer`, props.classNames?.footer]} style={props.styles?.footer}>
|
<div class={[`${prefixCls}-footer`, props.classNames?.footer]} style={props.styles?.footer}>
|
||||||
{renderFooter()}
|
{renderFooter()}
|
||||||
|
|||||||
@ -23,14 +23,14 @@ import {
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BubbleList',
|
name: 'BubbleList',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {} as any,
|
props: {},
|
||||||
setup(_, { attrs, slots, expose }) {
|
setup(_, { attrs, slots, expose }) {
|
||||||
const props = attrs as unknown as BubbleListProps & { class?: any; style?: any };
|
const props = attrs as unknown as BubbleListProps & { class?: any; style?: any };
|
||||||
const passThroughAttrs = useAttrs();
|
const passThroughAttrs = useAttrs();
|
||||||
|
|
||||||
const TOLERANCE = 1;
|
const TOLERANCE = 1;
|
||||||
|
|
||||||
const domProps = computed(() => pickAttrs(mergeProps(props as any, passThroughAttrs)) as any);
|
const domProps = computed(() => pickAttrs(mergeProps(props as any, passThroughAttrs)));
|
||||||
|
|
||||||
const items = ref(props.items);
|
const items = ref(props.items);
|
||||||
const roles = ref(props.roles as RolesType);
|
const roles = ref(props.roles as RolesType);
|
||||||
@ -108,7 +108,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
// 对外暴露能力
|
// 对外暴露能力
|
||||||
expose({
|
expose({
|
||||||
nativeElement: listRef as any,
|
nativeElement: listRef,
|
||||||
abortTypingByKey,
|
abortTypingByKey,
|
||||||
scrollTo: (info: any) => {
|
scrollTo: (info: any) => {
|
||||||
unref(listRef)?.scrollTo?.(info);
|
unref(listRef)?.scrollTo?.(info);
|
||||||
@ -125,20 +125,18 @@ export default defineComponent({
|
|||||||
props.class,
|
props.class,
|
||||||
{ [`${listPrefixCls}-reach-end`]: unref(scrollReachEnd) },
|
{ [`${listPrefixCls}-reach-end`]: unref(scrollReachEnd) },
|
||||||
]}
|
]}
|
||||||
style={props.style as any}
|
style={props.style}
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
onScroll={onInternalScroll}
|
onScroll={onInternalScroll}
|
||||||
>
|
>
|
||||||
{unref(displayData).map(({ key, onTypingComplete: onTypingCompleteBubble, ...bubble }: any) => (
|
{unref(displayData).map(({ key, onTypingComplete: onTypingCompleteBubble, ...bubble }) => (
|
||||||
<Bubble
|
<Bubble
|
||||||
{...bubble}
|
{...bubble}
|
||||||
avatar={slots.avatar ? () => slots.avatar?.({ item: { key, ...bubble } }) : (bubble as any).avatar}
|
avatar={slots.avatar ? () => slots.avatar?.({ item: { key, ...bubble } }) : bubble.avatar}
|
||||||
header={slots.header?.({ item: { key, ...bubble } }) ?? (bubble as any).header}
|
header={slots.header?.({ item: { key, ...bubble } }) ?? bubble.header}
|
||||||
footer={slots.footer?.({ item: { key, ...bubble } }) ?? (bubble as any).footer}
|
footer={slots.footer?.({ item: { key, ...bubble } }) ?? bubble.footer}
|
||||||
loadingRender={
|
loadingRender={slots.loading ? () => slots.loading({ item: { key, ...bubble } }) : bubble.loadingRender}
|
||||||
slots.loading ? () => slots.loading({ item: { key, ...bubble } }) : (bubble as any).loadingRender
|
content={slots.message?.({ item: { key, ...bubble } }) ?? bubble.content}
|
||||||
}
|
|
||||||
content={slots.message?.({ item: { key, ...bubble } }) ?? (bubble as any).content}
|
|
||||||
key={key}
|
key={key}
|
||||||
ref={(node: any) => {
|
ref={(node: any) => {
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -147,7 +145,7 @@ export default defineComponent({
|
|||||||
delete bubbleRefs.value[key];
|
delete bubbleRefs.value[key];
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
typing={unref(initialized) ? (bubble as any).typing : false}
|
typing={unref(initialized) ? bubble.typing : false}
|
||||||
onTypingComplete={() => {
|
onTypingComplete={() => {
|
||||||
onTypingCompleteBubble?.();
|
onTypingCompleteBubble?.();
|
||||||
onTypingComplete(key);
|
onTypingComplete(key);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { Bubble } from '@/components/xt-chat/xt-bubble';
|
|||||||
|
|
||||||
import { downloadByUrl } from '@/utils/tools';
|
import { downloadByUrl } from '@/utils/tools';
|
||||||
import markdownit from 'markdown-it';
|
import markdownit from 'markdown-it';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
@ -29,6 +30,13 @@ export default {
|
|||||||
|
|
||||||
const onDownload = () => {
|
const onDownload = () => {
|
||||||
// downloadByUrl('');
|
// downloadByUrl('');
|
||||||
|
message.success('下载成功!');
|
||||||
|
};
|
||||||
|
const onAddMediaCenter = () => {
|
||||||
|
message.success('成功添加至“素材中心”模块。');
|
||||||
|
};
|
||||||
|
const onAddTaskManage = () => {
|
||||||
|
message.success('成功添加至“任务管理”模块。');
|
||||||
};
|
};
|
||||||
const abortTyping = () => {
|
const abortTyping = () => {
|
||||||
bubbleRef.value?.abortTyping?.();
|
bubbleRef.value?.abortTyping?.();
|
||||||
@ -36,10 +44,22 @@ export default {
|
|||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
<header class="header flex justify-end items-center mb-16px px-32px">
|
<header class="header flex justify-end items-center mb-16px px-32px">
|
||||||
<Button type="outline" size="medium" class="mr-16px" v-slots={{ icon: () => <icon-plus size="14" /> }}>
|
<Button
|
||||||
|
type="outline"
|
||||||
|
size="medium"
|
||||||
|
class="mr-16px"
|
||||||
|
v-slots={{ icon: () => <icon-plus size="14" /> }}
|
||||||
|
onClick={onAddMediaCenter}
|
||||||
|
>
|
||||||
素材中心
|
素材中心
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="outline" size="medium" class="mr-16px" v-slots={{ icon: () => <icon-plus size="14" /> }}>
|
<Button
|
||||||
|
type="outline"
|
||||||
|
size="medium"
|
||||||
|
class="mr-16px"
|
||||||
|
v-slots={{ icon: () => <icon-plus size="14" /> }}
|
||||||
|
onClick={onAddTaskManage}
|
||||||
|
>
|
||||||
任务管理
|
任务管理
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
Reference in New Issue
Block a user