import { inject, InjectionKey, Ref, FunctionalComponent, computed } from 'vue';
|
import { Image, Video } from '@tarojs/components';
|
import { setOSSLink } from '@12333/utils';
|
import AutoWidthImage from '../Image/AutoWidthImage.vue';
|
import IconDelete from '@/assets/components/rich-card/icon-delete.png';
|
import IconUp from '@/assets/components/rich-card/icon-move-up.png';
|
import IconUpActive from '@/assets/components/rich-card/icon-move-up-active.png';
|
import IconDown from '@/assets/components/rich-card/icon-move-down.png';
|
import IconDownActive from '@/assets/components/rich-card/icon-move-down-active.png';
|
|
interface EditRichContentContext {
|
editContentList: Ref<API.IntroInfo[]>;
|
}
|
|
export const EditRichContentContextKey: InjectionKey<EditRichContentContext> = Symbol(
|
'EditRichContentContextKey'
|
);
|
|
export function useEditRichContentContext() {
|
return inject(EditRichContentContextKey);
|
}
|
|
export type EditorContainerProps = {
|
title?: string;
|
index?: number;
|
};
|
|
export const EditorContainer: FunctionalComponent<EditorContainerProps> = (props, { slots }) => {
|
const { title, index = 0 } = props;
|
|
const { editContentList } = useEditRichContentContext();
|
|
const canMoveUp = computed(() => index > 0);
|
|
const canMoveDown = computed(() => index < editContentList.value.length - 1);
|
|
function handleMoveUp() {
|
if (canMoveUp.value) {
|
[editContentList.value[index], editContentList.value[index - 1]] = [
|
editContentList.value[index - 1],
|
editContentList.value[index],
|
];
|
editContentList.value.forEach((item, index) => {
|
item.sequence = index;
|
});
|
}
|
}
|
|
function handleMoveDown() {
|
if (canMoveDown.value) {
|
[editContentList.value[index + 1], editContentList.value[index]] = [
|
editContentList.value[index],
|
editContentList.value[index + 1],
|
];
|
editContentList.value.forEach((item, index) => {
|
item.sequence = index;
|
});
|
}
|
}
|
|
function handleDelete() {
|
editContentList.value.splice(index, 1);
|
}
|
|
return (
|
<div class="editor-container-wrapper">
|
<div class="editor-container-top">
|
<div class="editor-container-title">{title}</div>
|
<div class="editor-container-actions">
|
<Image
|
class="editor-container-action-move-up"
|
src={canMoveUp.value ? IconUpActive : IconUp}
|
onTap={handleMoveUp}
|
/>
|
<Image
|
class="editor-container-action-move-down"
|
src={canMoveDown.value ? IconDownActive : IconDown}
|
onTap={handleMoveDown}
|
/>
|
<Image
|
class="editor-container-action-move-delete"
|
src={IconDelete}
|
onTap={handleDelete}
|
/>
|
</div>
|
</div>
|
{slots.default?.()}
|
</div>
|
);
|
};
|
|
type CommonEditorProps = {
|
item: API.IntroInfo;
|
index?: number;
|
};
|
|
type TextEditorProps = {} & CommonEditorProps;
|
|
export const TextEditor: FunctionalComponent<TextEditorProps> = (props) => {
|
return (
|
<EditorContainer title="文本" index={props.index}>
|
<nut-textarea
|
class="editor-textarea"
|
placeholderClass="editor-textarea-placeholder"
|
modelValue={props.item.content}
|
onUpdate:modelValue={(value) => (props.item.content = value)}
|
autosize
|
max-length={10000000000}
|
/>
|
</EditorContainer>
|
);
|
};
|
|
export function ImageEditor(props: CommonEditorProps) {
|
return (
|
<EditorContainer title="图片" index={props.index}>
|
{/* @ts-ignore */}
|
<AutoWidthImage class="editor-image" src={setOSSLink(props.item.path)} />
|
</EditorContainer>
|
);
|
}
|
|
export function VideoEditor(props: CommonEditorProps) {
|
return (
|
<EditorContainer title="视频" index={props.index}>
|
<Video class="editor-video" src={setOSSLink(props.item.path)} />
|
</EditorContainer>
|
);
|
}
|