Commit 5499f2c8 by Nikita

added remove iframe button

parent 6ce5f728
......@@ -31,6 +31,9 @@ import ReactStopwatch from 'react-stopwatch';
import Audio from "./extensions/Audio";
import { isMobile } from 'react-device-detect';
import IframeModal from "./modals/IframeModal";
import IframeCustomModal from "./modals/IframeCustomModal";
import RemoveIframeModal from "./modals/RemoveIframeModal";
const initialBubbleItems = ['bold', 'italic', 'underline', 'strike', '|', 'colorText', 'highlight'];
......@@ -55,6 +58,7 @@ const QEditor = ({
const [oldFocusFromTo, setOldFocusFromTo] = useState(null);
const [isUploading, setIsUploading] = useState(false);
const [recordType, setRecordType] = useState({video: true})
const [currentRemoveIframe, setCurrentRemoveIframe] = useState(null);
const getRgb = (hex) => {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
......@@ -495,29 +499,18 @@ const QEditor = ({
const getInnerModal = () => {
switch (innerModalType) {
case 'remove_iframe':
return <RemoveIframeModal />
case 'iframe':
return (
<Fragment>
<input type="text" value={embedContent} placeholder={'https://'}
onInput={(e) => setEmbedContent(e.target.value)
}/>
<ul className={'atma-editor-soc-video'}>
<li className={'youtube'}/>
<li className={'vimeo'}/>
{/* <li className={'vk'}/> */}
<li className={'ok'}/>
<li className={'rutube'}/>
</ul>
</Fragment>
)
return <IframeModal
embedContent={embedContent}
setEmbedContent={setEmbedContent}
/>
case 'iframe_custom':
return (
<Fragment>
<textarea style={{width: '100%', height: '100%'}} rows={18} value={embedContent} placeholder={'<iframe></iframe>'}
onInput={(e) => setEmbedContent(e.target.value)}
/>
</Fragment>
)
return <IframeCustomModal
embedContent={embedContent}
setEmbedContent={setEmbedContent}
/>
case 'iframe_pptx':
return (
<Fragment>{getUploader({accept: 'application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.slideshow, application/vnd.openxmlformats-officedocument.presentationml.presentation', afterParams: ['no_convert=1']})}</Fragment>
......@@ -536,7 +529,6 @@ const QEditor = ({
)
case 'voicemessage':
return (
<>
<Fragment>
{
isMobile &&
......@@ -577,7 +569,6 @@ const QEditor = ({
</div>
}
</Fragment>
</>
)
case 'screencust':
return (
......@@ -794,6 +785,181 @@ const QEditor = ({
return null
}
const buttons = innerModalType === 'remove_iframe' ?
[
{
title: 'Отмена',
className: ' atma-editor-cancel',
onClick: () => {
stopRecording();
unMuteAudio();
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setUploadedPaths([]);
setModalIsOpen(false);
}
},
{
title: 'Удалить',
className: ' atma-editor-complete',
onClick: () => {
currentRemoveIframe?.remove();
stopRecording();
unMuteAudio();
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setUploadedPaths([]);
setModalIsOpen(false);
}
},
] : [
{
title: 'Отмена',
className: ' atma-editor-cancel',
onClick: () => {
stopRecording();
unMuteAudio();
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setUploadedPaths([]);
setModalIsOpen(false);
}
},
{
title: (mediaBlobUrl && uploadedPaths.length === 0) ? (isUploading ? 'Сохранение...' : 'Вставить') : 'Вставить',
className: ' atma-editor-complete',
onClick: async () => {
if ((status === 'recording' || isUploading)) {
return false;
} else {
if (document.querySelectorAll('.atma-editor-uploader-progress').length > 0) {
if ( ! confirm('Не полностью загруженные файлы будут утеряны. Вы уверены, что хотите продолжить?')) {
return false;
}
}
try {
switch (innerModalType) {
case 'image':
uploadedPaths.map((file, i) => {
editor.chain().focus().setImage({src: file.path}).run();
});
break
case 'video':
uploadedPaths.map((file, i) => {
editor.chain().focus().setVideo({
src: file.path,
poster: file.path + '.jpg'
}).run();
});
break
case 'voicemessage':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().addVoiceMessage({src: data.file_path}).run();
}
});
}
}
break
case 'screencust':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().setVideo({src: data.file_path}).run();
}
});
}
}
break
case 'webcamera':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().setVideo({src: data.file_path}).run();
}
});
}
}
break
case 'iframe':
let _url = embedContent;
let reg = /(http|https):\/\/([\w.]+\/?)\S*/;
const url = new URL(reg.test(_url) ? _url : 'https:' + _url);
let urlId = url.pathname.replace(/\/$/ig, '').split('/').pop();
switch (url.hostname) {
case 'rutube.ru':
case 'www.rutube.ru':
_url = `https://rutube.ru/pl/?pl_id&pl_type&pl_video=${urlId}`;
break
case 'vimeo.com':
_url = `https://player.vimeo.com/video/${urlId}`;
break
case 'ok.ru':
case 'www.ok.ru':
_url = `//ok.ru/videoembed/${urlId}`;
break
case 'youtu.be':
case 'youtube.com':
case 'www.youtube.com':
if (url.hostname.indexOf('youtu.be') === -1 && url.search !== '') {
if (url.searchParams.get('v')) {
urlId = url.searchParams.get('v');
}
}
_url = `https://www.youtube.com/embed/${urlId}`;
break
}
editor.chain().focus().setIframe({src: _url, setModalIsOpen, setInnerModalType, setModalTitle, setCurrentRemoveIframe}).run();
break
case 'iframe_custom':
editor.chain().focus().insertContent(embedContent).run();
break
case 'iframe_pptx':
uploadedPaths.map((file, i)=>{
editor.chain().focus().insertContent(`<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=${file.path}" width="100%" height="600px" frameBorder="0"></iframe>`).run();
})
break
case 'file':
uploadedPaths.map((file, i) => {
let exp = file.path.split('.');
exp = exp[exp.length - 1]
editor.chain().focus().insertContent(`<a href="${file.path}" target="_blank" download="${file.name}.${exp}" data-size="${file.size}">${file.name}</a>`).run();
});
break
}
setModalIsOpen(false);
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setEmbedContent('');
setUploadedPaths([]);
setModalTitle('');
} catch (err) {
console.log(err);
setModalIsOpen(false);
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setEmbedContent('');
setUploadedPaths([]);
setModalTitle('');
}
}
},
disabled: isDisabledAction()
}
];
return (
<div
className="atma-editor-wrap"
......@@ -873,152 +1039,7 @@ const QEditor = ({
getInnerModal()
}
{
buildActionsModal([
{
title: 'Отмена',
className: ' atma-editor-cancel',
onClick: () => {
stopRecording();
unMuteAudio();
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setUploadedPaths([]);
setModalIsOpen(false);
}
},
{
title: (mediaBlobUrl && uploadedPaths.length === 0) ? (isUploading ? 'Сохранение...' : 'Вставить') : 'Вставить',
className: ' atma-editor-complete',
onClick: async () => {
if ((status === 'recording' || isUploading)) {
return false;
} else {
if (document.querySelectorAll('.atma-editor-uploader-progress').length > 0) {
if ( ! confirm('Не полностью загруженные файлы будут утеряны. Вы уверены, что хотите продолжить?')) {
return false;
}
}
try {
switch (innerModalType) {
case 'image':
uploadedPaths.map((file, i) => {
editor.chain().focus().setImage({src: file.path}).run();
});
break
case 'video':
uploadedPaths.map((file, i) => {
editor.chain().focus().setVideo({
src: file.path,
poster: file.path + '.jpg'
}).run();
});
break
case 'voicemessage':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().addVoiceMessage({src: data.file_path}).run();
}
});
}
}
break
case 'screencust':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().setVideo({src: data.file_path}).run();
}
});
}
}
break
case 'webcamera':
if (mediaBlobUrl && uploadedPaths.length === 0) {
if ( ! isUploading) {
await saveScreenCust(mediaBlobUrl).then(data => {
if (data?.file_path) {
editor.chain().focus().setVideo({src: data.file_path}).run();
}
});
}
}
break
case 'iframe':
let _url = embedContent;
let reg = /(http|https):\/\/([\w.]+\/?)\S*/;
const url = new URL(reg.test(_url) ? _url : 'https:' + _url);
let urlId = url.pathname.replace(/\/$/ig, '').split('/').pop();
switch (url.hostname) {
case 'rutube.ru':
case 'www.rutube.ru':
_url = `https://rutube.ru/pl/?pl_id&pl_type&pl_video=${urlId}`;
break
case 'vimeo.com':
_url = `https://player.vimeo.com/video/${urlId}`;
break
case 'ok.ru':
case 'www.ok.ru':
_url = `//ok.ru/videoembed/${urlId}`;
break
case 'youtu.be':
case 'youtube.com':
case 'www.youtube.com':
if (url.hostname.indexOf('youtu.be') === -1 && url.search !== '') {
if (url.searchParams.get('v')) {
urlId = url.searchParams.get('v');
}
}
_url = `https://www.youtube.com/embed/${urlId}`;
break
}
editor.chain().focus().setIframe({src: _url}).run();
break
case 'iframe_custom':
editor.chain().focus().insertContent(embedContent).run();
break
case 'iframe_pptx':
uploadedPaths.map((file, i)=>{
editor.chain().focus().insertContent(`<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=${file.path}" width="100%" height="600px" frameBorder="0"></iframe>`).run();
})
break
case 'file':
uploadedPaths.map((file, i) => {
let exp = file.path.split('.');
exp = exp[exp.length - 1]
editor.chain().focus().insertContent(`<a href="${file.path}" target="_blank" download="${file.name}.${exp}" data-size="${file.size}">${file.name}</a>`).run();
});
break
}
setModalIsOpen(false);
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setEmbedContent('');
setUploadedPaths([]);
setModalTitle('');
} catch (err) {
console.log(err);
setModalIsOpen(false);
clearBlobUrl();
setUploaderUid(`uid${new Date()}`);
setEmbedContent('');
setUploadedPaths([]);
setModalTitle('');
}
}
},
disabled: isDisabledAction()
}
])
buildActionsModal(buttons)
}
</EditorModal>
</div>
......
......@@ -21,6 +21,18 @@ const Iframe = Node.create({
console.log(this)
},
},
"setInnerModalType" : {
default: null
},
"setModalIsOpen" : {
default: null
},
"setModalTitle" : {
default: null
},
"setCurrentRemoveIframe" : {
default: null
}
}
},
......@@ -38,21 +50,35 @@ const Iframe = Node.create({
addNodeView() {
return ({ editor, node, ...a }) => {
const container = document.createElement('div');
// div.className = 'aspect-w-16 aspect-h-9' + (editor.isEditable ? ' cursor-pointer' : '');
const iframe = document.createElement('iframe');
if (editor.isEditable) {
iframe.className = 'pointer-events-none';
}
iframe.src = node.attrs.src;
iframe.frameBorder = node.attrs.frameborder;
iframe.allowfullscreen = node.attrs.allowfullscreen;
iframe.style = 'width:1280px;height:auto;aspect-ratio: 16 / 9;';
// div.append(video);
iframe.classList.add('customIframe');
const closeBtn = document.createElement('button');
closeBtn.textContent = 'X';
closeBtn.classList.add('closeBtn');
closeBtn.addEventListener('click', function () {
try {
node.attrs.setModalTitle('Вы уверены, что хотите удалить?');
node.attrs.setInnerModalType('remove_iframe');
node.attrs.setModalIsOpen(true);
node.attrs.setCurrentRemoveIframe(container);
} catch {
container.remove();
}
});
// if (editor.isEditable) {
// container.classList.add('pointer-events-none');
// }
container.append(closeBtn, iframe);
return {
dom: iframe,
dom: container,
}
}
},
......@@ -62,7 +88,7 @@ const Iframe = Node.create({
setIframe: (options) => ({ tr, dispatch }) => {
const { selection } = tr
const node = this.type.create(options)
//
if (dispatch) {
tr.replaceRangeWith(selection.from, selection.to, node)
}
......
......@@ -1022,4 +1022,25 @@ body{
.qseparator{
width: 16px;
}
.closeBtn {
position: relative;
display: flex;
justify-content: end;
border-radius: 50%;
border: none;
background-color: #2677e3;
color: #fff;
font-size: 0.5rem;
padding: 4px 6px;
top: 10px;
cursor: pointer;
right: 8px;
}
.customIframe {
width:1280px;
height:auto;
aspect-ratio: 16 / 9;
}
}
import React, { Fragment } from "react";
export default function IframeCustomModal ({embedContent, setEmbedContent}) {
return (
<Fragment>
<textarea
style={{width: '100%', height: '100%'}}
rows={18}
value={embedContent}
placeholder={'<iframe></iframe>'}
onInput={(e) => setEmbedContent(e.target.value)}
/>
</Fragment>
)
}
import React, { Fragment } from "react";
export default function IframeModal ({embedContent, setEmbedContent}) {
return (
<Fragment>
<input type="text" value={embedContent} placeholder={'https://'}
onInput={(e) => setEmbedContent(e.target.value)
}/>
<ul className={'atma-editor-soc-video'}>
<li className={'youtube'}/>
<li className={'vimeo'}/>
{/* <li className={'vk'}/> */}
<li className={'ok'}/>
<li className={'rutube'}/>
</ul>
</Fragment>
)
}
import React, { Fragment } from "react";
export default function RemoveIframeModal(){
return (
<Fragment>
</Fragment>
)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment