feat(componentCoding): 添加iframe全屏切换功能

- 引入全屏切换图标组件
- 实现iframe容器全屏切换逻辑
- 添加全屏状态监听和管理
- 设计iframe操作栏样式和布局
- 增加同步代码、复制git地址、提交代码快捷操作
- 使用useRef获取iframe引用以支持全屏操作
master
钟良源 3 months ago
parent ddbaf2c144
commit b6053e9abf

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="16px" height="16px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M340 865.142857q0-57.142857-94.285714-57.142857-90.285714 0-90.285714 59.428571 0 57.714286 98.285714 57.714286 86.285714 0 86.285714-60zm-33.714286-431.428571q0-34.857143-17.142857-58.285714t-50.857143-23.428571q-70.857143 0-70.857143 82.857143 0 77.142857 70.857143 77.142857 68 0 68-78.285714zm153.714286-185.142857l0 115.428571q-20.571429 6.857143-45.142857 12.571429 9.142857 24.571429 9.142857 48 0 72.571429-41.714286 123.714286t-112.571429 64.285714q-22.857143 4.571429-34 15.428571t-11.142857 33.142857q0 17.714286 12.857143 29.428571t33.142857 18.285714 44.857143 12.571429 49.142857 14.571429 44.857143 21.428571 33.142857 36.571429 12.857143 56.285714q0 173.714286-207.428571 173.714286-39.428571 0-74.285714-7.142857t-66.285714-23.428571-50-46.857143-18.571429-72.857143q0-94.285714 104-128.571429l0-2.285714q-38.285714-23.428571-38.285714-72 0-62.285714 36-78.285714l0-2.285714q-41.142857-13.714286-68.285714-62t-27.142857-94.571429q0-79.428571 54.285714-132.285714t134.285714-52.857143q54.857143 0 101.714286 26.857143 56 0 124.571429-26.857143zm181.714286 503.428571l-126.857143 0q2.285714-25.714286 2.285714-76.571429l0-348q0-53.714286-2.285714-73.142857l126.857143 0q-2.285714 18.857143-2.285714 70.857143l0 350.285714q0 50.857143 2.285714 76.571429zm343.428571-126.857143l0 112q-40.571429 22.285714-99.428571 22.285714-35.428571 0-61.142857-11.428571t-40-28.571429-22.571429-44.571429-10.571429-52.571429-2.285714-58.857143l0-200.571429 1.142857 0 0-2.285714q-4 0-10.857143-0.571429t-10.285714-0.571429q-12 0-33.714286 3.428571l0-108.571429 54.857143 0 0-43.428571q0-30.857143-3.428571-50.857143l129.714286 0q-3.428571 23.428571-3.428571 94.285714l97.714286 0 0 108.571429q-8.571429 0-24.857143-1.142857t-24.285714-1.142857l-48.571429 0 0 208.571429q0 74.857143 49.714286 74.857143 34.857143 0 62.285714-18.857143zm-329.142857-541.142857q0 33.142857-22.285714 58t-54.857143 24.857143q-33.142857 0-56-24.857143t-22.857143-58q0-33.714286 22.571429-58.857143t56.285714-25.142857q33.142857 0 55.142857 25.428571t22 58.571429z" /></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="18px" height="18.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M689.3568 820.9408 333.6192 820.9408c-13.9264 0-25.1904-11.264-25.1904-25.1904L308.4288 465.152l-211.968 0c-10.1888 0-19.4048-6.144-23.296-15.5648C69.2224 440.2176 71.424 429.312 78.6432 422.144l415.0272-415.0784c9.472-9.472 26.1632-9.472 35.6352 0l411.392 411.3408c7.2704 4.4544 12.0832 12.4416 12.0832 21.5552 0 14.1312-11.52 24.576-25.7024 25.1904-0.1536 0-0.3072 0-0.512 0l-211.968 0 0 330.5472C714.5984 809.6256 703.2832 820.9408 689.3568 820.9408zM358.8096 770.5088l305.3568 0L664.1664 439.9616c0-13.9264 11.264-25.1904 25.1904-25.1904l176.3328 0L511.488 60.5184 157.2864 414.7712l176.3328 0c13.9264 0 25.1904 11.264 25.1904 25.1904L358.8096 770.5088zM96.4096 923.1872l830.1056 0L926.5152 1024 96.4096 1024 96.4096 923.1872 96.4096 923.1872zM96.4096 923.1872" /></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="18px" height="18.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M528 504a16 16 0 0 1 16 16v208h66.112c12.8 0 20.416 14.272 13.312 24.896l-98.112 147.136a16 16 0 0 1-26.624 0l-98.112-147.2a16 16 0 0 1 13.312-24.832H480v-208a16 16 0 0 1 16-16z m-16-384a256.384 256.384 0 0 1 254.08 224.384 240.32 240.32 0 0 1 225.92 240.768c-0.64 132.672-110.912 238.848-243.648 238.848h-28.352a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h28.864c98.496 0 180.8-80.64 179.136-179.072a176.192 176.192 0 0 0-176-172.928h-32a16 16 0 0 1-16-16v-12.8c0-105.088-83.2-193.152-188.288-195.2a192.192 192.192 0 0 0-195.712 192v16a16 16 0 0 1-16 16h-32A176.192 176.192 0 0 0 96 580.928c-1.664 98.496 80.64 179.072 179.136 179.072h28.864a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16h-28.352C142.912 824 32.64 717.824 32 585.152a240.32 240.32 0 0 1 225.92-240.768A256.384 256.384 0 0 1 512 120z" /></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import styles from './style/index.module.less'; import styles from './style/index.module.less';
import { Button, Input, Select, Space } from '@arco-design/web-react'; import { Button, Select, Space } from '@arco-design/web-react';
import { IconSearch } from '@arco-design/web-react/icon'; import { IconFullscreen, IconFullscreenExit } from '@arco-design/web-react/icon';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { getMyComponentList } from '@/api/componentBase'; import { getMyComponentList } from '@/api/componentBase';
import { updateComponentCodingPath } from '@/store/ideContainer'; import { updateComponentCodingPath } from '@/store/ideContainer';
@ -12,6 +12,8 @@ const ComponentCoding = () => {
const [serverUrl, setServerUrl] = useState(''); const [serverUrl, setServerUrl] = useState('');
const [optionsList, setOptionsList] = useState([]); const [optionsList, setOptionsList] = useState([]);
const [originList, setOriginList] = useState([]); const [originList, setOriginList] = useState([]);
const [isFullscreen, setIsFullscreen] = useState(false);
const iframeRef = useRef(null);
const { componentCoding } = useSelector((state: any) => state.ideContainer); const { componentCoding } = useSelector((state: any) => state.ideContainer);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -41,6 +43,67 @@ const ComponentCoding = () => {
setServerUrl(`${uri}?folder=${codeServerFolderPre}${path}`); setServerUrl(`${uri}?folder=${codeServerFolderPre}${path}`);
}, [componentCoding]); }, [componentCoding]);
// 监听全屏状态变化
useEffect(() => {
const handleFullscreenChange = () => {
const isCurrentlyFullscreen =
document.fullscreenElement ||
(document as any).webkitFullscreenElement ||
(document as any).mozFullScreenElement ||
(document as any).msFullscreenElement;
setIsFullscreen(!!isCurrentlyFullscreen);
};
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
document.addEventListener('mozfullscreenchange', handleFullscreenChange);
document.addEventListener('MSFullscreenChange', handleFullscreenChange);
return () => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
document.removeEventListener('mozfullscreenchange', handleFullscreenChange);
document.removeEventListener('MSFullscreenChange', handleFullscreenChange);
};
}, []);
// 切换全屏状态
const toggleFullscreen = () => {
const iframeContainer = document.querySelector(`.${styles['code-iframe']}`) as HTMLElement;
if (!isFullscreen) {
// 进入全屏
if (iframeContainer.requestFullscreen) {
iframeContainer.requestFullscreen();
}
else if ((iframeContainer as any).webkitRequestFullscreen) {
(iframeContainer as any).webkitRequestFullscreen();
}
else if ((iframeContainer as any).mozRequestFullScreen) {
(iframeContainer as any).mozRequestFullScreen();
}
else if ((iframeContainer as any).msRequestFullscreen) {
(iframeContainer as any).msRequestFullscreen();
}
}
else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
}
else if ((document as any).webkitExitFullscreen) {
(document as any).webkitExitFullscreen();
}
else if ((document as any).mozCancelFullScreen) {
(document as any).mozCancelFullScreen();
}
else if ((document as any).msExitFullscreen) {
(document as any).msExitFullscreen();
}
}
};
return ( return (
<div className={styles['component-coding']}> <div className={styles['component-coding']}>
<div className={styles['header']}> <div className={styles['header']}>
@ -105,7 +168,30 @@ const ComponentCoding = () => {
</div> </div>
<div className={styles['code-iframe']}> <div className={styles['code-iframe']}>
<iframe width="100%" height="100%" frameBorder={0} src={serverUrl} /> <div className={styles['code-iframe-handle']}>
<Space size={10} className={styles['code-iframe-handle-left']}>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/tongbu.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
</span>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/git.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
git
</span>
<span className={styles['align']}>
<img src={'/ideContainer/imgs/tijiao.svg'} style={{ width: 16, height: 16, marginRight: 5 }} />
</span>
</Space>
<div className={styles['code-iframe-handle-right']} onClick={toggleFullscreen}>
{isFullscreen ? (
<IconFullscreenExit style={{ width: 18, height: 18, marginRight: 5, marginLeft: 5, color: '#ffffff' }} />
) : (
<IconFullscreen style={{ width: 18, height: 18, marginRight: 5, marginLeft: 5, color: '#ffffff' }} />
)}
</div>
</div>
<iframe width="100%" height="100%" frameBorder={0} src={serverUrl} ref={iframeRef} />
</div> </div>
</div> </div>
); );

@ -17,5 +17,40 @@
.code-iframe { .code-iframe {
height: 90%; height: 90%;
.code-iframe-handle {
display: flex;
justify-content: space-between;
padding: 0 10px;
background-color: #2c2c2c;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
.code-iframe-handle-left {
color: #ffffff;
.align {
display: flex;
align-items: center;
padding: 5px 8px;
&:hover {
cursor: pointer;
background-color: #474748;
}
}
}
.code-iframe-handle-right {
display: flex;
align-items: center;
justify-content: center;
&:hover {
cursor: pointer;
background-color: #474748;
}
}
}
} }
} }
Loading…
Cancel
Save