LittleDemon WebShell


Linux in-mum-web1499.main-hosting.eu 5.14.0-503.40.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 5 06:06:04 EDT 2025 x86_64
Path : /home/u901718425/domains/portal.urbanpillar.in/public_html/
File Upload :
Command :
Current File : /home/u901718425/domains/portal.urbanpillar.in/public_html/drive.js

$(document).ready(function () {
    let drivePath  = userInfo.role !== 'master' ? '/uploads/drive' : '/uploads/';
    function showToast(message, type = 'success') {
      Toastify({
        text: message,
        duration: 3000,
        gravity: "top",
        position: "right",
        backgroundColor: type === 'success' ? "#4CAF50" : "#F44336",
        stopOnFocus: true,
      }).showToast();
    }

   let firstSelectedIndex = null;


  let currentPath = '';
  let pathHistory = [];

  loadFiles();
  let filesIcon = {empty: '/img/empty-folder.svg',folder: '/img/folder.svg'};

  $('#uploadForm').on('submit', function (e) {
    e.preventDefault();
    let formData = new FormData(this);
    $.ajax({
      url: 'api/upload.php',
      type: 'POST',
      data: formData,
      contentType: false,
      processData: false,
      success: function () {
        $('#uploadModal').modal('hide');
        $('#uploadForm')[0].reset();
        loadFiles();
      }
    });
  });

function preview(file) {
    let html = '';
    const fileExt = file.name.split('.').pop().toLowerCase();
    const fullPath = currentPath ? `${currentPath}/${file.name}` : file.name;
    if (file.is_dir) {
        // Show folder icon based on empty/full
        html = `<img src="${file.is_empty ? filesIcon.empty : filesIcon.folder}" class="w-100 h-auto ratio-1x1" />`;
    } else {
        // Show preview based on file type
        if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'].includes(fileExt)) {
            html = `<img src="${drivePath}/${fullPath}" class="w-100 h-auto ratio-1x1" />`;
        } else if (fileExt === 'pdf') {
            html = `<iframe src="${drivePath}/${fullPath}" class="w-100 ratio-1x1"  frameborder="0"></iframe>`;
        } else if (fileExt === 'txt') {
            html = `<iframe src="${drivePath}/${fullPath}" class="w-100 bg-light text-dark ratio-1x1"  frameborder="0"></iframe>`;
        } else if (['doc', 'docx'].includes(fileExt)) {
            html = `<iframe src="https://docs.google.com/gview?url=${window.location.origin}${drivePath}/${file.name}&embedded=true" 
                        class="w-100 ratio-1x1" frameborder="0"></iframe>`;
        } else {
            html = `<div class="text-center"><i class="bi bi-file-earmark fs-1 text-secondary"></i></div>`;
        }
    }

    return html;
}

// Load files from a given path
function loadFiles(path = '') {
  currentPath = path;
    if(currentPath !==""){
      $('#back-button').show();
  }else {
      $('#back-button').hide();
  }

  $.getJSON('api/list.php', { folder: path }, function (files) {
    let html = '';
    if (files.length === 0) {
      html = '<div class="col-12"><div class="alert alert-warning">No files uploaded.</div></div>';
    } else {
      $.each(files, function (i, file) {
        const fullPath = path ? `${path}/${file.name}` : file.name;
        html += `
          <div class="col-4 col-md-2">
            <div class="card border-0 position-relative" >
              <div class="card-body ${file.is_dir ? 'folder' : 'file'}" data-path="${fullPath}">
                ${preview(file)}
                <p class="card-text mb-0 text-center fs-7">${file.name}</p>
              </div>
            </div>
          </div>`;
      });
    }
    $('#file-list').html(html);
  });
}



// Initial load
loadFiles();
let selectedPath = '';
let isDir = false;

function showContextMenu(x, y, path = null, isDirectory = false) {
  selectedPath = path;
  isDir = isDirectory;

  let menuHtml = "";

  if (path) {
    // Right-clicked on file or folder
    menuHtml = `
      <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
        <li class="list-group-item list-group-item-action" data-action="view">📄 View</li>
        <li class="list-group-item list-group-item-action" data-action="rename">✏️ Rename</li>
       ${['master'].includes(userInfo.role) && `<li class="list-group-item list-group-item-action" data-action="delete">🗑️ Delete</li>`}
        <li class="list-group-item list-group-item-action" data-action="download">⬇️ Download</li>
      </ul>
    `;
  } else {
    // Right-clicked on empty space
    menuHtml = `
      <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
        <li class="list-group-item list-group-item-action" data-action="create-folder">📁 Create Folder</li>
      </ul>
    `;
  }

  $("#custom-context-menu").remove();
  $("body").append(menuHtml);

  $(document).on("click.contextmenu", function () {
    $("#custom-context-menu").remove();
    $(document).off("click.contextmenu");
  });
}


$(document).on("click", "#back-button", function (e) {
    console.log(currentPath);
    if(currentPath.includes('/')){
       let backParts = currentPath.split("/");
       backParts.pop(); // remove last part (current folder)
        const previousPath = backParts.join('/');

        loadFiles(previousPath, false); // Load without adding to history
    }else{
        loadFiles('', false);
    }
    // back = back.splice()
});

function createFolderPrompt() {
  const folderName = prompt("Enter new folder name:");
  if (!folderName) return;

  $.post('api/create_folder.php', {
      path: currentPath,
      name: folderName || 'New Folder'
    }, function (response) {
      if (response.status === 'success') {
            showToast('Folder created successfully');
            loadFiles(currentPath);
          } else {
            showToast(response.message, 'error');
          }
    }, 'json');

}

// function debounce(func, delay) {
//   let timeout;
//   return function (...args) {
//     clearTimeout(timeout);
//     timeout = setTimeout(() => func.apply(this, args), delay);
//   };
// }


// const debouncedLoadFiles = debounce(() => loadFiles(currentPath), 500);

// // Instead of setInterval, use a mutation observer or manual trigger if needed
// // But if you still want interval-style updates, use:
// setInterval(() => {
//   debouncedLoadFiles();
// }, 50000);


$(document).on("contextmenu", function (e) {
  // Prevent context menu if right-clicked on file or folder
  if ($(e.target).closest(".file, .folder, #custom-context-menu").length === 0) {
    e.preventDefault();
    showContextMenu(e.pageX, e.pageY); // No path, show Create Folder
  }
});


function renameItem() {
  const newName = prompt('Enter new name:');
  if (!newName) return;

  $.post('api/rename.php', { path: selectedPath, new_name: newName }, function (res) {
    showToast(res.message, 'error');
    if (res.success) loadFiles(currentPath);
  }, 'json');
}

function deleteItem() {
  if (!confirm('Are you sure you want to delete this item?')) return;

  $.ajax({
    url: 'api/delete.php',
    method: 'POST',
    data: {
      path: selectedPath,
      is_dir: isDir
    },
    success: function (res) {
      if (res.success) {
        showToast(res.message);
        loadFiles(currentPath); // Refresh UI
      } else {
        showToast(res.message, 'error');
      }
    },
    error: function (xhr, status, error) {
      console.error("Delete failed", error);
      showToast("An error occurred while deleting the item.", 'error');
    }
  });
}

function downloadItem() {
  if (!selectedPath) return;

  const statusEl = document.getElementById('download-status');
  statusEl.textContent = 'Preparing download...';
  statusEl.style.display = 'block';

  fetch(`api/download.php?path=${encodeURIComponent(selectedPath)}`, {
    method: 'GET',
    credentials: 'include',
  })
    .then(response => {
      if (!response.ok) throw new Error("Download failed");

      const disposition = response.headers.get('Content-Disposition');
      const filenameMatch = disposition && disposition.match(/filename="(.+)"/);
      const filename = filenameMatch ? filenameMatch[1] : 'download.zip';

      return response.blob().then(blob => ({ blob, filename }));
    })
    .then(({ blob, filename }) => {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      a.click();
      window.URL.revokeObjectURL(url);

      document.getElementById('download-status').textContent = 'Download complete!';
      setTimeout(() => {
        document.getElementById('download-status').style.display = 'none';
      }, 3000);
    })
    .catch(err => {
      console.error(err);
      statusEl.textContent = 'Download failed!';
      setTimeout(() => {
        statusEl.style.display = 'none';
      }, 3000);
    });
}

// Double-click handler
$(document).on('dblclick', '.folder', function () {
  const folderPath = $(this).data('path');
  loadFiles(folderPath);
});

  
  
  
const dropZone = $('#drop-zone');

// Highlight drop area
dropZone.on('dragover dragenter', function (e) {
  e.preventDefault();
  e.stopPropagation();
  dropZone.addClass('bg-light border-success');
});

dropZone.on('dragleave drop', function (e) {
  e.preventDefault();
  e.stopPropagation();
  dropZone.removeClass('bg-light border-success');
});

// Drop handler
dropZone.on('drop', function (e) {
  const items = e.originalEvent.dataTransfer.items;
  if (items) {
    for (let i = 0; i < items.length; i++) {
      const item = items[i].webkitGetAsEntry?.();
      if (item) {
        traverseFileTree(item);
      }
    }
  }
});

function traverseFileTree(item, path = "") {
  if (item.isFile) {
    item.file(function (file) {
      uploadFile(file, path);
    });
  } else if (item.isDirectory) {
    const dirReader = item.createReader();
    dirReader.readEntries(function (entries) {
      for (let i = 0; i < entries.length; i++) {
        traverseFileTree(entries[i], path + item.name + "/");
      }
    });
  }
}

function uploadFile(file, folderPath = "") {
  const formData = new FormData();
  formData.append("file", file);
  formData.append("path", currentPath + "/" + folderPath); // dynamic folder path

  const id = "upload_" + Date.now() + "_" + Math.random().toString(36).substr(2, 5);
  showUploadStatus(id, `Uploading: ${folderPath}${file.name}`);

  $.ajax({
    url: "api/upload.php",
    method: "POST",
    data: formData,
    processData: false,
    contentType: false,
    success: function (res) {
      updateUploadStatus(id, `✅ ${folderPath}${file.name}`);
      loadFiles(currentPath); // Refresh UI
    },
    error: function () {
      updateUploadStatus(id, `❌ Failed: ${folderPath}${file.name}`);
    }
  });
}

function showUploadStatus(id, message) {
  const html = `
    <div id="${id}" class="alert alert-info shadow-sm py-2 px-3 mb-2">
      ${message}
    </div>
  `;
  $('#upload-status').append(html);
}

function updateUploadStatus(id, message) {
  $(`#${id}`).removeClass('alert-info').addClass('alert-success').html(message);
  setTimeout(() => $(`#${id}`).fadeOut(1000, () => $(`#${id}`).remove()), 4000);
}
  
//   let selectedItems = [];

// $(document).on('click', '.card-body', function (e) {
//   const path = $(this).data('path');

//   // Ctrl+Click selection
//   if (e.ctrlKey || e.metaKey) {
//     $(this).toggleClass('selected');
//   } else {
//     $('.card-body').removeClass('selected');
//     $(this).addClass('selected');
//   }

//   updateSelectedItems();
// });

// function updateSelectedItems() {
//   selectedItems = [];
//   $('.card-body.selected').each(function () {
//     selectedItems.push($(this).data('path'));
//   });
// }


// $(document).on("contextmenu", ".card-body", function (e) {
//   e.preventDefault();

//   const $clicked = $(this);
//   const filePath = $clicked.data("path");
//   const isDirectory = $clicked.hasClass("folder");

//   // Clear selection if this wasn't already selected
//   if (!$clicked.hasClass('selected')) {
//     $('.card-body').removeClass('selected');
//     $clicked.addClass('selected');
//   }

//   updateSelectedItems();

//   const x = e.pageX;
//   const y = e.pageY;

//   let menuHtml = "";

//   if (selectedItems.length > 1) {
//     // Show multi-select context menu
//     menuHtml = `
//       <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
//         <li class="list-group-item list-group-item-action" data-action="download-selected">⬇️ Download Selected</li>
//         <li class="list-group-item list-group-item-action" data-action="delete-selected">🗑️ Delete Selected</li>
//       </ul>
//     `;
//   } else if (selectedItems.length === 1) {
//     // Single item context menu
//     selectedPath = filePath;
//     isDir = isDirectory;

//     menuHtml = `
//       <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
//         <li class="list-group-item list-group-item-action" data-action="view">📄 View</li>
//         <li class="list-group-item list-group-item-action" data-action="rename">✏️ Rename</li>
//         <li class="list-group-item list-group-item-action" data-action="delete">🗑️ Delete</li>
//         <li class="list-group-item list-group-item-action" data-action="download">⬇️ Download</li>
//       </ul>
//     `;
//   }

//   $('#custom-context-menu').remove();
//   $('body').append(menuHtml);
// });

// $(document).on("click", ".card-body", function (e) {
//   const $clicked = $(this);
//   const allItems = $(".card-body");

//   if (e.ctrlKey || e.metaKey) {
//     // Toggle selection on Ctrl/Cmd click
//     $clicked.toggleClass("selected");

//     // Update base index only if there's at least one selected
//     const selected = allItems.filter(".selected");
//     if (selected.length === 1) {
//       firstSelectedIndex = allItems.index($clicked);
//     }
//   } else if (e.shiftKey && firstSelectedIndex !== null) {
//     // Shift + click: range selection
//     const currentIndex = allItems.index($clicked);
//     const start = Math.min(firstSelectedIndex, currentIndex);
//     const end = Math.max(firstSelectedIndex, currentIndex);

//     allItems.removeClass("selected");
//     for (let i = start; i <= end; i++) {
//       allItems.eq(i).addClass("selected");
//     }
//   } else {
//     // Regular click
//     allItems.removeClass("selected");
//     $clicked.addClass("selected");
//     firstSelectedIndex = allItems.index($clicked);
//   }

//   updateSelectedItems();
// });



// // Ctrl+A for select all
// $(document).on('keydown', function (e) {
//   if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'a') {
//     e.preventDefault();
//     $('.card-body').addClass('selected');
//     updateSelectedItems();
//   }
// });

// // Hide the custom context menu on clicking outside
$(document).on("click", function (e) {
  // If the click target is not inside the context menu
  if (!$(e.target).closest("#custom-context-menu").length) {
    $("#custom-context-menu").remove();
  }
});



let selectedItems = [];

$(document).on("click", ".card-body", function (e) {
  const $clicked = $(this);
  const allItems = $(".card-body");

  if (e.ctrlKey || e.metaKey) {
    // Toggle selection on Ctrl/Cmd click
    $clicked.toggleClass("selected");

    const selected = allItems.filter(".selected");
    if (selected.length === 1) {
      firstSelectedIndex = allItems.index($clicked);
    }
  } else if (e.shiftKey && firstSelectedIndex !== null) {
    // Shift + click: range selection
    const currentIndex = allItems.index($clicked);
    const start = Math.min(firstSelectedIndex, currentIndex);
    const end = Math.max(firstSelectedIndex, currentIndex);

    allItems.removeClass("selected");
    for (let i = start; i <= end; i++) {
      allItems.eq(i).addClass("selected");
    }
  } else {
    // Regular click
    allItems.removeClass("selected");
    $clicked.addClass("selected");
    firstSelectedIndex = allItems.index($clicked);
  }

  updateSelectedItems();
});

function updateSelectedItems() {
  selectedItems = [];
  $(".card-body.selected").each(function () {
    selectedItems.push($(this).data("path"));
  });
}

// Context Menu
$(document).on("contextmenu", ".card-body", function (e) {
  e.preventDefault();

  const $clicked = $(this);
  const filePath = $clicked.data("path");
  const isDirectory = $clicked.hasClass("folder");

  // If not selected, make it the only selected one
  if (!$clicked.hasClass("selected")) {
    $(".card-body").removeClass("selected");
    $clicked.addClass("selected");
  }

  updateSelectedItems();

  const x = e.pageX;
  const y = e.pageY;

  let menuHtml = "";

  if (selectedItems.length > 1) {
    menuHtml = `
      <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
        <li class="list-group-item list-group-item-action" data-action="download-selected">⬇️ Download Selected</li>
        <li class="list-group-item list-group-item-action" data-action="delete-selected">🗑️ Delete Selected</li>
      </ul>
    `;
  } else {
    selectedPath = filePath;
    isDir = isDirectory;

    menuHtml = `
      <ul id="custom-context-menu" class="position-absolute list-group shadow" style="top:${y}px;left:${x}px;z-index:9999;min-width:160px;">
        <li class="list-group-item list-group-item-action" data-action="view">📄 View</li>
        <li class="list-group-item list-group-item-action" data-action="rename">✏️ Rename</li>
        <li class="list-group-item list-group-item-action" data-action="delete">🗑️ Delete</li>
        <li class="list-group-item list-group-item-action" data-action="download">⬇️ Download</li>
      </ul>
    `;
  }

  $("#custom-context-menu").remove();
  $("body").append(menuHtml);
});

// Ctrl+A
$(document).on("keydown", function (e) {
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a") {
    e.preventDefault();
    $(".card-body").addClass("selected");
    updateSelectedItems();
  }
});


$(document).on("click", "#custom-context-menu li", function () {
  const action = $(this).data("action");
  $("#custom-context-menu").remove();

  switch (action) {
    case "view":
      viewFile();
      break;
    case "rename":
      renameItem();
      break;
    case "delete":
      deleteSelectedItems();
      break;
    case "download":
      downloadItem();
      break;
    case "create-folder":
      createFolderPrompt();
      break;
    case "download-selected":
      downloadSelectedItems();
      break;
    case "delete-selected":
      deleteSelectedItems();
      break;
  }
});

function viewFile() {
    
  if (!selectedPath) return;

  // Open the file in a new tab
  window.open(`https://portal.urbanpillar.in${drivePath}/${selectedPath}`, "_blank");
}


function downloadSelectedItems() {
  if (selectedItems.length === 0) return;

  const items = selectedItems.map(path => {
    const el = $(`.card-body[data-path="${path}"]`);
    return {
      path: path,
      is_dir: el.hasClass('folder')
    };
  });

  const form = $('<form>', {
    method: 'POST',
    action: 'api/zip.php',
    target: '_blank' // opens download in new tab
  });

  form.append($('<input>', {
    type: 'hidden',
    name: 'items',
    value: JSON.stringify(items)
  }));

  $('body').append(form);
  form.submit();
  form.remove();
}


function deleteSelectedItems() {
  if (selectedItems.length === 0) return;

  if (!confirm(`Are you sure you want to delete ${selectedItems.length} item(s)?`)) return;

  const itemsToDelete = selectedItems.map(path => {
    const el = $(`.card-body[data-path="${path}"]`);
    return {
      path: path,
      is_dir: el.hasClass('folder')
    };
  });

  $.ajax({
    url: 'api/delete.php',
    method: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ paths: itemsToDelete }),
    success: function (res) {
      console.log(res);
      loadFiles(currentPath);
    },
    error: function (err) {
      alert('Error deleting files.');
      console.error(err);
    }
  });
}



let isDragging = false;
let startX, startY;

$(document).on('mousedown', function (e) {
  // Left mouse button only
  if (e.button !== 0) return;

  isDragging = true;
  startX = e.pageX;
  startY = e.pageY;

  $('#selection-box').css({
    top: startY + 'px',
    left: startX + 'px',
    width: 0,
    height: 0,
    display: 'block'
  });
});

$(document).on('mousemove', function (e) {
  if (!isDragging) return;

  const x = Math.min(e.pageX, startX);
  const y = Math.min(e.pageY, startY);
  const w = Math.abs(e.pageX - startX);
  const h = Math.abs(e.pageY - startY);

  $('#selection-box').css({
    top: y + 'px',
    left: x + 'px',
    width: w + 'px',
    height: h + 'px'
  });

  $('.card-body').each(function () {
    const $el = $(this);
    const offset = $el.offset();
    const elX = offset.left;
    const elY = offset.top;
    const elW = $el.outerWidth();
    const elH = $el.outerHeight();

    const isInside = !(elX > x + w || elX + elW < x || elY > y + h || elY + elH < y);

    if (isInside) {
      $el.addClass('selected');
    } else if (!e.ctrlKey && !e.metaKey) {
      $el.removeClass('selected');
    }
  });

  updateSelectedItems();
});

$(document).on('mouseup', function () {
  if (isDragging) {
    isDragging = false;
    $('#selection-box').hide();
  }
});


});

LittleDemon - FACEBOOK
[ KELUAR ]