Closed TobiasKrais closed 2 months ago
the feature will be support in the Business Version.
I think this feature is too simple to be added to Business Version. Thus I add a simple JS code to the aieditor configuration to add the feature for me:
onCreated:(aiEditor) => {
// replace span in ai menu with bodo icon after aieditor is loaded
let aiMenu = document.querySelector('.menu-ai');
// continue only if aiMenu exists and id is tippy
if (aiMenu && aiMenu.id === 'tippy') {
// get direct child elements of aiMenu
let children = aiMenu.children;
for (let i = 0; i < children.length; i++) {
if (children[i].tagName.toLowerCase() === 'span') {
// get bodo icon and replace span with it
children[i].replaceWith(getBodoIcon());
break; // exit loop after replacing the first span
}
}
}
// Target elements to be observed
const targetNodes = document.querySelectorAll('.aie-container');
// Configuration options for the observer
const config = { childList: true, subtree: true };
// Callback function to be executed when mutations are observed
const callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
for (let node of mutation.addedNodes) {
if (node.nodeType === 1 && node.id && node.id.match(/^tippy-\d+$/)) {
const overlay = document.getElementById(node.id);
// Check if the overlay contains a child with the class 'aie-ai-panel-body' or 'aie-translate-result-panel'
let panelBody = overlay.querySelector('.aie-ai-panel-body');
if (!panelBody) {
panelBody = overlay.querySelector('.aie-translate-result-panel');
}
if (!panelBody) {
continue;
}
let parent = panelBody;
while (parent && parent !== overlay) {
parent = parent.parentNode;
}
if (parent === overlay) {
// Create bar with button
const bar = document.createElement('div');
bar.classList.add('aie-ai-panel-header');
// add move button
const moveButton = document.createElement('span');
moveButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18 11V8L22 12L18 16V13H13V18H16L12 22L8 18H11V13H6V16L2 12L6 8V11H11V6H8L12 2L16 6H13V11H18Z"></path></svg>';
bar.appendChild(moveButton);
// add close button
const closeButton = document.createElement('span');
closeButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M11.9997 10.5865L16.9495 5.63672L18.3637 7.05093L13.4139 12.0007L18.3637 16.9504L16.9495 18.3646L11.9997 13.4149L7.04996 18.3646L5.63574 16.9504L10.5855 12.0007L5.63574 7.05093L7.04996 5.63672L11.9997 10.5865Z"></path></svg>';
bar.appendChild(closeButton);
panelBody.insertBefore(bar, panelBody.firstChild);
let isDragging = false;
let offsetX, offsetY;
// Start mousedown event when the user begins dragging
moveButton.addEventListener('mousedown', function(e) {
isDragging = true;
// Save mouse position relative to the overlay
offsetX = e.clientX - overlay.offsetLeft;
offsetY = e.clientY - overlay.offsetTop;
moveButton.style.cursor = 'grabbing';
});
// Trigger mousemove event when the overlay is moved
document.addEventListener('mousemove', function(e) {
if (isDragging) {
// Update overlay position
overlay.style.left = (e.clientX - offsetX) + 'px';
overlay.style.top = (e.clientY - offsetY) + 'px';
}
});
// End mouseup event when the mouse is released
document.addEventListener('mouseup', function() {
isDragging = false;
moveButton.style.cursor = 'pointer';
});
// Close button deletes the current tippy element
closeButton.addEventListener('click', function() {
overlay.remove();
});
}
}
}
}
}
};
// Create and start observer instances
targetNodes.forEach(function(targetNode) {
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
},
and
.aie-ai-panel-header {
background-color: #fafafa;
border-bottom: 1px solid;
border-color: var(--aie-input-border-color);
height: 25px;
padding: 5px;
text-align: right;
}
.aie-ai-panel-header svg {
height: 20px;
padding-left: 5px;
}
@TobiasKrais ,This is how I understand this feature: Behind the feature, there may often be other more complex and refined requirements.
For example, the panel needs to be pinned, so that when the user clicks on the editor, the window cannot disappear. In this way, the user can insert the AI content into any position of the editor.
Of course, in addition to this, with the continuous iteration of the editor, more features may be added to the drag position, and the drag position may also change.
OK, now I understand the idea you have. I saw the demo site but didn't see the drag area. I think the drag area and close button should be in free version. Why? The preview window is sometimes directly above the content you marked. And if you want to recheck the original content, its not possible. And with the solution above, everyone can easily get the feature free. The pin button is really a good idea for business version.
Please allow moving the preview dialogue of the bubble menu and the translation menu. Thus the user is able to move the dialogue in case the marked content is hidden behind the dialogue.