Make services reorderable (drag and drop)
This commit is contained in:
parent
d723dc2511
commit
c05b2eca8d
@ -21,6 +21,7 @@
|
||||
</div>
|
||||
|
||||
<ul id="service-selector"></ul>
|
||||
<div id="service-last-drag-position" class="hidden"></div>
|
||||
|
||||
<button id="add-button"><i class="fa fa-plus"></i></button>
|
||||
|
||||
|
@ -96,6 +96,19 @@ ipcRenderer.on('data', (event, appData, brandIcons, solidIcons, actualServices,
|
||||
createService(i);
|
||||
}
|
||||
|
||||
// Init drag last position
|
||||
const lastDragPosition = document.getElementById('service-last-drag-position');
|
||||
lastDragPosition.addEventListener('dragover', () => {
|
||||
const index = services.length;
|
||||
if (draggedId !== index && draggedId !== index - 1) {
|
||||
resetDrag();
|
||||
lastDragTarget = dragTargetId = index;
|
||||
lastDragPosition.classList.remove('hidden');
|
||||
lastDragPosition.classList.add('drag-target');
|
||||
}
|
||||
});
|
||||
|
||||
// Set active service
|
||||
if (actualSelectedService < 0 || actualSelectedService >= services.length) {
|
||||
actualSelectedService = 0;
|
||||
}
|
||||
@ -129,6 +142,31 @@ ipcRenderer.on('updateService', (e, id, data) => {
|
||||
}
|
||||
});
|
||||
|
||||
ipcRenderer.on('reorderService', (e, serviceId, targetId) => {
|
||||
const oldServices = services;
|
||||
services = [];
|
||||
|
||||
for (let i = 0; i < targetId; i++) {
|
||||
if (i !== serviceId) {
|
||||
services.push(oldServices[i]);
|
||||
}
|
||||
}
|
||||
services.push(oldServices[serviceId]);
|
||||
const newId = services.length - 1;
|
||||
for (let i = targetId; i < oldServices.length; i++) {
|
||||
if (i !== serviceId) {
|
||||
services.push(oldServices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('service-selector').innerHTML = '';
|
||||
for (let i = 0; i < services.length; i++) {
|
||||
services[i].li = undefined;
|
||||
createService(i);
|
||||
}
|
||||
setActiveService(newId);
|
||||
});
|
||||
|
||||
ipcRenderer.on('deleteService', (e, id) => {
|
||||
const nav = document.querySelector('#service-selector');
|
||||
|
||||
@ -199,6 +237,55 @@ function createService(index, nextNavButton) {
|
||||
if (service.autoLoad) {
|
||||
loadService(index, service);
|
||||
}
|
||||
|
||||
initDrag(index, li);
|
||||
}
|
||||
|
||||
let draggedId;
|
||||
let lastDragTarget = -1;
|
||||
let dragTargetId = -1;
|
||||
let dragTargetCount = 0;
|
||||
|
||||
function initDrag(index, li) {
|
||||
li.serviceId = index;
|
||||
li.draggable = true;
|
||||
li.addEventListener('dragstart', (event) => {
|
||||
draggedId = index;
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
document.getElementById('service-last-drag-position').classList.remove('hidden');
|
||||
});
|
||||
li.addEventListener('dragover', () => {
|
||||
if (draggedId !== index && draggedId !== index - 1) {
|
||||
resetDrag();
|
||||
lastDragTarget = dragTargetId = index;
|
||||
document.getElementById('service-last-drag-position').classList.remove('hidden');
|
||||
li.classList.add('drag-target');
|
||||
}
|
||||
});
|
||||
li.addEventListener('dragend', () => {
|
||||
reorderService(draggedId, lastDragTarget);
|
||||
resetDrag();
|
||||
});
|
||||
}
|
||||
|
||||
function resetDrag() {
|
||||
lastDragTarget = -1;
|
||||
dragTargetId = -1;
|
||||
dragTargetCount = 0;
|
||||
document.getElementById('service-selector').querySelectorAll('li').forEach(li => {
|
||||
li.classList.remove('drag-target');
|
||||
});
|
||||
const lastDragPosition = document.getElementById('service-last-drag-position');
|
||||
lastDragPosition.classList.remove('drag-target');
|
||||
lastDragPosition.classList.add('hidden');
|
||||
}
|
||||
|
||||
function reorderService(serviceId, targetId) {
|
||||
console.log('Reordering service', serviceId, targetId);
|
||||
if (targetId >= 0) {
|
||||
setActiveService(null);
|
||||
ipcRenderer.send('reorderService', serviceId, targetId);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
@ -215,7 +302,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
function setActiveService(serviceId) {
|
||||
const currentService = services[serviceId];
|
||||
process.nextTick(() => {
|
||||
if (currentService) {
|
||||
loadService(serviceId, currentService);
|
||||
}
|
||||
|
||||
// Hide previous service
|
||||
if (services[selectedService] && services[selectedService].view) {
|
||||
@ -223,7 +312,9 @@ function setActiveService(serviceId) {
|
||||
}
|
||||
|
||||
// Show service
|
||||
if (currentService) {
|
||||
currentService.view.classList.add('active');
|
||||
}
|
||||
|
||||
// Save active service ID
|
||||
selectedService = serviceId;
|
||||
|
@ -10,6 +10,51 @@ body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#service-selector [draggable] {
|
||||
user-select: none;
|
||||
background-color: rgb(43, 43, 43);
|
||||
}
|
||||
|
||||
#service-selector [draggable] img {
|
||||
-webkit-user-drag: none;
|
||||
user-drag: none;
|
||||
}
|
||||
|
||||
#service-selector .drag-target button {
|
||||
height: 144px;
|
||||
padding-top: 88px;
|
||||
}
|
||||
|
||||
#service-selector .drag-target button::after,
|
||||
#service-last-drag-position.drag-target {
|
||||
content: "";
|
||||
height: 72px;
|
||||
border: 1px dashed #fff;
|
||||
box-sizing: border-box;
|
||||
|
||||
background-color: rgb(43, 43, 43);
|
||||
}
|
||||
#service-selector .drag-target button::after {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
#service-last-drag-position:not(.hidden):not(.drag-target) {
|
||||
display: block;
|
||||
padding: 16px 4px;
|
||||
background-color: #fff5;
|
||||
}
|
||||
#service-last-drag-position:not(.drag-target)::after {
|
||||
content: "";
|
||||
display: block;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
#service-selector .drag-target::after {
|
||||
top: 75% !important;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline-color: rgb(118, 93, 176);
|
||||
}
|
||||
|
21
src/main.js
21
src/main.js
@ -158,6 +158,27 @@ function createWindow() {
|
||||
window.webContents.send('deleteService', id);
|
||||
});
|
||||
|
||||
ipcMain.on('reorderService', (e, serviceId, targetId) => {
|
||||
console.log('Reordering services', serviceId, targetId);
|
||||
|
||||
const oldServices = config.services;
|
||||
config.services = [];
|
||||
|
||||
for (let i = 0; i < targetId; i++) {
|
||||
if (i !== serviceId) {
|
||||
config.services.push(oldServices[i]);
|
||||
}
|
||||
}
|
||||
config.services.push(oldServices[serviceId]);
|
||||
for (let i = targetId; i < oldServices.length; i++) {
|
||||
if (i !== serviceId) {
|
||||
config.services.push(oldServices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
e.reply('reorderService', serviceId, targetId);
|
||||
});
|
||||
|
||||
ipcMain.on('updateWindowTitle', (event, serviceId, viewTitle) => {
|
||||
if (serviceId === null) {
|
||||
window.setTitle(Meta.title);
|
||||
|
Loading…
Reference in New Issue
Block a user