Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MC-World-Compressor/Frontend/llms.txt

Use this file to discover all available pages before exploring further.

Overview

MC World Compressor uses a sophisticated chunked upload system that allows users to upload large Minecraft world files (up to 4GB) with real-time progress tracking and drag-and-drop support.

Upload Specifications

Chunk Size

50MB per chunk

Max File Size

4GB (4,294,967,296 bytes)

Supported Formats

.zip, .tar, .tar.gz

Upload Method

Drag & drop or file picker

How Chunked Upload Works

The upload system splits large files into manageable chunks to ensure reliable transfers even for large worlds.

Implementation Details

From app/[locale]/upload/page.js:129-177:
const tamañoChunk = 50 * 1024 * 1024; // 50MB
const chunksTotales = Math.ceil(fichero.size / tamañoChunk);
const idSubida = Date.now().toString() + Math.floor(Math.random() * 1000);

for (let chunkIndex = 0; chunkIndex < chunksTotales; chunkIndex++) {
  const start = chunkIndex * tamañoChunk;
  const end = Math.min(start + tamañoChunk, fichero.size);
  const chunk = fichero.slice(start, end);

  const formData = new FormData();
  formData.append('mundo_comprimido', chunk);
  formData.append('fileName', fichero.name);
  formData.append('uploadId', idSubida);
  formData.append('chunkIndex', chunkIndex);
  formData.append('totalChunks', chunksTotales);
  formData.append('isLastChunk', chunkIndex === chunksTotales - 1 ? 'true' : 'false');

  const response = await fetch(`${backendUrl}/api/subir`, {
    method: 'POST',
    body: formData,
  });

  setProgresoSubida(Math.round(((chunkIndex + 1) / chunksTotales) * 100));
}

Chunk Parameters

Each chunk is uploaded with metadata:
ParameterDescription
mundo_comprimidoThe binary chunk data
fileNameOriginal file name
uploadIdUnique identifier for this upload session
chunkIndexCurrent chunk number (0-based)
totalChunksTotal number of chunks in the file
isLastChunkBoolean indicating if this is the final chunk

File Validation

The system validates files before upload:

Format Validation

From app/[locale]/upload/page.js:95-104:
const nombre = file.name.toLowerCase();
const esZip = nombre.endsWith('.zip');
const esTarGz = nombre.endsWith('.tar.gz');
const esTar = !esTarGz && nombre.endsWith('.tar');

if (!(esZip || esTar || esTarGz)) {
  setError(t('upload.errors.zipOnly'));
  setFichero(null);
  return;
}

Size Validation

From app/[locale]/upload/page.js:106-111:
const MAX_TAMAÑO = 4 * 1024 * 1024 * 1024; // 4GB en bytes
if (file.size > MAX_TAMAÑO) {
  setError(t('upload.errors.sizeLimit'));
  setFichero(null);
  return;
}
Files larger than 4GB will be rejected. Ensure your world file is under this limit before uploading.

Progress Tracking

The upload progress is calculated based on completed chunks:
setProgresoSubida(Math.round(((chunkIndex + 1) / chunksTotales) * 100));
Users see a real-time progress bar and percentage:
<div className="bg-gray-200 dark:bg-gray-700 rounded-full h-2 mb-2">
  <div 
    className="bg-blue-600 dark:bg-blue-500 h-2 rounded-full transition-all duration-300 ease-in-out"
    style={{ width: `${progresoSubida}%` }}
  ></div>
</div>

Drag and Drop Support

The upload area supports drag and drop functionality with visual feedback:

Implementation

From app/[locale]/upload/page.js:187-228:
onDragOver={(e) => {
  e.preventDefault();
  e.stopPropagation();
  if (!subiendo) {
    e.currentTarget.classList.add('border-blue-500');
  }
}}

onDrop={(e) => {
  e.preventDefault();
  e.stopPropagation();
  e.currentTarget.classList.remove('border-blue-500');
  
  if (subiendo) return;
  
  if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
    const file = e.dataTransfer.files[0];
    // Validation logic...
    setFichero(file);
    setError(null);
  }
}}
The drop zone provides visual feedback by changing border color when files are dragged over it.

Upload States

The upload component manages several states:
const [fichero, setFichero] = useState(null);           // Selected file
const [subiendo, setSubiendo] = useState(false);        // Upload in progress
const [progresoSubida, setProgresoSubida] = useState(0); // Progress percentage
const [serverId, setServerId] = useState(null);         // Job ID after upload
const [error, setError] = useState(null);               // Error messages

Large File Handling

For files larger than 500MB, users receive a special notification when uploading the final chunk: From app/[locale]/upload/page.js:132-138:
const archivoPesado = fichero.size > 500 * 1024 * 1024; // 500MB

for (let chunkIndex = 0; chunkIndex < chunksTotales; chunkIndex++) {
  if (chunkIndex === chunksTotales - 1 && archivoPesado) {
    setMostrarAvisoUltimoChunk(true);
  }
  // Upload logic...
}
This warning alerts users that the final chunk may take longer to process.

Upload Protection

The system prevents accidental navigation away during upload: From app/[locale]/upload/page.js:70-87:
useEffect(() => {
  const handleBeforeUnload = (e) => {
    if (subiendo) {
      e.preventDefault();
      e.returnValue = '';
      return '';
    }
  };

  if (subiendo) {
    window.addEventListener('beforeunload', handleBeforeUnload);
    window.history.pushState(null, '', window.location.pathname);
  }

  return () => {
    window.removeEventListener('beforeunload', handleBeforeUnload);
  };
}, [subiendo, locale]);
Users will receive a browser warning if they attempt to close the page while an upload is in progress.

Success Handling

After successful upload, the user is redirected to the status page: From app/[locale]/upload/page.js:61-68:
useEffect(() => {
  if (serverId && locale) {
    const timer = setTimeout(() => {
      router.push(`/${locale}/status/${serverId}`);
    }, 1500);
    return () => clearTimeout(timer);
  }
}, [serverId, router, locale]);
The serverId is returned from the backend after the last chunk is processed successfully.

Build docs developers (and LLMs) love