This commit is contained in:
2025-10-26 07:28:22 +04:00
parent e41e49f7ea
commit 3fc8329303
8 changed files with 348 additions and 72 deletions

View File

@@ -23,18 +23,18 @@ document.addEventListener('DOMContentLoaded', async () => {
darkMode.toggle();
});
// Initialize file tree
fileTree = new FileTree('fileTree', webdavClient);
fileTree.onFileSelect = async (item) => {
await loadFile(item.path);
};
// Initialize collection selector
collectionSelector = new CollectionSelector('collectionSelect', webdavClient);
collectionSelector.onChange = async (collection) => {
await fileTree.load();
};
await collectionSelector.load();
// Initialize file tree
fileTree = new FileTree('fileTree', webdavClient);
fileTree.onFileSelect = async (item) => {
await loadFile(item.path);
};
await fileTree.load();
// Initialize editor
@@ -68,6 +68,13 @@ document.addEventListener('DOMContentLoaded', async () => {
mermaid.initialize({ startOnLoad: true, theme: darkMode.isDark ? 'dark' : 'default' });
});
// Listen for column resize events to refresh editor
window.addEventListener('column-resize', () => {
if (editor && editor.editor) {
editor.editor.refresh();
}
});
/**
* File Operations
*/

102
static/js/column-resizer.js Normal file
View File

@@ -0,0 +1,102 @@
/**
* Column Resizer Module
* Handles draggable column dividers
*/
class ColumnResizer {
constructor() {
this.resizer1 = document.getElementById('resizer1');
this.resizer2 = document.getElementById('resizer2');
this.sidebarPane = document.getElementById('sidebarPane');
this.editorPane = document.getElementById('editorPane');
this.previewPane = document.getElementById('previewPane');
// Load saved dimensions
this.loadDimensions();
// Setup listeners
this.setupResizers();
}
setupResizers() {
this.resizer1.addEventListener('mousedown', (e) => this.startResize(e, 1));
this.resizer2.addEventListener('mousedown', (e) => this.startResize(e, 2));
}
startResize(e, resizerId) {
e.preventDefault();
const startX = e.clientX;
const startWidth1 = this.sidebarPane.offsetWidth;
const startWidth2 = this.editorPane.offsetWidth;
const containerWidth = this.sidebarPane.parentElement.offsetWidth;
const resizer = resizerId === 1 ? this.resizer1 : this.resizer2;
resizer.classList.add('dragging');
const handleMouseMove = (moveEvent) => {
const deltaX = moveEvent.clientX - startX;
if (resizerId === 1) {
// Resize sidebar and editor
const newWidth1 = Math.max(150, Math.min(40 * containerWidth / 100, startWidth1 + deltaX));
const newWidth2 = startWidth2 - (newWidth1 - startWidth1);
this.sidebarPane.style.flex = `0 0 ${newWidth1}px`;
this.editorPane.style.flex = `1 1 ${newWidth2}px`;
} else if (resizerId === 2) {
// Resize editor and preview
const newWidth2 = Math.max(250, Math.min(70 * containerWidth / 100, startWidth2 + deltaX));
const containerFlex = this.sidebarPane.offsetWidth;
this.editorPane.style.flex = `0 0 ${newWidth2}px`;
this.previewPane.style.flex = `1 1 auto`;
}
};
const handleMouseUp = () => {
resizer.classList.remove('dragging');
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
// Save dimensions
this.saveDimensions();
// Trigger editor resize
if (window.editor && window.editor.editor) {
window.editor.editor.refresh();
}
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}
saveDimensions() {
const dimensions = {
sidebar: this.sidebarPane.offsetWidth,
editor: this.editorPane.offsetWidth,
preview: this.previewPane.offsetWidth
};
localStorage.setItem('columnDimensions', JSON.stringify(dimensions));
}
loadDimensions() {
const saved = localStorage.getItem('columnDimensions');
if (!saved) return;
try {
const { sidebar, editor, preview } = JSON.parse(saved);
this.sidebarPane.style.flex = `0 0 ${sidebar}px`;
this.editorPane.style.flex = `0 0 ${editor}px`;
this.previewPane.style.flex = `1 1 auto`;
} catch (error) {
console.error('Failed to load column dimensions:', error);
}
}
}
// Initialize on DOM ready
document.addEventListener('DOMContentLoaded', () => {
window.columnResizer = new ColumnResizer();
});

View File

@@ -25,7 +25,7 @@ class FileTree {
const isDir = node.dataset.isdir === 'true';
// Toggle folder
if (e.target.closest('.tree-toggle')) {
if (e.target.closest('.tree-node-toggle')) {
this.toggleFolder(node);
return;
}
@@ -83,21 +83,23 @@ class FileTree {
}
createNodeElement(node, level) {
const nodeWrapper = document.createElement('div');
nodeWrapper.className = 'tree-node-wrapper';
nodeWrapper.style.marginLeft = `${level * 12}px`;
const div = document.createElement('div');
div.className = 'tree-node';
div.dataset.path = node.path;
div.dataset.isdir = node.isDirectory;
div.style.paddingLeft = `${level * 20 + 10}px`;
// Toggle arrow for folders
if (node.isDirectory) {
const toggle = document.createElement('span');
toggle.className = 'tree-toggle';
toggle.innerHTML = '<i class="bi bi-chevron-right"></i>';
toggle.className = 'tree-node-toggle';
toggle.innerHTML = '';
div.appendChild(toggle);
} else {
const spacer = document.createElement('span');
spacer.className = 'tree-spacer';
spacer.style.width = '16px';
spacer.style.display = 'inline-block';
div.appendChild(spacer);
@@ -105,45 +107,47 @@ class FileTree {
// Icon
const icon = document.createElement('i');
if (node.isDirectory) {
icon.className = 'bi bi-folder-fill';
icon.style.color = '#dcb67a';
} else {
icon.className = 'bi bi-file-earmark-text';
icon.style.color = '#6a9fb5';
}
icon.className = `bi ${node.isDirectory ? 'bi-folder-fill' : 'bi-file-earmark-text'} tree-node-icon`;
div.appendChild(icon);
// Content wrapper
const contentWrapper = document.createElement('div');
contentWrapper.className = 'tree-node-content';
// Name
const name = document.createElement('span');
name.className = 'tree-name';
name.className = 'tree-node-name';
name.textContent = node.name;
div.appendChild(name);
name.title = node.name; // Tooltip on hover
contentWrapper.appendChild(name);
// Size for files
if (!node.isDirectory && node.size) {
const size = document.createElement('span');
size.className = 'tree-size';
size.className = 'file-size-badge';
size.textContent = this.formatSize(node.size);
div.appendChild(size);
contentWrapper.appendChild(size);
}
return div;
div.appendChild(contentWrapper);
nodeWrapper.appendChild(div);
return nodeWrapper;
}
toggleFolder(nodeElement) {
const childContainer = nodeElement.querySelector('.tree-children');
if (!childContainer) return;
const toggle = nodeElement.querySelector('.tree-toggle i');
const toggle = nodeElement.querySelector('.tree-node-toggle');
const isExpanded = childContainer.style.display !== 'none';
if (isExpanded) {
childContainer.style.display = 'none';
toggle.className = 'bi bi-chevron-right';
toggle.innerHTML = '▶';
} else {
childContainer.style.display = 'block';
toggle.className = 'bi bi-chevron-down';
toggle.innerHTML = '▼';
}
}