212 lines
5.5 KiB
TypeScript
212 lines
5.5 KiB
TypeScript
import { Container } from '@kevisual/container';
|
|
import { useEffect, useRef, useState } from 'react';
|
|
import { useParams } from 'react-router';
|
|
import { query } from '@/modules';
|
|
|
|
import { message } from '@/modules/message';
|
|
export const useListener = (id?: string, opts?: any) => {
|
|
const { refresh } = opts || {};
|
|
const [connected, setConnected] = useState(false);
|
|
// 监听服务器的消息
|
|
useEffect(() => {
|
|
if (!id) return;
|
|
if (!connected) return;
|
|
const ws = query.qws.ws;
|
|
ws.send(
|
|
JSON.stringify({
|
|
type: 'subscribe',
|
|
data: {
|
|
type: 'pageEdit',
|
|
data: {
|
|
cid: id,
|
|
// cids: [],
|
|
// pids:'',
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
ws.addEventListener('message', listener);
|
|
return () => {
|
|
if (!id) return;
|
|
if (!connected) return;
|
|
ws.removeEventListener('message', listener);
|
|
};
|
|
}, [id, connected]);
|
|
const init = async () => {
|
|
query.qws.listenConnect(() => {
|
|
setConnected(true);
|
|
});
|
|
};
|
|
useEffect(() => {
|
|
init();
|
|
}, []);
|
|
const listener = (event) => {
|
|
const parseIfJson = (data: string) => {
|
|
try {
|
|
return JSON.parse(data);
|
|
} catch (e) {
|
|
return data;
|
|
}
|
|
};
|
|
const receivedData = parseIfJson(event.data);
|
|
if (typeof receivedData === 'string') return;
|
|
if (receivedData.type === 'pageEdit' && receivedData.source === 'container') {
|
|
const { data: containerData } = receivedData;
|
|
if (containerData.id !== id) return;
|
|
if (refresh) {
|
|
refresh(containerData);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
export const Preview = () => {
|
|
const params = useParams<{ id: string }>();
|
|
const id = params.id;
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
const containerRef = useRef<Container | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!id) return;
|
|
fetch();
|
|
}, []);
|
|
const fetch = async () => {
|
|
const res = await query.post({
|
|
path: 'container',
|
|
key: 'get',
|
|
id,
|
|
});
|
|
if (res.code === 200) {
|
|
const data = res.data;
|
|
// setData([data]);
|
|
console.log('data', data);
|
|
const code = {
|
|
id: data.id,
|
|
title: data.title,
|
|
codeId: data.id,
|
|
code: data.code,
|
|
data: data.data,
|
|
};
|
|
init([code]);
|
|
} else {
|
|
message.error(res.message || 'Failed to fetch data');
|
|
}
|
|
};
|
|
const refresh = (data: any) => {
|
|
if (!data.id) return;
|
|
const code = {
|
|
id: data.id,
|
|
title: data.title,
|
|
codeId: data.id,
|
|
code: data.code,
|
|
data: data.data,
|
|
hash: '',
|
|
};
|
|
init([code], true);
|
|
};
|
|
useListener(id, { refresh: refresh });
|
|
const init = async (data: any[], replace: boolean = false) => {
|
|
// console.log('data', data, ref.current);
|
|
if (containerRef.current) {
|
|
const container = containerRef.current;
|
|
console.log('data', data, container.data);
|
|
container.updateData(data);
|
|
await new Promise((resolve) => {
|
|
setTimeout(resolve, 2000);
|
|
});
|
|
console.log('update---data', data, container.data);
|
|
container.destroy(id!);
|
|
container.render(id!);
|
|
return;
|
|
}
|
|
console.log('data', containerRef.current);
|
|
const container = new Container({
|
|
root: ref.current!,
|
|
data: data as any,
|
|
});
|
|
container.render(id!);
|
|
containerRef.current = container;
|
|
};
|
|
return <div className='mx-auto border bg-gray-200 h-full w-full' ref={ref}></div>;
|
|
};
|
|
export const PreviewWrapper = () => {
|
|
const params = useParams<{ id: string }>();
|
|
const id = params.id;
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
const containerRef = useRef<Container | null>(null);
|
|
useEffect(() => {
|
|
if (!id) return;
|
|
fetch();
|
|
}, []);
|
|
const fetch = async () => {
|
|
const res = await query.post<any, any>({
|
|
path: 'container',
|
|
key: 'get',
|
|
payload: {
|
|
id,
|
|
}
|
|
});
|
|
if (res.code === 200) {
|
|
const data = res.data;
|
|
// setData([data]);
|
|
console.log('data', data);
|
|
const code = {
|
|
id: data.id,
|
|
title: data.title,
|
|
codeId: data.id,
|
|
code: data.code,
|
|
data: data.data,
|
|
};
|
|
init([code]);
|
|
} else {
|
|
message.error(res.message || 'Failed to fetch data');
|
|
}
|
|
};
|
|
const refresh = (data: any) => {
|
|
if (!data.id) return;
|
|
const code = {
|
|
id: data.id,
|
|
title: data.title,
|
|
codeId: data.id,
|
|
code: data.code,
|
|
data: data.data,
|
|
hash: '',
|
|
};
|
|
init([code], true);
|
|
};
|
|
useListener(id, { refresh: refresh });
|
|
const init = async (data: any[], replace: boolean = false) => {
|
|
// console.log('data', data, ref.current);
|
|
if (containerRef.current) {
|
|
const container = containerRef.current;
|
|
console.log('data', data, container.data);
|
|
container.updateData(data);
|
|
await new Promise((resolve) => {
|
|
setTimeout(resolve, 2000);
|
|
});
|
|
console.log('update---data', data, container.data);
|
|
container.destroy(id!);
|
|
container.render(id!);
|
|
return;
|
|
}
|
|
console.log('data', containerRef.current);
|
|
const container = new Container({
|
|
root: ref.current!,
|
|
data: data as any,
|
|
});
|
|
container.render(id!);
|
|
containerRef.current = container;
|
|
};
|
|
return (
|
|
<div className='w-full h-full bg-gray-200'>
|
|
<div className='text-center mb-4 pt-2 font-bold text-4xl '>Preview</div>
|
|
<div
|
|
className='flex '
|
|
style={{
|
|
height: 'calc(100% - 32px)',
|
|
}}>
|
|
<div className='mx-auto border bg-white h-h-full w-[80%] h-[80%] overflow-scroll scrollbar relative' ref={ref}></div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|