Untitled

 avatar
unknown
plain_text
a year ago
6.1 kB
2
Indexable
import React, { useState, useEffect } from 'react';
import db from './firebase-config';
import firebase from 'firebase/compat/app';
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { Button, Container, Grid, Typography, CircularProgress, Snackbar } from '@mui/material';
import MuiAlert from '@mui/material/Alert';
import './App.css';
import ErrorPage from './components/ErrorPage';
import Watermark from './components/Watermark';
import CircularProgressWithLabel from './components/CircularProgressWithLabel';
import FileLoadingIndicator from './components/FileLoadingIndicator';
import Modal from './components/Modal';

const STORAGE_PATH = 'uploads/';
const PREVIEW_PATH = 'previews/';
const FILES_COLLECTION = 'files';

const App = () => {
  const [users, setUsers] = useState([]);
  const [isLoading, setLoading] = useState(false);
  const [isSnackbarOpen, setSnackbarOpen] = useState(false);
  const [errorMessage, setErrorMessage] = useState("");
  const [uploadProgress, setUploadProgress] = useState(0);
  const [currentFileIndex, setCurrentFileIndex] = useState(0);
  const [totalFiles, setTotalFiles] = useState(1);
  const [fileControl, setFileControl] = useState(0);
  const [progressControl, setProgressControl] = useState(0);
  const [finalProgress, setFinalProgress] = useState([]);
  const [sumControl, setSumControl] = useState(0);
  const [isModalOpen, setModalOpen] = useState(false);
  const [modalItem, setModalItem] = useState(null);
  const [sessionId, setSessionId] = useState('');

  // Generate a unique session ID
  useEffect(() => {
    const uniqueSessionId = `session_${Date.now()}_${Math.floor(Math.random() * 1000000)}`;
    setSessionId(uniqueSessionId);
  }, []);

  useEffect(() => {
    if (sessionId) {
      const query = db.collection(FILES_COLLECTION)
                      .where('sessionId', '==', sessionId)
                      .orderBy('datetime', 'desc');

      const unsubscribe = query.onSnapshot(snapshot => {
        setUsers(snapshot.docs.map(doc => ({
          id: doc.id,
          title: doc.data().title,
          image: doc.data().images,
          preview: doc.data().preview,
          datetime: doc.data().datetime,
          type: doc.data().type
        })));
      });

      return () => unsubscribe();
    }
  }, [sessionId]);

  useEffect(() => {
    if (sumControl) {
      const sum = finalProgress.reduce((a, b) => a + b, 0);
      setUploadProgress(sum / totalFiles);
    }
  }, [sumControl, finalProgress, totalFiles]);

  useEffect(() => {
    if (fileControl) {
      setCurrentFileIndex(index => index + 1);
    }
  }, [fileControl]);

  useEffect(() => {
    if (progressControl) {
      setFinalProgress(progress => {
        progress[progressControl.index] = progressControl.value;
        return progress;
      });
      setSumControl(new Date().getUTCMilliseconds());
    }
  }, [progressControl]);

  const handleCloseSnackBar = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }
    setSnackbarOpen(false);
  };

  const openModal = (item) => {
    setModalItem(item);
    setModalOpen(true);
  };

  const closeModal = () => {
    setModalOpen(false);
    setModalItem(null);
  };

  const addList = async (e) => {
    setLoading(true);
    const filesLocal = Array.from(e.target.files);
    setTotalFiles(filesLocal.length);

    const storage = getStorage();

    const uploadPromises = filesLocal.map((file, index) => {
      const storagePath = STORAGE_PATH + file.name;
      const storageRef = ref(storage, storagePath);
      const uploadTask = uploadBytesResumable(storageRef, file);

      return new Promise((resolve, reject) => {
        uploadTask.on('state_changed', 
          (snapshot) => {
            const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            setProgressControl({ index, value: progress });
          }, 
          (error) => {
            console.error(`Error uploading ${file.name}:`, error);
            setErrorMessage(error.message);
            setSnackbarOpen(true);
            resolve();
          }, 
          async () => {
            const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
            await db.collection(FILES_COLLECTION).add({
              title: file.name,
              images: downloadURL,
              datetime: firebase.firestore.FieldValue.serverTimestamp(),
              type: file.type.startsWith('image/') ? 'image' : 'video',
              sessionId // Store the session ID with each file
            });
            resolve();
          });
      });
    });

    await Promise.all(uploadPromises);
    setLoading(false);
  };

  return (
    <div className="App" style={{ backgroundColor: "#a090a2", height: "100vh", overflowY: "auto" }}>
      <Snackbar open={isSnackbarOpen} autoHideDuration={6000} onClose={handleCloseSnackBar} anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}>
        <MuiAlert elevation={6} variant="filled" onClose={handleCloseSnackBar} severity="success">
          Your file has been successfully uploaded!
        </MuiAlert>
      </Snackbar>
      <Modal item={modalItem} isOpen={isModalOpen} onClose={closeModal} />
      <Container maxWidth="md" style={{ backgroundColor: "#ccb7cc", marginTop: "25px", paddingBottom: "25px" }}>
        {/* Content and upload logic here */}
        {isLoading && (
          <div id="loading-overlay" className="loading-overlay">
            <CircularProgressWithLabel value={uploadProgress ? uploadProgress : 0} />
            <FileLoadingIndicator fileUploaded={currentFileIndex} totalFiles={totalFiles} />
          </div>
        )}
        {!isLoading && users.map(item => (
          <Grid key={item.id}>
            {/* Display uploaded files here */}
          </Grid>
        ))}
      </Container>
    </div>
  );
};

export default App;
Editor is loading...
Leave a Comment