const { remote, ipcRenderer, clipboard } = require('electron');
let offsetX = 0;
let offsetY = 0;
let isDragging = false;
document.addEventListener('mousedown', function(e) {
if (e.target.id === 'draggable') {
isDragging = true;
const { x, y } = remote.getCurrentWindow().getBounds();
offsetX = e.clientX - x;
offsetY = e.clientY - y;
}
});
document.addEventListener('mousemove', function(e) {
if (isDragging) {
remote.getCurrentWindow().setBounds({
x: e.screenX - offsetX,
y: e.screenY - offsetY,
width: remote.getCurrentWindow().getBounds().width,
height: remote.getCurrentWindow().getBounds().height
});
}
});
document.addEventListener('mouseup', function() {
if (isDragging) {
isDragging = false;
const bounds = remote.getCurrentWindow().getBounds();
ipcRenderer.send('save-bounds', bounds);
}
});
document.addEventListener('DOMContentLoaded', async () => {
try {
const clipboardData = await ipcRenderer.invoke('fetch-clipboard-data');
displayClipboardData(clipboardData);
} catch (err) {
console.error('Error fetching clipboard data:', err);
}
});
document.getElementById('clear-all-button').addEventListener('click', async () => {
try {
await ipcRenderer.invoke('delete-all-clipboard-data');
const clipboardData = await ipcRenderer.invoke('fetch-clipboard-data');
displayClipboardData(clipboardData);
} catch (err) {
console.error('Error deleting all data:', err);
}
});
function displayClipboardData(data) {
const container = document.getElementById('clipboard-container');
const amountOfData = document.getElementById('amount-of-data');
container.innerHTML = '';
amountOfData.textContent = `[${data.length}]`;
if (data.length === 0) {
container.innerHTML = '<p class="text-[13px]">No clipboard history available.<br>Try copying something!</p>';
return;
}
data.forEach(item => {
const itemElement = document.createElement('div');
itemElement.className = 'clipboard-item bg-zinc-700 p-2 mb-2 rounded text-[13px] relative';
const contentElement = document.createElement('div');
contentElement.textContent = `${item.content}`;
itemElement.appendChild(contentElement);
const menuButton = document.createElement('div');
menuButton.className = 'absolute top-0 right-2 h-full flex items-center';
menuButton.innerHTML = `
<svg class="w-4 h-4 fill-current text-white cursor-pointer" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M5 12c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zm7 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zm7 0c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/>
</svg>
`;
itemElement.addEventListener('click', () => {
clipboard.writeText(item.content);
window.close();
})
menuButton.addEventListener('click', (event) => {
event.stopPropagation();
showContextMenu(event, item);
});
itemElement.appendChild(menuButton);
container.appendChild(itemElement);
});
}
let contextMenuShowing = null;
function showContextMenu(event, item) {
if (contextMenuShowing) {
contextMenuShowing.remove();
contextMenuShowing = null;
}
const menuButton = event.currentTarget;
const rect = menuButton.getBoundingClientRect();
const contextMenu = document.createElement('div');
contextMenu.className = 'context-menu absolute bg-zinc-600 text-white rounded w-[75px]';
const options = ['Full Data', 'Delete', 'Pin'];
options.forEach(option => {
const optionElement = document.createElement('div');
optionElement.textContent = option;
switch (option) {
case "Delete":
optionElement.className = 'context-menu-option cursor-pointer py-1 px-1 rounded text-[12px] hover:bg-red-500 transition-colors duration-300';
break;
case "Pin":
optionElement.className = 'context-menu-option cursor-pointer py-1 px-1 rounded text-[12px] hover:bg-yellow-500 transition-colors duration-300';
break;
default:
optionElement.className = 'context-menu-option cursor-pointer py-1 px-1 rounded text-[12px] hover:bg-zinc-800 transition-colors duration-300';
break;
}
optionElement.addEventListener("click", async () => {
switch (option) {
case "Delete":
try {
await ipcRenderer.invoke('delete-clipboard-data', item);
const clipboardData = await ipcRenderer.invoke('fetch-clipboard-data');
displayClipboardData(clipboardData);
} catch (err) {
console.error('Error deleting all data:', err);
}
break;
case "Pin":
try {
await ipcRenderer.invoke('pin-clipboard-data', item);
const clipboardData = await ipcRenderer.invoke('fetch-clipboard-data');
displayClipboardData(clipboardData);
} catch (err) {
console.error('Error deleting all data:', err);
}
break;
case "Full Data":
break;
}
contextMenu.remove();
contextMenuShowing = null;
})
contextMenu.appendChild(optionElement);
});
contextMenu.style.left = `250px`;
contextMenu.style.top = `${rect.bottom - "10"}px`;
document.body.appendChild(contextMenu);
contextMenuShowing = contextMenu;
const closeMenuOnClickOutside = (event) => {
if (!contextMenu.contains(event.target)) {
document.removeEventListener('click', closeMenuOnClickOutside);
contextMenu.remove();
contextMenuShowing = null;
}
};
document.addEventListener('click', closeMenuOnClickOutside);
}
1 answer
Here's a breakdown of the functionality:
- The user can drag the window by clicking and dragging on the draggable area.
- On page load, the application fetches clipboard data and displays it.
- The user can clear all clipboard data by clicking the "clear all" button.
- Each clipboard item displayed has a context menu with options to view full data, delete the item, or pin the item.
- When clicking on a clipboard item, it copies the content to the clipboard and closes the window.
The context menu functionality allows the user to perform actions on individual clipboard items, such as deleting them or pinning them for future reference. The menu is displayed when the user clicks on the menu button next to each clipboard item.
Overall, this code snippet provides a functional clipboard manager application with the ability to interact with clipboard data and manage it effectively.