made file item a complte functional component now :)

This commit is contained in:
subnub
2024-06-23 05:07:42 -04:00
parent d9fcceebc5
commit 127760dba0
11 changed files with 444 additions and 856 deletions
+177 -94
View File
@@ -1,117 +1,200 @@
import axios from "../axiosInterceptor";
export const setSelectedItem = (selectedItem) => ({
type: "SET_SELECTED_ITEM",
selectedItem
})
type: "SET_SELECTED_ITEM",
selectedItem,
});
export const startSetSelectedItem = (id, file, fromQuickItems, isGoogleDrive) => {
export const startSetSelectedItem = (
id,
file,
fromQuickItems,
isGoogleDrive
) => {
return (dispatch) => {
const currentDate = Date.now();
console.log("curr", currentDate);
return (dispatch) => {
const currentDate = Date.now();
dispatch(setLastSelected(currentDate));
dispatch(setLastSelected(currentDate));
if (!fromQuickItems) {
dispatch(setSelected(id))
} else {
dispatch(setSelected("quick-"+id))
}
if (file) {
if (isGoogleDrive) {
axios.get(`/file-service-google/info/${id}`).then((results) => {
const data = results.data;
const {filename: name, length: size, uploadDate: date, parentName: location, metadata, _id: id} = results.data;
dispatch(setSelectedItem({name, size, date, file, location, transcoded: metadata.transcoded, isVideo: metadata.isVideo, id, linkType: metadata.linkType, link: metadata.link, drive: metadata.drive, personalFile: metadata.personalFile, data: results.data}))
}).catch((err) => {
console.log(err)
})
} else {
axios.get(`/file-service/info/${id}`).then((results) => {
const {filename: name, length: size, uploadDate: date, parentName: location, metadata, _id: id} = results.data;
dispatch(setSelectedItem({name, size, date, file, location, transcoded: metadata.transcoded, isVideo: metadata.isVideo, id, linkType: metadata.linkType, link: metadata.link, drive: metadata.drive, personalFile: metadata.personalFile, data: results.data}))
}).catch((err) => {
console.log(err)
})
}
} else {
if (isGoogleDrive) {
axios.get(`/folder-service-google/info/${id}`).then((results) => {
const {name, 0: size, createdAt: date, parentName: location, _id: id, drive, personalFolder: personalFile} = results.data;
dispatch(setSelectedItem({name, size, date, file, location, data: results.data, id, drive, personalFile}))
}).catch((err) => {
console.log(err)
})
} else {
axios.get(`/folder-service/info/${id}`).then((results) => {
const {name, 0: size, createdAt: date, parentName: location, _id: id, drive, personalFolder: personalFile} = results.data;
dispatch(setSelectedItem({name, size, date, file, location, data: results.data, id, drive, personalFile}))
}).catch((err) => {
console.log(err)
})
}
}
if (!fromQuickItems) {
dispatch(setSelected(id));
} else {
dispatch(setSelected("quick-" + id));
}
}
if (file) {
if (isGoogleDrive) {
axios
.get(`/file-service-google/info/${id}`)
.then((results) => {
const data = results.data;
const {
filename: name,
length: size,
uploadDate: date,
parentName: location,
metadata,
_id: id,
} = results.data;
dispatch(
setSelectedItem({
name,
size,
date,
file,
location,
transcoded: metadata.transcoded,
isVideo: metadata.isVideo,
id,
linkType: metadata.linkType,
link: metadata.link,
drive: metadata.drive,
personalFile: metadata.personalFile,
data: results.data,
})
);
})
.catch((err) => {
console.log(err);
});
} else {
axios
.get(`/file-service/info/${id}`)
.then((results) => {
const {
filename: name,
length: size,
uploadDate: date,
parentName: location,
metadata,
_id: id,
} = results.data;
dispatch(
setSelectedItem({
name,
size,
date,
file,
location,
transcoded: metadata.transcoded,
isVideo: metadata.isVideo,
id,
linkType: metadata.linkType,
link: metadata.link,
drive: metadata.drive,
personalFile: metadata.personalFile,
data: results.data,
})
);
})
.catch((err) => {
console.log(err);
});
}
} else {
if (isGoogleDrive) {
axios
.get(`/folder-service-google/info/${id}`)
.then((results) => {
const {
name,
0: size,
createdAt: date,
parentName: location,
_id: id,
drive,
personalFolder: personalFile,
} = results.data;
dispatch(
setSelectedItem({
name,
size,
date,
file,
location,
id,
drive,
personalFile,
})
);
})
.catch((err) => {
console.log(err);
});
} else {
axios
.get(`/folder-service/info/${id}`)
.then((results) => {
const {
name,
0: size,
createdAt: date,
parentName: location,
_id: id,
drive,
personalFolder: personalFile,
} = results.data;
dispatch(
setSelectedItem({
name,
size,
date,
file,
location,
id,
drive,
personalFile,
})
);
})
.catch((err) => {
console.log(err);
});
}
}
};
};
export const editSelectedItem = (item) => ({
type: "EDIT_SELECTED_ITEM",
item
})
type: "EDIT_SELECTED_ITEM",
item,
});
export const resetSelectedItem = () => ({
type: "RESET_SELECTED_ITEM"
})
type: "RESET_SELECTED_ITEM",
});
export const resetSelected = () => ({
type: "RESET_SELECTED"
})
type: "RESET_SELECTED",
});
export const setLastSelected = (lastSelected) => ({
type: "SET_LAST_SELECTED",
lastSelected
})
type: "SET_LAST_SELECTED",
lastSelected,
});
export const setRightSelected = (selected) => ({
type: "SET_RIGHT_SELECTED",
selected
})
type: "SET_RIGHT_SELECTED",
selected,
});
export const setShareSelected = (selected) => ({
type: "SET_SHARE_SELECTED",
selected
})
type: "SET_SHARE_SELECTED",
selected,
});
export const editShareSelected = (selected) => ({
type: "EDIT_SHARE_SELECTED",
selected
})
type: "EDIT_SHARE_SELECTED",
selected,
});
export const setSelected = (selected) => ({
type: "SET_SELECTED",
selected
})
type: "SET_SELECTED",
selected,
});
+1
View File
@@ -66,6 +66,7 @@ export const downloadFile = async (fileID: string) => {
};
export const getFileThumbnail = async (thumbnailID: string) => {
// TODO: Change this
const url = `http://localhost:5173/api/file-service/thumbnail/${thumbnailID}`;
const config = {
responseType: "arraybuffer",
+3 -5
View File
@@ -65,11 +65,9 @@ const DataForm = (props) => {
<div className="inner__folders">
{folders?.map((folder) => (
<FolderItem
{...folder}
folder={folder}
key={folder._id}
itemSelected={folder._id === props.selected}
folderClick={props.folderClick}
deleteFolder={props.deleteFolder}
/>
))}
</div>
@@ -155,7 +153,7 @@ const DataForm = (props) => {
<React.Fragment key={index}>
{filePage.map((file) => (
<FileItem
{...file}
file={file}
key={file._id}
itemSelected={file._id === props.selected}
downloadFile={props.downloadFile}
@@ -207,7 +205,7 @@ const DataForm = (props) => {
<React.Fragment key={index}>
{filePage.map((file) => (
<FileItem
{...file}
file={file}
key={file._id}
itemSelected={file._id === props.selected}
downloadFile={props.downloadFile}
-206
View File
@@ -1,206 +0,0 @@
import capitalize from "../../utils/capitalize";
import moment from "moment";
import React from "react";
import ContextMenu from "../ContextMenu";
import mobilecheck from "../../utils/mobileCheck";
const FileItem = (props) => {
if (props.state.movingMode) {
return (
<tr
className={"moving__file"}
onClick={() => {
props.fileClick(props._id, props);
}}
onContextMenu={(e) => props.getContextMenu(e)}
onTouchStart={props.onTouchStart}
onTouchEnd={props.onTouchEnd}
onTouchMove={props.onTouchMove}
>
<td>
<div class="inner__moving">
<div class="moving__info">
<p>Moving 4 items</p>
<span>2 minutes remaining</span>
<div class="progress__moving">
<div
class="active__progress"
style={{
width: "20%",
marginLeft: `${props.state.movingPercentage}%`,
}}
></div>
</div>
</div>
<div class="cancel__moving">
<a href="#">
<img src="/assets/cancelmove.svg" alt="cancelmode" />
</a>
</div>
</div>
</td>
<td></td>
<td></td>
<td></td>
</tr>
);
} else if (props.listView) {
const extensionImageResults = props.getExtensionImage();
return (
<tr
className={
props.state.editNameMode
? "editable__row"
: props._id !== props.selected
? ""
: "active__recent"
}
onClick={props.startFileClick}
onContextMenu={props.selectContext}
onTouchStart={props.onTouchStart}
onTouchEnd={props.onTouchEnd}
onTouchMove={props.onTouchMove}
>
{/* <ContextMenu parent={props.metadata.parent} contextSelected={props.state.contextSelected} closeContext={props.closeContext} downloadFile={props.downloadFile} file={props} changeEditNameMode={props.changeEditNameMode} closeEditNameMode={props.closeEditNameMode} changeDeleteMode={props.changeDeleteMode} startMovingFile={props.startMovingFile}/> */}
<td class="name__row">
<div class="inner__name--row">
<span class="extension__wrap noSelect">
{extensionImageResults.passed ? (
<img src={extensionImageResults.ext} alt="accessimage" />
) : (
<div
className="no-extension__wrapper"
style={{ background: extensionImageResults.color }}
>
<span className="no-extension__title">
{extensionImageResults.ext}
</span>
</div>
)}
</span>
<p className="name__row-filename noSelect">
{props.state.editNameMode ? "" : capitalize(props.filename)}
</p>
{props.state.editNameMode ? (
<div onClick={props.clickStopPropagation} class="edit__name">
<input
type="text"
value={props.state.editName}
onChange={props.changeEditName}
/>
<a onClick={props.saveNameEdit} class="edit__save">
SAVE
</a>
</div>
) : undefined}
</div>
</td>
<td class="location__row noSelect">
{props.metadata.drive
? "Google Drive"
: props.metadata.personalFile
? "Amazon S3"
: "myDrive"}
</td>
<td class="modified__row noSelect">
{moment(props.uploadDate).format("L")}
</td>
<td class="settings__row noSelect">
<div class="settings__wrap">
<div>
<ContextMenu
parent={props.metadata.parent}
contextSelected={props.state.contextSelected}
closeContext={props.closeContext}
downloadFile={props.downloadFile}
file={props}
changeEditNameMode={props.changeEditNameMode}
closeEditNameMode={props.closeEditNameMode}
changeDeleteMode={props.changeDeleteMode}
startMovingFile={props.startMovingFile}
/>
</div>
{/* <ContextMenu parent={props.metadata.parent} contextSelected={props.state.contextSelected} closeContext={props.closeContext} downloadFile={props.downloadFile} file={props} changeEditNameMode={props.changeEditNameMode} closeEditNameMode={props.closeEditNameMode} changeDeleteMode={props.changeDeleteMode} startMovingFile={props.startMovingFile}/> */}
<a onClick={props.selectContext}>
<i class="fas fa-ellipsis-h"></i>
</a>
</div>
{props.state.deleteMode ? (
<div onClick={props.clickStopPropagation} class="delete__wrap">
<p>Are you sure you want to delete this?</p>
<div class="delete__buttons">
<a onClick={props.startDeleteFile} class="delete__button">
Delete
</a>
<a onClick={props.removeDeleteMode} class="keep__button">
Keep File
</a>
</div>
</div>
) : undefined}
</td>
</tr>
);
} else {
return (
<div
className={
props._id !== props.selected
? "elem__access noSelect"
: "elem__access active__recent noSelect"
}
onClick={() => {
props.fileClick(props._id, props);
}}
onContextMenu={props.selectContext}
onTouchStart={props.onTouchStart}
onTouchEnd={props.onTouchEnd}
onTouchMove={props.onTouchMove}
>
<div
className="context__menu--wrapper"
onClick={props.clickStopPropagation}
>
<ContextMenu
gridMode={true}
quickItemMode={true}
contextSelected={props.state.contextSelected}
closeContext={props.closeContext}
downloadFile={props.downloadFile}
file={props}
changeEditNameMode={props.changeEditNameMode}
closeEditNameMode={props.closeEditNameMode}
changeDeleteMode={props.changeDeleteMode}
startMovingFile={props.startMovingFile}
/>
</div>
<div class="access__image noSelect">
<img
class={props.state.imageClassname}
src={props.state.imageSrc}
onError={props.thumbnailOnError}
/>
</div>
<div class="access__info--file">
<p
className="noSelect"
style={props._id !== props.selected ? {} : { color: "white" }}
>
{capitalize(props.filename)}
</p>
<span
className="noSelect"
style={props._id !== props.selected ? {} : { color: "white" }}
>
{moment(props.uploadDate).format("L")}
</span>
</div>
</div>
);
}
};
export default FileItem;
+189 -517
View File
@@ -1,534 +1,206 @@
import FileItem from "./FileItem";
import {
startSetSelectedItem,
setRightSelected,
setLastSelected,
} from "../../actions/selectedItem";
import mobileCheck from "../../utils/mobileCheck";
import env from "../../enviroment/envFrontEnd";
import axios from "../../axiosInterceptor";
import { connect } from "react-redux";
import React from "react";
import { startRenameFile, startRemoveFile } from "../../actions/files";
import capitalize from "../../utils/capitalize";
import moment from "moment";
import React, { useMemo, useRef } from "react";
import ContextMenu from "../ContextMenu";
import mobilecheck from "../../utils/mobileCheck";
import Swal from "sweetalert2";
import { setMoverID } from "../../actions/mover";
import { setMobileContextMenu } from "../../actions/mobileContextMenu";
import { useContextMenu } from "../../hooks/contextMenu";
import { useDispatch, useSelector } from "react-redux";
import classNames from "classnames";
import { useThumbnail } from "../../hooks/files";
import { getFileColor, getFileExtension } from "../../utils/files";
import { startSetSelectedItem } from "../../actions/selectedItem";
import { setPopupFile } from "../../actions/popupFile";
class FileItemContainer extends React.Component {
constructor(props) {
super(props);
const FileItem = (props) => {
const { file } = props;
const currentSelectedItem = useSelector(
(state) => state.selectedItem.selected
);
const listView = useSelector((state) => state.filter.listView);
const { image, hasThumbnail, imageOnError } = useThumbnail(
file.metadata.hasThumbnail,
file.metadata.thumbnailID
);
const dispatch = useDispatch();
const lastSelected = useRef(0);
const {
onContextMenu,
closeContextMenu,
onTouchStart,
onTouchMove,
onTouchEnd,
clickStopPropagation,
...contextMenuState
} = useContextMenu();
const fileExtension = useMemo(
() => getFileExtension(file.filename, listView ? 3 : 4),
[file.filename]
);
this.failedToLoad = false;
const imageColor = useMemo(
() => getFileColor(file.filename),
[file.filename]
);
const elementSelected = useMemo(
() => file._id === currentSelectedItem,
[file._id, currentSelectedItem]
);
this.lastTouch = 0;
const fileClick = () => {
const currentDate = Date.now();
this.imageLoaded = false;
this.state = {
contextMenuPos: {},
imageSrc: "/images/file-svg.svg",
imageClassname: "noSelect file__item-no-thumbnail",
contextSelected: false,
editNameMode: false,
editName: this.props.filename,
deleteMode: false,
movingMode: false,
movingPercentage: 0,
};
}
getThumbnail = async () => {
this.imageLoaded = true;
const thumbnailID = this.props.metadata.thumbnailID;
// const imageClassname = this.props.listView ? "file__image__listview--no-opacity" : "file__image--no-opacity"
const imageClassname = "noSelect";
if (this.props.metadata.drive && !this.props.metadata.googleDoc) {
return await this.setState(() => ({
...this.state,
imageSrc: this.props.metadata.thumbnailID,
imageClassname: imageClassname,
}));
if (!elementSelected) {
dispatch(startSetSelectedItem(file._id, true, false));
}
const config = {
responseType: "arraybuffer",
};
const isMobile = mobilecheck();
await this.setState(() => ({
...this.state,
imageSrc: "/images/file-svg.svg",
imageClassname: "noSelect file__item-no-thumbnail",
}));
const url = !this.props.metadata.personalFile
? `/file-service/thumbnail/${thumbnailID}`
: `/file-service-personal/thumbnail/${thumbnailID}`;
axios
.get(url, config)
.then((results) => {
const imgFile = new Blob([results.data]);
const imgUrl = URL.createObjectURL(imgFile);
this.setState(() => ({
...this.state,
imageSrc: imgUrl,
imageClassname: imageClassname,
}));
})
.catch((err) => {
console.log(err);
});
};
thumbnailOnError = () => {
console.log("thumbnail on error");
this.setState(() => ({
...this.state,
imageSrc: "/images/file-svg.svg",
imageClassname: "noSelect file__item-no-thumbnail",
}));
};
componentDidMount = () => {
const hasThumbnail = this.props.metadata.hasThumbnail;
if (
hasThumbnail &&
!this.failedToLoad &&
!this.props.listView &&
!this.imageLoaded
) {
this.getThumbnail();
if (isMobile || currentDate - lastSelected.current < 1500) {
dispatch(setPopupFile({ showPopup: true, ...file }));
}
lastSelected.current = Date.now();
};
shouldComponentUpdate = (nextProp, nextState) => {
if (listView) {
return (
nextProp.itemSelected !== this.props.itemSelected ||
nextProp.listView !== this.props.listView ||
nextProp.rightSelected !== this.props.rightSelected ||
nextState.imageSrc !== this.state.imageSrc ||
nextState.imageClassname !== this.state.imageClassname ||
this.props.filename !== nextProp.filename ||
this.props.metadata.transcoded !== nextProp.metadata.transcode ||
nextState.contextSelected !== this.state.contextSelected ||
nextState.editNameMode !== this.state.editNameMode ||
nextState.editName !== this.state.editName ||
nextState.deleteMode !== this.state.deleteMode ||
nextState.movingMode !== this.state.movingMode ||
nextState.movingPercentage !== this.state.movingPercentage
<tr
className={!elementSelected ? "" : "active__recent"}
onClick={fileClick}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onTouchEnd={onTouchEnd}
>
{/* <ContextMenu parent={props.metadata.parent} contextSelected={props.state.contextSelected} closeContext={props.closeContext} downloadFile={props.downloadFile} file={props} changeEditNameMode={props.changeEditNameMode} closeEditNameMode={props.closeEditNameMode} changeDeleteMode={props.changeDeleteMode} startMovingFile={props.startMovingFile}/> */}
<td class="name__row">
<div class="inner__name--row">
<span class="extension__wrap noSelect">
<div
className="no-extension__wrapper"
style={{ background: imageColor }}
>
<span className="no-extension__title">{fileExtension}</span>
</div>
</span>
<p className="name__row-filename noSelect">{props.file.filename}</p>
</div>
</td>
<td class="location__row noSelect">
{props.file.metadata.drive
? "Google Drive"
: props.file.metadata.personalFile
? "Amazon S3"
: "myDrive"}
</td>
<td class="modified__row noSelect">
{moment(props.uploadDate).format("L")}
</td>
<td class="settings__row noSelect">
<div class="settings__wrap">
<div>
<ContextMenu
gridMode={false}
quickItemMode={false}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
file={file}
/>
</div>
{/* <ContextMenu parent={props.metadata.parent} contextSelected={props.state.contextSelected} closeContext={props.closeContext} downloadFile={props.downloadFile} file={props} changeEditNameMode={props.changeEditNameMode} closeEditNameMode={props.closeEditNameMode} changeDeleteMode={props.changeDeleteMode} startMovingFile={props.startMovingFile}/> */}
<a onClick={onContextMenu}>
<i class="fas fa-ellipsis-h"></i>
</a>
</div>
</td>
</tr>
);
};
componentDidUpdate = (nextProp) => {
// console.log("file item component updated")
return;
const hasThumbnail = this.props.metadata.hasThumbnail;
if (hasThumbnail && !this.failedToLoad && !this.imageLoaded) {
this.getThumbnail();
} else if (nextProp.listView !== this.props.listView) {
this.setState(() => ({
...this.state,
imageClassname: this.props.listView
? "file__image__listview"
: "file__image",
}));
}
};
onTouchStart = () => {
//alert("Touch start");
const date = new Date();
this.lastTouch = date.getTime();
};
onTouchMove = () => {
this.lastTouch = 0;
};
onTouchEnd = () => {
if (this.lastTouch === 0) {
//alert("last touch 0");
return;
}
const date = new Date();
const difference = date - this.lastTouch;
//alert("Touch end: " + difference)
//alert("touch end: " + difference);
this.lastTouch = 0;
if (difference > 500) {
//alert("Context menu");
//this.getContextMenu();
this.selectContext();
}
};
getContextMenu = (e) => {
if (e) e.preventDefault();
const isMobile = mobileCheck();
const windowX = window.innerWidth;
const windowY = window.innerHeight;
let styleObj = { right: 0, left: 0, top: "-38px", bottom: 0 };
if (isMobile) {
styleObj = { bottom: 0, left: "2px", top: "unset", right: "unset" };
} else {
const clientY = e.nativeEvent.clientY;
const clientX = e.nativeEvent.clientX;
if (clientY < windowY / 3) {
styleObj = { bottom: "-190px", top: "unset" };
}
if (clientY > (windowY / 4) * 3.5) {
styleObj = { bottom: "unset", top: "-190px" };
}
if (clientX > windowX / 2) {
styleObj = { ...styleObj, left: "unset", right: 0 };
} else {
styleObj = { ...styleObj, left: 0, right: "unset" };
}
}
// if (isMobile) {
// styleObj = {bottom: 0, left: "2px", top: "unset", right: "unset"}
// }
this.setState(() => ({ ...this.state, contextMenuPos: styleObj }));
this.props.dispatch(startSetSelectedItem(this.props._id, true, false));
this.props.dispatch(setLastSelected(0));
this.props.dispatch(setRightSelected(this.props._id));
};
getWrapperClassname = () => {
let classname = "";
if (this.props.listView) {
classname += "file__item__listview";
} else {
classname += "file__item";
}
if (this.props._id === this.props.selected) {
classname += " file__item--selected";
}
return classname;
};
selectContext = (e) => {
if (e) e.stopPropagation();
if (e) e.preventDefault();
if (mobilecheck()) {
this.props.dispatch(setMobileContextMenu(true, this.props));
return;
}
this.setState(() => {
return {
...this.state,
contextSelected: !this.state.contextSelected,
};
});
};
closeContext = () => {
this.setState(() => {
return {
...this.state,
contextSelected: false,
};
});
};
editNamePopup = async () => {
let inputValue = this.props.filename;
const { value: folderName } = await Swal.fire({
title: "Enter A File Name",
input: "text",
inputValue: inputValue,
showCancelButton: true,
inputValidator: (value) => {
if (!value) {
return "Please Enter a Name";
}
},
});
if (folderName === undefined || folderName === null) {
return;
}
// console.log("rename is google", this.props.isGoogle);
this.props.dispatch(
startRenameFile(this.props._id, folderName, this.props.metadata.drive)
);
};
changeEditNameMode = () => {
this.editNamePopup();
// const isMobile = mobilecheck();
// if (isMobile || !this.props.listView) {
// this.mobileEditName();
// return;
// }
// this.setState(() => {
// return {
// ...this.state,
// editNameMode: !this.state.editNameMode
// }
// })
};
closeEditNameMode = () => {
this.setState(() => {
return {
...this.state,
editNameMode: false,
};
});
};
changeEditName = (e) => {
const value = e.target.value;
this.setState(() => {
return {
...this.state,
editName: value,
};
});
};
saveNameEdit = () => {
const value = this.state.editName;
this.props.dispatch(
startRenameFile(this.props._id, value, this.props.metadata.drive)
);
this.closeEditNameMode();
};
deleteFilePopup = () => {
Swal.fire({
title: "Confirm Deletion",
text: "You cannot undo this action",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete",
}).then((result) => {
if (result.value) {
this.props.dispatch(
startRemoveFile(
this.props._id,
this.props.metadata.drive,
this.props.metadata.personalFile
)
);
}
});
};
removeDeleteMode = () => {
this.setState(() => {
return {
...this.state,
deleteMode: false,
};
});
};
changeDeleteMode = () => {
this.deleteFilePopup();
// const isMobile = mobilecheck();
// if (isMobile || !this.props.listView) {
// this.mobileDeleteFile()
// return;
// }
// this.setState(() => {
// return {
// ...this.state,
// deleteMode: true,
// contextSelected: false
// }
// })
};
startDeleteFile = () => {
//this.props.dispatch(startRemoveFile(this.props._id, this.props.metadata.drive, this.props.metadata.personalFile))
this.changeDeleteMode();
};
startMovingFile = () => {
// console.log("moving file")
// this.setState(() => {
// return {
// ...this.state,
// movingMode: true
// }
// })
// window.setInterval(this.changeMoverPos, 50)
// // REMEMBER TO STOP THIS WHEN FINISHED
this.props.dispatch(
setMoverID(
this.props._id,
this.props.metadata.parent,
true,
this.props.metadata.drive,
this.props.metadata.personalFile
)
);
};
changeMoverPos = () => {
this.setState(() => {
return {
...this.state,
movingPercentage:
this.state.movingPercentage >= 80
? 0
: this.state.movingPercentage + 1,
};
});
};
getFileExtension = (filename) => {
const filenameSplit = filename.split(".");
if (filenameSplit.length > 1) {
let extension = filenameSplit[filenameSplit.length - 1];
if (extension.length > 3)
extension =
extension.substring(0, 2) +
extension.substring(extension.length - 1, extension.length);
return extension.toUpperCase();
} else {
return "UNK";
}
};
getColor = (ext) => {
const letter = ext.substring(0, 1).toUpperCase();
const colorObj = {
A: "#e53935",
B: "#d81b60",
C: "#8e24aa",
D: "#5e35b1",
E: "#3949ab",
F: "#1e88e5",
G: "#039be5",
H: "#00acc1",
I: "#00897b",
J: "#43a047",
K: "#fdd835",
L: "#ffb300",
M: "#fb8c00",
N: "#f4511e",
O: "#d32f2f",
P: "#c2185b",
Q: "#7b1fa2",
R: "#512da8",
S: "#303f9f",
T: "#1976d2",
U: "#0288d1",
V: "#0097a7",
W: "#0097a7",
X: "#00796b",
Y: "#388e3c",
Z: "#fbc02d",
};
if (colorObj[letter]) {
return colorObj[letter];
} else {
return "#03a9f4";
}
};
getExtensionImage = () => {
const ext = this.getFileExtension(this.props.filename);
return { passed: false, ext, color: this.getColor(ext) };
};
startFileClick = () => {
this.props.fileClick(this.props._id, this.props);
};
clickStopPropagation = (e) => {
e.stopPropagation();
};
render() {
} else {
return (
<FileItem
getWrapperClassname={this.getWrapperClassname}
getContextMenu={this.getContextMenu}
onTouchStart={this.onTouchStart}
onTouchEnd={this.onTouchEnd}
onTouchMove={this.onTouchMove}
selectContext={this.selectContext}
closeContext={this.closeContext}
changeEditNameMode={this.changeEditNameMode}
closeEditNameMode={this.closeEditNameMode}
changeEditName={this.changeEditName}
saveNameEdit={this.saveNameEdit}
changeDeleteMode={this.changeDeleteMode}
startDeleteFile={this.startDeleteFile}
startMovingFile={this.startMovingFile}
getExtensionImage={this.getExtensionImage}
startFileClick={this.startFileClick}
clickStopPropagation={this.clickStopPropagation}
removeDeleteMode={this.removeDeleteMode}
thumbnailOnError={this.thumbnailOnError}
state={this.state}
{...this.props}
/>
<div
className={classNames(
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer w-48 flex items-center justify-center flex-col h-[150px] animiate hover:border-[#3c85ee] overflow-hidden",
elementSelected ? "border-[#3c85ee]" : "border-[#ebe9f9]"
)}
onClick={fileClick}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onTouchEnd={onTouchEnd}
>
{contextMenuState.selected && (
<div onClick={clickStopPropagation}>
<ContextMenu
gridMode={true}
quickItemMode={true}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
file={file}
/>
</div>
)}
<div
className={classNames(
"inline-flex items-center w-full bg-white relative",
{
"mt-2": !hasThumbnail,
}
)}
>
{hasThumbnail ? (
<img
className="w-full min-h-[88px] max-h-[88px] h-full flex object-cover"
src={image}
onError={imageOnError}
/>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="150"
height="150"
viewBox="0 0 24 24"
className="w-full min-h-[80px] max-h-[80px] h-full flex"
>
<path
d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z"
fill={imageColor}
/>
</svg>
)}
{!hasThumbnail && (
<div className="w-full h-full absolute flex justify-center items-center text-white mt-3">
<p className="text-sm">{fileExtension}</p>
</div>
)}
</div>
<div
className={classNames(
"p-3 overflow-hidden text-ellipsis block w-full animate",
elementSelected ? "bg-[#3c85ee]" : "bg-white"
)}
>
<p
className={classNames(
"m-0 text-[14px] leading-[16px] font-normal max-w-full overflow-hidden text-ellipsis whitespace-nowrap animate",
elementSelected ? "text-white" : "text-[#212b36]"
)}
>
{capitalize(file.filename)}
</p>
<span
className={classNames(
"m-0 text-[#637381] font-normal max-w-full whitespace-nowrap text-xs animate",
elementSelected ? "text-white" : "text-[#637381]"
)}
>
Created {moment(file.uploadDate).format("MM/DD/YY hh:mma")}
</span>
</div>
</div>
);
}
}
};
const connectStateToProp = (state) => ({
listView: state.filter.listView,
rightSelected: state.selectedItem.rightSelected,
resetSelected: state.selectedItem.resetSelected,
selected: state.selectedItem.selected,
});
export default connect(connectStateToProp)(FileItemContainer);
export default FileItem;
+31 -8
View File
@@ -1,13 +1,20 @@
import React, { useMemo } from "react";
import React, { useMemo, useRef } from "react";
import ContextMenu from "../ContextMenu";
import { useContextMenu } from "../../hooks/contextMenu";
import classNames from "classnames";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { startSetSelectedItem } from "../../actions/selectedItem";
import mobilecheck from "../../utils/mobileCheck";
const FolderItem = (props) => {
const { folder } = props;
const currentSelectedItem = useSelector(
(state) => state.selectedItem.selected
);
const lastSelected = useRef(0);
const navigate = useNavigate();
const dispatch = useDispatch();
const {
onContextMenu,
closeContextMenu,
@@ -19,10 +26,26 @@ const FolderItem = (props) => {
} = useContextMenu();
const elementSelected = useMemo(
() => props._id === currentSelectedItem,
[props._id, currentSelectedItem]
() => props.folder._id === currentSelectedItem,
[props.folder._id, currentSelectedItem]
);
const folderClick = () => {
const currentDate = Date.now();
if (!elementSelected) {
dispatch(startSetSelectedItem(folder._id, false, false));
}
const isMobile = mobilecheck();
if (isMobile || currentDate - lastSelected.current < 1500) {
navigate(`/folder/${folder._id}`);
}
lastSelected.current = Date.now();
};
return (
<div
className={classNames(
@@ -31,7 +54,7 @@ const FolderItem = (props) => {
"bg-[#3c85ee]": elementSelected,
}
)}
onClick={() => props.folderClick(props._id, props)}
onClick={folderClick}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
@@ -41,10 +64,10 @@ const FolderItem = (props) => {
<ContextMenu
gridMode={true}
folderMode={true}
quickItemMode={props.parent !== "/"}
quickItemMode={props.folder.parent !== "/"}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
folder={props}
folder={props.folder}
/>
</div>
<div>
@@ -74,7 +97,7 @@ const FolderItem = (props) => {
elementSelected ? "text-white" : "text-black"
)}
>
<p>{props.name}</p>
<p>{props.folder.name}</p>
</div>
</div>
);
+2
View File
@@ -61,6 +61,8 @@ class MainSectionContainer extends React.Component {
const isMobile = mobileCheck();
console.log("file", file);
if (
(currentDate - this.props.lastSelected < 1500 &&
selectedFileID === this.props.selected) ||
+1 -6
View File
@@ -50,12 +50,7 @@ const QuickAccess = (props) => {
}}
>
{quickfilesList?.map((file) => (
<QuickAccessItem
key={file._id}
downloadFile={props.downloadFile}
fileClick={props.fileClick}
{...file}
/>
<QuickAccessItem key={file._id} file={file} />
))}
</div>
</div>
+36 -16
View File
@@ -1,21 +1,27 @@
import capitalize from "../../utils/capitalize";
import moment from "moment";
import React, { useMemo } from "react";
import React, { useMemo, useRef } from "react";
import ContextMenu from "../ContextMenu";
import classNames from "classnames";
import { getFileColor, getFileExtension } from "../../utils/files";
import { useThumbnail } from "../../hooks/files";
import { useContextMenu } from "../../hooks/contextMenu";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import mobilecheck from "../../utils/mobileCheck";
import { startSetSelectedItem } from "../../actions/selectedItem";
import { setPopupFile } from "../../actions/popupFile";
const QuickAccessItem = (props) => {
const { file } = props;
const currentSelectedItem = useSelector(
(state) => state.selectedItem.selected
);
const { image, hasThumbnail, imageOnError } = useThumbnail(
props.metadata.hasThumbnail,
props.metadata.thumbnailID
file.metadata.hasThumbnail,
file.metadata.thumbnailID
);
const dispatch = useDispatch();
const lastSelected = useRef(0);
const {
onContextMenu,
@@ -28,29 +34,43 @@ const QuickAccessItem = (props) => {
} = useContextMenu();
const fileExtension = useMemo(
() => getFileExtension(props.filename),
[props.filename]
() => getFileExtension(file.filename),
[file.filename]
);
const imageColor = useMemo(
() => getFileColor(props.filename),
[props.filename]
() => getFileColor(file.filename),
[file.filename]
);
const elementSelected = useMemo(
() => `quick-${props._id}` === currentSelectedItem,
[props._id, currentSelectedItem]
() => `quick-${file._id}` === currentSelectedItem,
[file._id, currentSelectedItem]
);
const quickItemClick = () => {
const currentDate = Date.now();
if (!elementSelected) {
dispatch(startSetSelectedItem(file._id, true, true));
}
const isMobile = mobilecheck();
if (isMobile || currentDate - lastSelected.current < 1500) {
dispatch(setPopupFile({ showPopup: true, ...file }));
}
lastSelected.current = Date.now();
};
return (
<div
className={classNames(
"border rounded-md o transition-all duration-400 ease-in-out cursor-pointer w-48 flex items-center justify-center flex-col h-[150px] animiate hover:border-[#3c85ee] overflow-hidden",
elementSelected ? "border-[#3c85ee]" : "border-[#ebe9f9]"
)}
onClick={() => {
props.fileClick(props._id, props, true);
}}
onClick={quickItemClick}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
@@ -63,7 +83,7 @@ const QuickAccessItem = (props) => {
quickItemMode={true}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
file={props}
file={file}
/>
</div>
)}
@@ -115,7 +135,7 @@ const QuickAccessItem = (props) => {
elementSelected ? "text-white" : "text-[#212b36]"
)}
>
{capitalize(props.filename)}
{capitalize(file.filename)}
</p>
<span
className={classNames(
@@ -123,7 +143,7 @@ const QuickAccessItem = (props) => {
elementSelected ? "text-white" : "text-[#637381]"
)}
>
Created {moment(props.uploadDate).format("MM/DD/YY hh:mma")}
Created {moment(file.uploadDate).format("MM/DD/YY hh:mma")}
</span>
</div>
</div>
+1 -1
View File
@@ -42,7 +42,7 @@
@import "./components/MobileContextMenu";
.animate {
transition: 0.3s ease all;
transition: 0.2s ease all;
}
.animate-movement {
+3 -3
View File
@@ -1,12 +1,12 @@
export const getFileExtension = (filename: string) => {
export const getFileExtension = (filename: string, length = 4) => {
const filenameSplit = filename.split(".");
if (filenameSplit.length > 1) {
let extension = filenameSplit[filenameSplit.length - 1];
if (extension.length > 4)
if (extension.length > length)
extension =
extension.substring(0, 3) +
extension.substring(0, length - 1) +
extension.substring(extension.length - 1, extension.length);
return extension.toUpperCase();