Skip to content
Snippets Groups Projects
Commit 60d45e20 authored by Balaji D's avatar Balaji D :blush:
Browse files

FileInsert #38

parent ac62e395
No related branches found
No related tags found
1 merge request!41Fileinsert #38
......@@ -13,6 +13,7 @@ export function useFolder( folderId = null, folder= null) {
SELECT_FOLDER : 'select-folder',
UPDATE_FOLDER : 'update-folder',
SET_CHILD_FOLDERS : 'set_child_folders',
SET_CHILD_FILES: "set-child-files",
}
function reducer( state, { type,payload } ){
......@@ -37,6 +38,11 @@ export function useFolder( folderId = null, folder= null) {
...state,
childFolders : payload.childFolders,
};
case ACTIONS.SET_CHILD_FILES:
return {
...state,
childFiles: payload.childFiles,
};
default:
return state;
......@@ -104,6 +110,23 @@ export function useFolder( folderId = null, folder= null) {
})
})
},[folderId])
useEffect(() => {
if(firebase.auth().currentUser)
{
return (
database.files
.where("folderId", "==", folderId)
.where("userId", "==", firebase.auth().currentUser.uid)
.onSnapshot(snapshot => {
dispatch({
type: ACTIONS.SET_CHILD_FILES,
payload: { childFiles: snapshot.docs.map(database.formatDoc) },
})
})
)
}
}, [folderId])
return state;
}
\ No newline at end of file
import React, { useState } from "react"
import ReactDOM from "react-dom"
import { faFileUpload } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { storage, database } from '../fire.js'
import { ROOT_FOLDER } from "../hooks/useFolder"
import { v4 as uuidV4 } from "uuid"
import { ProgressBar, Toast } from "react-bootstrap"
import firebase from 'firebase'
export default function AddFile({ currentFolder }) {
const [uploadingFiles, setUploadingFiles] = useState([])
function handleUpload(e) {
const file = e.target.files[0]
if (currentFolder == null || file == null) return
const id = uuidV4()
setUploadingFiles(prevUploadingFiles => [
...prevUploadingFiles,
{ id: id, name: file.name, progress: 0, error: false },
])
const filePath =
currentFolder === ROOT_FOLDER
? `${currentFolder.path.join("/")}/${file.name}`
: `${currentFolder.path.join("/")}/${currentFolder.name}/${file.name}`
const uploadTask = storage
.ref(`/files/${firebase.auth().currentUser.uid}/${filePath}`)
.put(file)
uploadTask.on(
"state_changed",
snapshot => {
const progress = snapshot.bytesTransferred / snapshot.totalBytes
setUploadingFiles(prevUploadingFiles => {
return prevUploadingFiles.map(uploadFile => {
if (uploadFile.id === id) {
return { ...uploadFile, progress: progress }
}
return uploadFile
})
})
},
() => {
setUploadingFiles(prevUploadingFiles => {
return prevUploadingFiles.map(uploadFile => {
if (uploadFile.id === id) {
return { ...uploadFile, error: true }
}
return uploadFile
})
})
},
() => {
setUploadingFiles(prevUploadingFiles => {
return prevUploadingFiles.filter(uploadFile => {
return uploadFile.id !== id
})
})
uploadTask.snapshot.ref.getDownloadURL().then(url => {
database.files
.where("name", "==", file.name)
.where("userId", "==", firebase.auth().currentUser.uid)
.where("folderId", "==", currentFolder.id)
.get()
.then(existingFiles => {
const existingFile = existingFiles.docs[0]
if (existingFile) {
existingFile.ref.update({ url: url })
} else {
database.files.add({
url: url,
name: file.name,
createdAt: database.getTime(),
folderId: currentFolder.id,
userId: firebase.auth().currentUser.uid,
})
}
})
})
}
)
}
return (
<>
<label className="btn btn-outline-success btn-sm m-0 mr-2">
<FontAwesomeIcon icon={faFileUpload} />
<input
type="file"
onChange={handleUpload}
style={{ opacity: 0, position: "absolute", left: "-9999px" }}
/>
</label>
{uploadingFiles.length > 0 &&
ReactDOM.createPortal(
<div
style={{
position: "absolute",
bottom: "1rem",
right: "1rem",
maxWidth: "250px",
}}
>
{uploadingFiles.map(file => (
<Toast
key={file.id}
onClose={() => {
setUploadingFiles(prevUploadingFiles => {
return prevUploadingFiles.filter(uploadFile => {
return uploadFile.id !== file.id
})
})
}}
>
<Toast.Header
closeButton={file.error}
className="text-truncate w-100 d-block"
>
{file.name}
</Toast.Header>
<Toast.Body>
<ProgressBar
animated={!file.error}
variant={file.error ? "danger" : "primary"}
now={file.error ? 100 : file.progress * 100}
label={
file.error
? "Error"
: `${Math.round(file.progress * 100)}%`
}
/>
</Toast.Body>
</Toast>
))}
</div>,
document.body
)}
</>
)
}
\ No newline at end of file
import { faFile } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import React from "react"
export default function File({ file }) {
return (
<a
href={file.url}
target="_blank"
className="btn btn-outline-dark text-truncate w-100"
>
<FontAwesomeIcon icon={faFile} className="mr-2" />
{file.name}
</a>
)
}
......@@ -10,7 +10,6 @@ export default function FolderNav( {currentFolder} ) {
path = [...path,...currentFolder.path];
}
return(
<Breadcrumb
className="flex-grow-1"
......
import React, { useEffect, useState } from 'react'
import React, { useState, Component } from "react"
import AddFolder from './AddFolder'
import AddFile from './AddFile'
import { Container, Button, Navbar, Nav } from 'react-bootstrap'
import { ROOT_FOLDER, useFolder } from '.././hooks/useFolder'
import { useFolder } from '.././hooks/useFolder'
import Folder from './Folder'
import FolderNav from './FolderNav'
import Deffolders from './Deffolders'
import Deletefolder from './Deletefolder'
import Sharelink from './Sharelink'
import { useParams } from 'react-router-dom'
import copyright from './copyright'
import Deletefolder from './Deletefolder'
import { useParams,useLocation } from 'react-router-dom'
import { Link } from 'react-router-dom'
import File from './File'
import 'firebase/storage';
import ReactDOM from "react-dom"
import firebase from "../fire";
import Loader from 'react-loader-spinner'
const Hero = ({ handleLogout }) => {
const { folderId } = useParams()
const { folder, childFolders } = useFolder(folderId)
const { state = {} } = useLocation()
const { folder, childFolders, childFiles } = useFolder(folderId, state.folder)
if (!folder) {
return (
......@@ -44,6 +49,7 @@ const Hero = ({ handleLogout }) => {
)}
{folder.id!=null && ( <Sharelink currentFolder={folder} /> )}
{folder.id!=null && ( <Deletefolder currentFolder={folder} /> )}
{folder.id!=null && ( <AddFile currentFolder={folder} /> )}
</div>
{childFolders.length > 0 && (
......@@ -59,8 +65,109 @@ const Hero = ({ handleLogout }) => {
))}
</div>
)}
{childFolders.length > 0 && childFiles.length > 0 && <hr />}
{childFiles.length > 0 && (
<div className="d-flex flex-wrap">
{childFiles.map(childFile => (
<div
key={childFile.id}
style={{ maxWidth: "250px" }}
className="p-2"
>
<File file={childFile} />
<div id="root">
</div>
</div>
))}
</div>
)}
</Container>
<Navbar fixed='bottom' variant='light' bg='light'>
<Container className='ml-sm-2'>
<Nav.Link eventKey={2} href='copyright'>
&copy; Digital Course File Group 2
</Nav.Link>
</Container>
</Navbar>
</>
)
}
class ContextMenu extends React.Component {
state = {
visible: false,
};
componentDidMount() {
document.addEventListener('contextmenu', this._handleContextMenu);
document.addEventListener('click', this._handleClick);
document.addEventListener('scroll', this._handleScroll);
};
componentWillUnmount() {
document.removeEventListener('contextmenu', this._handleContextMenu);
document.removeEventListener('click', this._handleClick);
document.removeEventListener('scroll', this._handleScroll);
}
_handleContextMenu = (event) => {
event.preventDefault();
this.setState({ visible: true });
const clickX = event.clientX;
const clickY = event.clientY;
const screenW = window.innerWidth;
const screenH = window.innerHeight;
const rootW = this.root.offsetWidth;
const rootH = this.root.offsetHeight;
const right = (screenW - clickX) > rootW;
const left = !right;
const top = (screenH - clickY) > rootH;
const bottom = !top;
if (right) {
this.root.style.left = `${clickX + 5}px`;
}
if (left) {
this.root.style.left = `${clickX - rootW - 5}px`;
}
if (top) {
this.root.style.top = `${clickY + 5}px`;
}
if (bottom) {
this.root.style.top = `${clickY - rootH - 5}px`;
}
};
_handleClick = (event) => {
const { visible } = this.state;
const wasOutside = !(event.target.contains === this.root);
if (wasOutside && visible) this.setState({ visible: false, });
};
_handleScroll = () => {
const { visible } = this.state;
if (visible) this.setState({ visible: false, });
};
render() {
const { visible } = this.state;
return(visible || null) &&
<div ref={ref => {this.root = ref}} className="contextMenu">
<div className="contextMenu--option">Delete</div>
</div>
};
}
ReactDOM.render(<ContextMenu/>, document.getElementById('root'));
export default Hero
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment