about summary refs log blame commit diff stats
path: root/html/file-system/index.html
blob: 75a7daa3825f1d054a8ec0e0660f3164deeb3f07 (plain) (tree)
1
2
3
4
5
6




                                                                          
                                                

































                                           
                 


                                

                             
                                              

                              













                                                     
                                



                                           

                                      



                       
                        




                               




                              


                          
                                     



                                   
                             













                                       
                     






                                   






































                                                                      



                                           





































                                                       
                             

























                                    



                              
















































































                                                     












                                                
                         




































                                                   
                      




                                               
                           
































                                                   
                      








                                               


















                                     




















                                              

                               
                                             






                                       






                                  

                                



                                                  
                        


                               



                                  



                              
                          




























                                                                         
 





                                   
                           
         







                                                                 
                                              



                                                  
                                                                             
                                
                                                                   
                                 
                                 
                                                    

                                                                                                    

          

                 









                                                                                                                 
                                 
                                                                                               



                                                                                             
                                                                               


                                                                             

      





                                                                               
        


                                                       
 
                                                                                              
 


                                 

                           

                                        
  
 
                                                       
 













                                                                  
 





                                                      

     







                                                                

                   


                                                                                            
 
                                            









                                                 




                                                               
 


                                                                   
 



                                     
 





                                                     
     
  
 







                                                                            
     
  
 
                          


                                                                               
                                             
                                    

               
 



                                                              
 
                                                   
                                                  





                                             


                                                                 
                 
     
                      
  
 




                                                                                                     
     
                      
  
 
                         




                                                           
 

                                                                                                                       
 






                                                                                      
     
                      
  
 





                                                                                                   
     
  
 



                                                                          












































                                                                                                       

                                                     

















                                                                         


                                


                                           
                                                                             
                 














                                                                                           
                               
                                       

                                
                                                                              




                                       
                 
     







                                                                                    
 
                                                               

                                                           

                                                           


















                                                                          













                                                                           
                                                                                                  
                                                              

                                                                                  




                                                          
                      
  
 















                                                           
                        
    
                                                                









































                                                                     


























































                                                                                                 
















                                                                                                  
                                         




                                                 
                                              
                                             

                                                


                        
                                                    

                                                                        
                                               
                                              
                                               





                                                                         
                                               

                                                






                                                                           
                                                       

                                                         






                                               



                                          













                                                                               






















                                                               
                      













                                                                        





















                                                                                  







                                                                                     
        


                                                                                                     
                                                                                               

















                                                                                         



                                           
         



         
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Folders in Folders in Folders</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: beige;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        #navigation {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            margin: 0.625em 0;
        }
        #navigation button {
            margin: 0.3125em;
            padding: 0.625em 0.9375em;
            font-size: 1em;
            flex-grow: 1;
            min-width: 7.5em;
        }
        #currentPath {
            font-weight: bold;
            margin: 0.625em 0;
        }
        ul {
            list-style-type: none;
            width: 100%;
            max-width: 37.5em;
        }
        li {
            margin: 0.3125em 0;
            cursor: pointer;
        }
        .folder {
            display: flex;
            align-items: center;
            padding: 0.5em;
            margin: 0;
            border-radius: 0;
            transition: background-color 0.2s;
            width: 100%;
            padding-left: 2em;
        }
        .folder:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }
        .folder.dragging {
            opacity: 0.5;
        }
        .folder.drag-over {
            background-color: rgba(0, 120, 250, 0.1);
            border: 2px dashed #0078fa;
        }
        .folder::before {
            content: "📁";
            margin-right: 0.5em;
            margin-left: -1.5em;
        }
        ul {
            padding-left: 1.5em;
            border-left: 1px solid #e0e0e0;
            margin: 0;
            width: calc(100% - 1.5em);
        }
        li {
            margin: 0;
            padding: 0;
            width: 100%;
        }
        #editor {
            margin-top: 1.25em;
            width: 100%;
            max-width: 37.5em;
            cursor: move;
            min-width: 200px;
            min-height: 150px;
            resize: both;
            overflow: auto;
        }
        #editor textarea {
            width: 100%;
            height: calc(100% - 3em);
            font-size: 1em;
            padding: 0.625em;
            box-sizing: border-box;
            resize: none;
            margin-bottom: 0;
        }
        h1 {
            text-align: center;
            font-size: 1.5em;
            margin-top: 0.625em;
        }
        @media (max-width: 37.5em) {
            h1 {
                font-size: 1.25em;
            }
            #navigation button {
                font-size: 0.875em;
                padding: 0.5em 0.625em;
            }
            .folder {
                font-size: 1em;
            }
            #editor textarea {
                height: 7.5em;
                font-size: 0.875em;
            }
        }
        #navigation {
            display: none; /* Hide the button navigation by default */
        }

        .context-menu {
            position: fixed;
            background: white;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
            padding: 0.5em 0;
            min-width: 150px;
            z-index: 1000;
            display: none;
        }

        .context-menu.active {
            display: block;
        }

        .context-menu-item {
            padding: 0.5em 1em;
            cursor: pointer;
            display: flex;
            align-items: center;
        }

        .context-menu-item:hover {
            background-color: #f0f0f0;
        }

        .context-menu-item::before {
            margin-right: 0.5em;
        }

        .context-menu-item.new-folder::before {
            content: "📁";
        }

        .context-menu-item.rename::before {
            content: "✏️";
        }

        .context-menu-item.copy::before {
            content: "📋";
        }

        .context-menu-item.paste::before {
            content: "📥";
        }

        .context-menu-item.delete::before {
            content: "🗑️";
        }

        #editor {
            display: none; /* Hide editor by default */
            position: fixed;
            right: 20px;
            top: 20px;
            background: white;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 1em;
            box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
        }

        .folder.selected {
            background-color: rgba(0, 120, 250, 0.1);
        }

        #fileSystemContainer {
            width: 100%;
            max-width: 37.5em;
            min-height: 300px;
            background: white;
            border: 1px solid #e0e0e0;
            border-radius: 4px;
            padding: 1em;
            margin-top: 1em;
            box-sizing: border-box;
            overflow: hidden;
        }

        .empty-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 200px;
            color: #666;
            text-align: center;
        }

        .empty-state::before {
            content: "📁";
            font-size: 3em;
            margin-bottom: 0.5em;
            opacity: 0.5;
        }

        .empty-state-text {
            font-size: 1.1em;
            margin-bottom: 1em;
        }

        .root-folder {
            padding: 0.5em;
            padding-left: 2em;
            margin: 0;
            width: 100%;
            border-radius: 0;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .root-folder:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .root-folder.selected {
            background-color: rgba(0, 120, 250, 0.1);
        }

        #editorHeader {
            padding: 0.5em;
            background-color: #f5f5f5;
            border-bottom: 1px solid #ccc;
            margin: -1em -1em 1em -1em;
            border-radius: 4px 4px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 0.5em;
        }

        #editorHeader h2 {
            margin: 0;
            font-size: 1.1em;
        }

        .editor-controls {
            display: flex;
            gap: 0.3em;
        }

        .editor-button {
            cursor: pointer;
            padding: 0.2em 0.5em;
            border-radius: 3px;
            font-size: 0.9em;
            color: #666;
        }

        .editor-button:hover {
            background-color: #e0e0e0;
        }

        .resize-handle {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: #f5f5f5;
            border: 1px solid #ccc;
        }

        .resize-handle.se {
            right: 0;
            bottom: 0;
            cursor: se-resize;
        }

        .resize-handle.sw {
            left: 0;
            bottom: 0;
            cursor: sw-resize;
        }

        .resize-handle.ne {
            right: 0;
            top: 0;
            cursor: ne-resize;
        }

        .resize-handle.nw {
            left: 0;
            top: 0;
            cursor: nw-resize;
        }

        .resize-handle:hover {
            background-color: #e0e0e0;
        }

        /* Update the inchworm styles */
        .inchworm {
            position: absolute;
            top: -16px;
            left: 0;
            font-size: 22px;
            animation: inch 18s infinite linear;
            transform-origin: center;
            color: green;
        }

        @keyframes inch {
            /* Forward */
            0% { 
                left: 0; 
                transform: scaleX(1) scaleY(1);
            }
            5% { 
                left: 0; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            10% { 
                left: 30px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            15% { 
                left: 30px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            20% { 
                left: 60px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            25% { 
                left: 60px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            30% { 
                left: 90px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            35% { 
                left: 90px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            40% { 
                left: 120px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            
            /* Rest */
            42% { 
                left: 120px; 
                transform: scaleX(1) scaleY(1);
            }
            
            /* Backwards */
            45% { 
                left: 120px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            50% { 
                left: 90px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            55% { 
                left: 90px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            60% { 
                left: 60px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            65% { 
                left: 60px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            70% { 
                left: 30px; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            75% { 
                left: 30px; 
                transform: scaleX(0.4) scaleY(1.4);
            }
            80% { 
                left: 0; 
                transform: scaleX(1.3) scaleY(0.7);
            }
            
            /* Rest */
            85% { 
                left: 0; 
                transform: scaleX(1) scaleY(1);
            }
            100% { 
                left: 0; 
                transform: scaleX(1) scaleY(1);
            }
        }

        .folder.editing {
            padding: 0;
            margin: 0;
        }

        .folder.editing input {
            font-size: 1em;
            padding: 0.5em;
            margin: 0.25em 0;
            width: calc(100% - 2em);
            border: 1px solid #ccc;
            border-radius: 4px;
            outline: none;
        }

        .folder.editing input:focus {
            border-color: #0078fa;
        }

        #viewControls {
            position: absolute;
            top: 1em;
            right: 1em;
        }

        .view-toggle {
            padding: 0.5em;
            border: 1px solid #ccc;
            border-radius: 4px;
            background: white;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .view-toggle:hover {
            background-color: #f0f0f0;
        }

        #breadcrumbs {
            padding: 0.5em 1em;
            margin: 0;
            border-bottom: 1px solid #e0e0e0;
            display: none;
            text-align: left;
            background-color: #f8f8f8;
            border-radius: 4px 4px 0 0;
            white-space: normal;
            word-break: keep-all;
            line-height: 1.8;
        }

        .breadcrumb-item {
            display: inline-block;
            cursor: pointer;
            padding: 0.2em 0.5em;
            border-radius: 3px;
            color: #666;
            white-space: nowrap;
        }

        .breadcrumb-item:hover {
            background-color: rgba(0, 0, 0, 0.05);
            color: #000;
        }

        .breadcrumb-separator {
            margin: 0 0.2em;
            color: #999;
            user-select: none;
            display: inline-block;
        }

        /* Grid view styles */
        .grid-view {
            display: none;
            grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
            gap: 1em;
            padding: 1em;
        }

        .grid-folder {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 1em;
            cursor: pointer;
            border-radius: 4px;
            text-align: center;
        }

        .grid-folder:hover {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .grid-folder-icon {
            font-size: 2em;
            margin-bottom: 0.5em;
        }

        .grid-folder-name {
            font-size: 0.9em;
            word-break: break-word;
            max-width: 100%;
        }

        #fileSystemContainer {
            display: flex;
            flex-direction: column;
        }

        .grid-view {
            padding-top: 0;
        }
    </style>
</head>
<body>

<div id="navigation">
    <button onclick="goToRoot()">Go to Root</button>
    <button onclick="goUp()">Go Up One Level</button>
    <button onclick="createFolderPrompt()">Create Folder</button>
    <button onclick="copyItem()">Copy</button>
    <button onclick="pasteItem()">Paste</button>
    <button onclick="deleteItem()">Delete</button>
</div>

<div id="fileSystemContainer" oncontextmenu="showContextMenu(event, 'root')">
    <div id="breadcrumbs"></div>
    <div class="root-folder" onclick="selectFolder('root')">~</div>
    <ul id="fileSystemTree"></ul>
    <div class="grid-view"></div>
    <div class="empty-state" style="display: none;">
        <div class="empty-state-text">No folders yet.</div>
        <div class="empty-state-hint">Right-click and use the context menu to create a folder.</div>
    </div>
</div>

<div id="editor">
    <div id="editorHeader">
        <h2><span id="editorPath">/</span></h2>
        <div class="editor-controls">
            <span class="editor-button" onclick="setEditorSize('normal')" title="Normal Size"></span>
            <span class="editor-button" onclick="setEditorSize('vertical')" title="Vertical Split"></span>
            <span class="editor-button" onclick="setEditorSize('horizontal')" title="Horizontal Split"></span>
            <span class="editor-button" onclick="setEditorSize('full')" title="Full Screen"></span>
            <span class="editor-button" id="closeEditor" onclick="hideEditor()" title="Close"></span>
        </div>
    </div>
    <div class="inchworm">O</div>
    <textarea id="folderContent" placeholder="Select a folder to edit its contents"></textarea>
</div>

<div class="context-menu" id="contextMenu">
    <div class="context-menu-item new-folder" onclick="createFolderPrompt()">New Folder</div>
    <div class="context-menu-item rename" onclick="renameFolder()">Rename</div>
    <div class="context-menu-item copy" onclick="copyItem()">Copy</div>
    <div class="context-menu-item paste" onclick="pasteItem()">Paste</div>
    <div class="context-menu-item delete" onclick="deleteItem()">Delete</div>
</div>

<div id="viewControls">
    <button class="view-toggle" onclick="toggleView()" title="Toggle View">
        <span class="tree-icon">🌳</span>/<span class="grid-icon">📱</span>
    </button>
</div>

<script>
const initialState = () => ({
    root: { type: 'folder', children: {}, content: '' }
});

const loadFileSystem = () => JSON.parse(localStorage.getItem('fileSystem')) || initialState();

const state = {
    fileSystem: loadFileSystem(),
    currentFolderPath: 'root',
    copiedFolderData: null,
    copiedItemPath: null,
    draggedPath: null,
    viewMode: 'tree' // 'tree' or 'grid'
};

const clone = (obj) => JSON.parse(JSON.stringify(obj));

const updateFileSystem = (newFileSystem) => {
    state.fileSystem = newFileSystem;
    saveFileSystem(newFileSystem);
};

const getFolder = (path, fileSystem = state.fileSystem) => {
    const parts = path.split('/').filter(part => part !== 'root');
    return parts.reduce((current, part) => {
        if (!current || !current.children[part]) {
            return null;
        }
        return current.children[part];
    }, fileSystem.root);
};

const updateFolder = (fileSystem, path, updateFn) => {
    const rootCopy = clone(fileSystem);
    const folderToUpdate = getFolder(path, rootCopy);
    if (!folderToUpdate) {
        alert(`Folder not found for path: ${path}`);
        return null;
    }

    updateFn(folderToUpdate);
    return rootCopy;
};

const addFolder = (path, name, folderData, fileSystem) => {
    return updateFolder(fileSystem, path, (folder) => {
        if (folder.children[name]) {
            alert(`Folder with name "${name}" already exists.`);
            return;
        }
        folder.children[name] = folderData || { type: 'folder', children: {}, content: '' };
    });
};

const deleteFolder = (path, fileSystem) => {
    if (path === 'root') {
        return fileSystem;
    }

    if (!path.includes('/')) {
        const newFileSystem = clone(fileSystem);
        delete newFileSystem.root.children[path];
        return newFileSystem;
    }

    const [parentPath, folderName] = path.split(/\/([^\/]+)$/);
    return updateFolder(fileSystem, parentPath, (folder) => {
        delete folder.children[folderName];
    });
};

const saveFileSystem = (fileSystem) => {
    localStorage.setItem('fileSystem', JSON.stringify(fileSystem));
};

const goToRoot = () => {
    state.currentFolderPath = 'root';
    render();
};

const goUp = () => {
    const parts = state.currentFolderPath.split('/');
    if (parts.length > 1) {
        parts.pop();
        state.currentFolderPath = parts.join('/');
        render();
    }
};

const createFolder = (path, name) => {
    const updatedFileSystem = addFolder(path, name, null, state.fileSystem);
    if (updatedFileSystem) {
        updateFileSystem(updatedFileSystem);
        render();
    } else {
        console.error('Error creating folder', path, name);
        alert('Error creating folder');
    }
};

const deleteItem = () => {
    console.log('Attempting to delete:', state.currentFolderPath); // Debug log
    
    // Basic validation
    if (state.currentFolderPath === 'root') {
        alert("Can't delete root!");
        return;
    }

    // Get parent path and folder name
    const parts = state.currentFolderPath.split('/');
    const folderName = parts[parts.length - 1];
    const parentPath = parts.slice(0, -1).join('/') || 'root';

    // Create new file system and delete the folder
    const newFileSystem = clone(state.fileSystem);
    const parent = parentPath === 'root' ? 
        newFileSystem.root : 
        getFolder(parentPath, newFileSystem);

    if (parent && parent.children) {
        delete parent.children[folderName];
        updateFileSystem(newFileSystem);
        state.currentFolderPath = parentPath;
        document.getElementById('editor').style.display = 'none';
        render();
    }
    hideContextMenu();
};

const copyItem = () => {
    const folder = getFolder(state.currentFolderPath);
    if (folder) {
        state.copiedFolderData = clone(folder); // Store a deep copy of the folder
        state.copiedItemPath = state.currentFolderPath; // Store the path so that we can remove later
    }
    hideContextMenu();
};

const pasteItem = () => {
    if (!state.copiedItemPath || !state.copiedFolderData) {
        alert('No item to paste');
        hideContextMenu();
        return;
    }

    const [oldPath, folderName] = state.copiedItemPath.split(/\/([^\/]+)$/);
    const updatedFileSystem = addFolder(state.currentFolderPath, folderName, state.copiedFolderData, state.fileSystem);

    if (updatedFileSystem) {
        updateFileSystem(deleteFolder(oldPath, updatedFileSystem)); // Remove original
        state.copiedFolderData = null; // Clear the copied data
        state.copiedItemPath = null;
        render();
    } else {
        alert('Error pasting item');
    }
    hideContextMenu();
};

const saveFolderContent = () => {
    const updatedFileSystem = updateFolder(state.fileSystem, state.currentFolderPath, (folder) => {
        folder.content = document.getElementById('folderContent').value;
    });
    if (updatedFileSystem) {
        updateFileSystem(updatedFileSystem);
    }
};

document.getElementById('folderContent').addEventListener('input', () => {
    saveFolderContent();
});

const handleDragStart = (e, path) => {
    e.target.classList.add('dragging');
    e.dataTransfer.setData('text/plain', path);
    state.draggedPath = path;
};

const handleDragEnd = (e) => {
    e.target.classList.remove('dragging');
    document.querySelectorAll('.folder').forEach(f => {
        f.classList.remove('drag-over');
    });
};

const handleDragOver = (e) => {
    e.preventDefault();
    e.target.classList.add('drag-over');
};

const handleDragLeave = (e) => {
    e.target.classList.remove('drag-over');
};

const handleDrop = (e, targetPath) => {
    e.preventDefault();
    e.target.classList.remove('drag-over');
    
    if (!state.draggedPath || state.draggedPath === targetPath) return;
    
    const sourcePath = state.draggedPath;
    const sourceFolder = getFolder(sourcePath);
    
    if (!sourceFolder) return;
    
    // Create a copy of the dragged folder
    const [, folderName] = sourcePath.split(/\/([^\/]+)$/);
    const updatedFileSystem = addFolder(targetPath, folderName, clone(sourceFolder), state.fileSystem);
    
    if (updatedFileSystem) {
        // Remove the original folder
        updateFileSystem(deleteFolder(sourcePath, updatedFileSystem));
        state.draggedPath = null;
        render();
    }
};

const renderFolderTree = (folder, path = 'root') => {
    const entries = Object.entries(folder.children);
    return entries.length ? entries.map(([name, item]) => {
        const fullPath = path === 'root' ? name : `${path}/${name}`;
        return `
            <li>
                <div class="folder" 
                    onclick="selectFolder('${fullPath}')"
                    oncontextmenu="showContextMenu(event, '${fullPath}')"
                    draggable="true"
                    ondragstart="handleDragStart(event, '${fullPath}')"
                    ondragend="handleDragEnd(event)"
                    ondragover="handleDragOver(event)"
                    ondragleave="handleDragLeave(event)"
                    ondrop="handleDrop(event, '${fullPath}')"
                >${name}</div>
                <ul>${renderFolderTree(item, fullPath)}</ul>
            </li>
        `;
    }).join('') : '';
};

const selectFolder = (path) => {
    // Don't proceed if no path is provided
    if (!path) return;

    const folder = path === 'root' ? state.fileSystem.root : getFolder(path);
    if (folder) {
        // Remove previous selection
        document.querySelectorAll('.folder.selected, .root-folder.selected').forEach(f => {
            f.classList.remove('selected');
        });
        
        // Add selection to current folder
        if (path === 'root') {
            document.querySelector('.root-folder').classList.add('selected');
        } else {
            const folderElement = document.querySelector(`.folder[onclick*="${path}"]`);
            if (folderElement) {
                folderElement.classList.add('selected');
            }
        }
        
        // Set the current path
        state.currentFolderPath = path;
        
        // Update editor content
        document.getElementById('folderContent').value = folder.content || '';
        
        // Show editor in normal size
        editor.style.display = 'block';
        setEditorSize('normal');
        
        render();
    }
};

const render = () => {
    if (!state.fileSystem.root) {
        console.error('File system is not initialized correctly', state.fileSystem);
        alert('File system is not initialized correctly');
        return;
    }

    // Show/hide breadcrumbs and root folder based on view mode
    document.getElementById('breadcrumbs').style.display = 
        state.viewMode === 'grid' ? 'block' : 'none';
    document.querySelector('.root-folder').style.display = 
        state.viewMode === 'grid' ? 'none' : 'block';

    // Update current folder content based on view mode
    if (state.viewMode === 'tree') {
        document.getElementById('fileSystemTree').style.display = 'block';
        document.querySelector('.grid-view').style.display = 'none';
        document.getElementById('fileSystemTree').innerHTML = 
            renderFolderTree(state.fileSystem.root);
    } else {
        document.getElementById('fileSystemTree').style.display = 'none';
        document.querySelector('.grid-view').style.display = 'grid';
        const currentFolder = state.currentFolderPath === 'root' ? 
            state.fileSystem.root : 
            getFolder(state.currentFolderPath);
        document.querySelector('.grid-view').innerHTML = 
            renderGridView(currentFolder);
    }

    renderBreadcrumbs();

    // Update path displays
    const currentPath = state.currentFolderPath.replace('root', '') || '/';
    document.title = `Folder: ${currentPath}`;
    document.getElementById('editorPath').textContent = currentPath;
    
    // Update root folder selection state
    const rootFolder = document.querySelector('.root-folder');
    if (state.currentFolderPath === 'root') {
        rootFolder.classList.add('selected');
    } else {
        rootFolder.classList.remove('selected');
    }

    // Update folder tree and empty state
    document.getElementById('fileSystemTree').innerHTML = renderFolderTree(state.fileSystem.root);
    const emptyState = document.querySelector('.empty-state');
    const hasNoFolders = Object.keys(state.fileSystem.root.children).length === 0;
    emptyState.style.display = hasNoFolders ? 'flex' : 'none';
};

const createFolderPrompt = () => {
    const name = prompt('Enter folder name:');
    if (name) createFolder(state.currentFolderPath, name);
    hideContextMenu();
};

const contextMenu = document.getElementById('contextMenu');

// Prevent default context menu
document.addEventListener('contextmenu', (e) => {
    e.preventDefault();
});

// Hide context menu when clicking outside
document.addEventListener('click', (e) => {
    if (!contextMenu.contains(e.target)) {
        contextMenu.classList.remove('active');
    }
});

const showContextMenu = (e, path) => {
    e.preventDefault();
    e.stopPropagation();
    
    // Just update the current path without selecting the folder
    if (path) {
        state.currentFolderPath = path;
    }
    
    // Position the menu
    contextMenu.style.left = `${e.pageX}px`;
    contextMenu.style.top = `${e.pageY}px`;
    
    // Show the menu
    contextMenu.classList.add('active');
    
    // Enable/disable paste option
    const pasteOption = contextMenu.querySelector('.paste');
    pasteOption.style.opacity = state.copiedFolderData ? '1' : '0.5';
    
    // Prevent menu from going off-screen
    const rect = contextMenu.getBoundingClientRect();
    if (rect.right > window.innerWidth) {
        contextMenu.style.left = `${e.pageX - rect.width}px`;
    }
    if (rect.bottom > window.innerHeight) {
        contextMenu.style.top = `${e.pageY - rect.height}px`;
    }
};

// Add double-click handler to show/hide editor
document.addEventListener('dblclick', (e) => {
    if (!e.target.classList.contains('folder')) {
        document.getElementById('editor').style.display = 'none';
    }
});

const editor = document.getElementById('editor');
const editorHeader = document.getElementById('editorHeader');

let isDragging = false;
let currentX;
let currentY;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;

const dragStart = (e) => {
    if (e.target.closest('#closeEditor') || e.target.classList.contains('resize-handle')) return;
    
    if (e.type === "touchstart") {
        initialX = e.touches[0].clientX - xOffset;
        initialY = e.touches[0].clientY - yOffset;
    } else {
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;
    }

    if (e.target === editorHeader || e.target.closest('#editorHeader')) {
        isDragging = true;
    }
};

const dragEnd = () => {
    initialX = currentX;
    initialY = currentY;
    isDragging = false;
};

const drag = (e) => {
    if (isDragging) {
        e.preventDefault();

        if (e.type === "touchmove") {
            currentX = e.touches[0].clientX - initialX;
            currentY = e.touches[0].clientY - initialY;
        } else {
            currentX = e.clientX - initialX;
            currentY = e.clientY - initialY;
        }

        xOffset = currentX;
        yOffset = currentY;

        setTranslate(currentX, currentY, editor);
    }
};

const setTranslate = (xPos, yPos, el) => {
    el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
};

const hideEditor = () => {
    editor.style.display = 'none';
};

// Add event listeners for drag functionality
editorHeader.addEventListener("touchstart", dragStart, false);
editorHeader.addEventListener("touchend", dragEnd, false);
editorHeader.addEventListener("touchmove", drag, false);

editorHeader.addEventListener("mousedown", dragStart, false);
document.addEventListener("mousemove", drag, false);
document.addEventListener("mouseup", dragEnd, false);

const setEditorSize = (mode, editorElement = editor) => {
    // Reset any existing transforms and positioning
    editorElement.style.transform = 'none';
    editorElement.style.transition = 'all 0.3s ease';
    
    // Get viewport dimensions and convert padding to pixels
    const vw = window.innerWidth;
    const vh = window.innerHeight;
    const padding = '2em';
    const paddingPx = parseFloat(getComputedStyle(document.documentElement).fontSize) * 2;
    const fullModePadding = '4em';
    const fullModePaddingPx = parseFloat(getComputedStyle(document.documentElement).fontSize) * 4;
    
    // Reset all positioning first
    editorElement.style.position = 'fixed';
    editorElement.style.margin = '0';
    editorElement.style.maxWidth = 'none';
    editorElement.style.bottom = padding;
    
    switch (mode) {
        case 'normal':
            editorElement.style.width = '37.5em';
            editorElement.style.height = '300px';
            editorElement.style.left = '20px';
            editorElement.style.top = '20px';
            editorElement.style.right = 'auto';
            editorElement.style.bottom = 'auto';
            break;
            
        case 'vertical':
            // Take up the left half of the viewport
            editorElement.style.width = `${(vw - paddingPx * 3) / 2}px`;
            editorElement.style.height = `${vh - paddingPx * 2}px`;
            editorElement.style.left = padding;
            editorElement.style.top = padding;
            editorElement.style.right = 'auto';
            break;
            
        case 'horizontal':
            // Take up the top half of the viewport
            editorElement.style.width = `${vw - paddingPx * 2}px`;
            editorElement.style.height = `${(vh - paddingPx * 3) / 2}px`;
            editorElement.style.left = padding;
            editorElement.style.top = padding;
            editorElement.style.right = padding;
            break;
            
        case 'full':
            // Take up the full viewport with larger padding
            editorElement.style.width = `${vw - fullModePaddingPx * 2}px`;
            editorElement.style.height = `${vh - fullModePaddingPx * 2}px`;
            editorElement.style.top = fullModePadding;
            editorElement.style.left = fullModePadding;
            editorElement.style.right = fullModePadding;
            editorElement.style.bottom = fullModePadding;
            break;
    }
    
    // Reset offsets used by drag functionality
    xOffset = 0;
    yOffset = 0;
    
    // Ensure the editor is visible
    editorElement.style.display = 'block';
};

const renameFolder = () => {
    console.log('Attempting to rename:', state.currentFolderPath); // Debug log
    
    // Basic validation
    if (state.currentFolderPath === 'root') {
        alert("Can't rename root!");
        return;
    }

    // Get parent path and folder name
    const parts = state.currentFolderPath.split('/');
    const oldName = parts[parts.length - 1];
    const parentPath = parts.slice(0, -1).join('/') || 'root';

    const newName = prompt(`Rename "${oldName}" to:`, oldName);
    if (!newName || newName === oldName) return;

    // Create new file system and rename the folder
    const newFileSystem = clone(state.fileSystem);
    const parent = parentPath === 'root' ? 
        newFileSystem.root : 
        getFolder(parentPath, newFileSystem);

    if (parent && parent.children) {
        if (parent.children[newName]) {
            alert('A folder with this name already exists');
            return;
        }

        parent.children[newName] = parent.children[oldName];
        delete parent.children[oldName];
        updateFileSystem(newFileSystem);
        state.currentFolderPath = parentPath === 'root' ? 
            newName : 
            `${parentPath}/${newName}`;
        render();
    }
    hideContextMenu();
};

// Add double-click to rename
const handleFolderDoubleClick = (e) => {
    const folderElement = e.target.closest('.folder');
    if (folderElement && !folderElement.classList.contains('editing')) {
        e.preventDefault();
        e.stopPropagation();
        renameFolder();
    }
};

document.addEventListener('dblclick', handleFolderDoubleClick);

const toggleView = () => {
    state.viewMode = state.viewMode === 'tree' ? 'grid' : 'tree';
    render();
};

const navigateTo = (path, openDetails = false) => {
    state.currentFolderPath = path;
    
    // Only open folder details if explicitly requested (from breadcrumbs)
    if (openDetails) {
        const folder = path === 'root' ? state.fileSystem.root : getFolder(path);
        if (folder) {
            document.getElementById('folderContent').value = folder.content || '';
            editor.style.display = 'block';
            setEditorSize('normal');
        }
    }
    
    render();
};

const renderBreadcrumbs = () => {
    // Start with root, but ensure we don't duplicate it
    const parts = state.currentFolderPath.split('/').filter(part => part !== 'root');
    const fullPath = ['root', ...parts];
    
    // Generate breadcrumbs from the full path
    const breadcrumbs = fullPath.map((part, index) => {
        const path = fullPath.slice(0, index + 1).join('/');
        const isLastItem = index === fullPath.length - 1;
        
        return `
            <span class="breadcrumb-item" 
                onclick="navigateTo('${path}', ${isLastItem})">${part === 'root' ? '~' : part}</span>
            ${index < fullPath.length - 1 ? '<span class="breadcrumb-separator">/</span>' : ''}
        `;
    }).join('');

    document.getElementById('breadcrumbs').innerHTML = breadcrumbs;
};

const renderGridView = (folder) => {
    const entries = Object.entries(folder.children);
    return entries.map(([name, item]) => `
        <div class="grid-folder" 
            onclick="navigateTo('${state.currentFolderPath}/${name}')"
            oncontextmenu="showContextMenu(event, '${state.currentFolderPath}/${name}')">
            <div class="grid-folder-icon">📁</div>
            <div class="grid-folder-name">${name}</div>
        </div>
    `).join('');
};

const hideContextMenu = () => {
    contextMenu.classList.remove('active');
};

render();
</script>

</body>
</html>