diff --git a/src/components/NewContextMenu/NewContextMenu.jsx b/src/components/NewContextMenu/NewContextMenu.jsx deleted file mode 100644 index 027b9a8..0000000 --- a/src/components/NewContextMenu/NewContextMenu.jsx +++ /dev/null @@ -1,124 +0,0 @@ -import classNames from "classnames"; -import React from "react"; -import Swal from "sweetalert2"; -import { deleteFile, renameFile } from "../../api/filesAPI"; -import { useFiles, useQuickFiles } from "../../hooks/files"; - -const NewContextMenu = (props) => { - const { invalidateFilesCache } = useFiles(); - const { invalidateQuickFilesCache } = useQuickFiles(); - const liClassname = - "flex w-full px-[20px] py-[12px] items-center font-normal justify-start no-underline transition-all duration-400 ease-in-out hover:bg-[#f6f5fd] hover:text-[#3c85ee] hover:font-medium"; - const spanClassname = "inline-flex mr-[18px]"; - - const renameItem = async () => { - if (!props.folderMode) { - const { value: filename } = await Swal.fire({ - title: "Enter A File Name", - input: "text", - inputValue: props.file.filename, - showCancelButton: true, - inputValidator: (value) => { - if (!value) { - return "Please Enter a Name"; - } - }, - }); - await renameFile(props.file._id, filename); - invalidateFilesCache(); - invalidateQuickFilesCache(); - } - }; - - const deleteItem = async () => { - if (!props.folderMode) { - const result = await Swal.fire({ - title: "Confirm Deletion", - text: "You cannot undo this action", - icon: "warning", - showCancelButton: true, - confirmButtonColor: "#3085d6", - cancelButtonColor: "#d33", - confirmButtonText: "Yes, delete", - }); - - if (result.value) { - await deleteFile(props.file._id); - invalidateFilesCache(); - invalidateQuickFilesCache(); - } - } - }; - - return ( -
- -
- ); -}; - -export default NewContextMenu; diff --git a/src/components/NewContextMenu/index.jsx b/src/components/NewContextMenu/index.jsx index b442ade..65ad962 100644 --- a/src/components/NewContextMenu/index.jsx +++ b/src/components/NewContextMenu/index.jsx @@ -1,73 +1,162 @@ -import React from "react"; -import { connect } from "react-redux"; -import { setShareSelected } from "../../actions/selectedItem"; -import NewContextMenu from "./NewContextMenu"; +import classNames from "classnames"; +import React, { useEffect, useRef } from "react"; +import Swal from "sweetalert2"; +import { deleteFile, renameFile } from "../../api/filesAPI"; +import { useFiles, useQuickFiles } from "../../hooks/files"; -class NewContextMenuContainer extends React.Component { - constructor(props) { - super(props); +const NewContextMenu = (props) => { + const { invalidateFilesCache } = useFiles(); + const { invalidateQuickFilesCache } = useQuickFiles(); + const wrapperRef = useRef(); + const liClassname = + "flex w-full px-[20px] py-[12px] items-center font-normal justify-start no-underline transition-all duration-400 ease-in-out hover:bg-[#f6f5fd] hover:text-[#3c85ee] hover:font-medium"; + const spanClassname = "inline-flex mr-[18px]"; - this.wrapperRef = React.createRef(); - } - - componentDidMount = () => { - document.addEventListener("mousedown", this.handleClickOutside); - }; - - componentWillUnmount = () => { - document.removeEventListener("mousedown", this.handleClickOutside); - }; - - componentDidUpdate = () => {}; - - handleClickOutside = () => { - if ( - this.props.contextSelected.selected && - this.wrapperRef && - !this.wrapperRef.current.contains(event.target) - ) { - this.props.closeContext(); + const renameItem = async () => { + if (!props.folderMode) { + const { value: filename } = await Swal.fire({ + title: "Enter A File Name", + input: "text", + inputValue: props.file.filename, + showCancelButton: true, + inputValidator: (value) => { + if (!value) { + return "Please Enter a Name"; + } + }, + }); + await renameFile(props.file._id, filename); + invalidateFilesCache(); + invalidateQuickFilesCache(); } }; - startFileDownload = () => { - console.log("start download file", this.props.file._id); - this.props.downloadFile(this.props.file._id, this.props.file); + const deleteItem = async () => { + if (!props.folderMode) { + const result = await Swal.fire({ + title: "Confirm Deletion", + text: "You cannot undo this action", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#3085d6", + cancelButtonColor: "#d33", + confirmButtonText: "Yes, delete", + }); + + if (result.value) { + await deleteFile(props.file._id); + invalidateFilesCache(); + invalidateQuickFilesCache(); + } + } }; - startRenameFile = async (e) => { - console.log("rename file click"); - this.props.changeEditNameMode(); + // startMovingFile = async () => { + // this.props.dispatch( + // setMoverID( + // this.props._id, + // this.props.metadata.parent, + // true, + // this.props.metadata.drive, + // this.props.metadata.personalFile + // ) + // ); + // }; + + // startShareFile = () => { + // this.props.dispatch(setShareSelected({ ...this.props.file })); + // }; + + // startFileDownload = () => { + // console.log("start download file", this.props.file._id); + // this.props.downloadFile(this.props.file._id, this.props.file); + // }; + + const outOfBoundsClickCheck = () => { + if (wrapperRef && !wrapperRef.current.contains(event.target)) { + props.closeContext(); + } }; - startDeleteFile = async () => { - this.props.changeDeleteMode(); - }; + useEffect(() => { + document.addEventListener("mousedown", outOfBoundsClickCheck); + document.addEventListener("touchstart", outOfBoundsClickCheck); - startShareFile = () => { - this.props.dispatch(setShareSelected({ ...this.props.file })); - }; + return () => { + document.removeEventListener("mousedown", outOfBoundsClickCheck); + document.removeEventListener("touchstart", outOfBoundsClickCheck); + }; + }, []); - stopPropagation = (e) => { - e.stopPropagation(); - if (this.props.quickItemMode || this.props.gridMode) - this.props.closeContext(); - }; + return ( +
+ +
+ ); +}; - render() { - return ( - - ); - } -} - -export default connect()(NewContextMenuContainer); +export default NewContextMenu; diff --git a/src/components/NewContextMenu/index2.jsx b/src/components/NewContextMenu/index2.jsx new file mode 100644 index 0000000..da0b285 --- /dev/null +++ b/src/components/NewContextMenu/index2.jsx @@ -0,0 +1,75 @@ +import React from "react"; +import { connect } from "react-redux"; +import { setShareSelected } from "../../actions/selectedItem"; +import NewContextMenu from "."; + +class NewContextMenuContainer extends React.Component { + constructor(props) { + super(props); + + this.wrapperRef = React.createRef(); + } + + // componentDidMount = () => { + // document.addEventListener("mousedown", this.handleClickOutside); + // document.addEventListener("touchstart", this.handleClickOutside); + // }; + + // componentWillUnmount = () => { + // document.removeEventListener("mousedown", this.handleClickOutside); + // document.removeEventListener("touchstart", this.handleClickOutside); + // }; + + componentDidUpdate = () => {}; + + handleClickOutside = () => { + if ( + this.props.contextSelected.selected && + this.wrapperRef && + !this.wrapperRef.current.contains(event.target) + ) { + this.props.closeContext(); + } + }; + + startFileDownload = () => { + console.log("start download file", this.props.file._id); + this.props.downloadFile(this.props.file._id, this.props.file); + }; + + startRenameFile = async (e) => { + console.log("rename file click"); + this.props.changeEditNameMode(); + }; + + startDeleteFile = async () => { + this.props.changeDeleteMode(); + }; + + startShareFile = () => { + this.props.dispatch(setShareSelected({ ...this.props.file })); + }; + + stopPropagation = (e) => { + e.stopPropagation(); + if (this.props.quickItemMode || this.props.gridMode) + this.props.closeContext(); + }; + + // render() { + // return ( + // + // ); + // } +} + +export default connect()(NewContextMenuContainer); diff --git a/src/components/QuickAccessItem/QuickAccessItem.jsx b/src/components/QuickAccessItem/QuickAccessItem.jsx deleted file mode 100644 index 92718f5..0000000 --- a/src/components/QuickAccessItem/QuickAccessItem.jsx +++ /dev/null @@ -1,127 +0,0 @@ -import capitalize from "../../utils/capitalize"; -import moment from "moment"; -import React, { useMemo, useState } from "react"; -import NewContextMenu from "../NewContextMenu"; -import classNames from "classnames"; -import { getFileColor, getFileExtension } from "../../utils/files"; -import { useThumbnail } from "../../hooks/files"; -import { useContextMenu } from "../../hooks/contextMenu"; - -const QuickAccessItem = (props) => { - const { image, hasThumbnail, imageOnError } = useThumbnail( - props.metadata.hasThumbnail, - props.metadata.thumbnailID - ); - - const { onContextMenu, closeContextMenu, ...contextMenuState } = - useContextMenu(); - - const fileExtension = useMemo( - () => getFileExtension(props.filename), - [props.filename] - ); - - const imageColor = useMemo( - () => getFileColor(props.filename), - [props.filename] - ); - - const elementSelected = useMemo( - () => `quick-${props._id}` === props.selected, - [props._id, props.selected] - ); - - return ( -
{ - props.fileClick(props._id, props, true); - }} - onContextMenu={onContextMenu} - onTouchStart={props.onTouchStart} - onTouchEnd={props.onTouchEnd} - onTouchMove={props.onTouchMove} - > - {contextMenuState.selected && ( -
- -
- )} -
- {hasThumbnail ? ( - - ) : ( - - - - )} - {!hasThumbnail && ( -
-

{fileExtension}

-
- )} -
-
-

- {capitalize(props.filename)} -

- - Created {moment(props.uploadDate).calendar()} - -
-
- ); -}; - -export default QuickAccessItem; diff --git a/src/components/QuickAccessItem/index.jsx b/src/components/QuickAccessItem/index.jsx index ff3072c..6a6b9e0 100644 --- a/src/components/QuickAccessItem/index.jsx +++ b/src/components/QuickAccessItem/index.jsx @@ -1,152 +1,134 @@ -import QuickAccessItem from "./QuickAccessItem"; -import { - setRightSelected, - setLastSelected, - setSelected, -} 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 Swal from "sweetalert2"; -import { startRenameFile, startRemoveFile } from "../../actions/files"; -import { setMoverID } from "../../actions/mover"; -import mobilecheck from "../../utils/mobileCheck"; -import { setMobileContextMenu } from "../../actions/mobileContextMenu"; +import capitalize from "../../utils/capitalize"; +import moment from "moment"; +import React, { useMemo, useState } from "react"; +import NewContextMenu from "../NewContextMenu"; +import classNames from "classnames"; +import { getFileColor, getFileExtension } from "../../utils/files"; +import { useThumbnail } from "../../hooks/files"; +import { useContextMenu } from "../../hooks/contextMenu"; -const currentURL = env.url; +const QuickAccessItem = (props) => { + const { image, hasThumbnail, imageOnError } = useThumbnail( + props.metadata.hasThumbnail, + props.metadata.thumbnailID + ); -class QuickAccessItemContainer extends React.Component { - constructor(props) { - super(props); + const { + onContextMenu, + closeContextMenu, + onTouchStart, + onTouchMove, + onTouchEnd, + clickStopPropagation, + ...contextMenuState + } = useContextMenu(); - this.failedToLoad = false; - this.lastTouch = 0; + const fileExtension = useMemo( + () => getFileExtension(props.filename), + [props.filename] + ); - this.state = { - image: "/images/file-svg.svg", - imageClassname: "noSelect file__item-no-thumbnail", - contextSelected: false, - hasThumbnail: false, - }; - } + const imageColor = useMemo( + () => getFileColor(props.filename), + [props.filename] + ); - onTouchStart = () => { - const date = new Date(); - this.lastTouch = date.getTime(); - }; + const elementSelected = useMemo( + () => `quick-${props._id}` === props.selected, + [props._id, props.selected] + ); - onTouchMove = () => { - this.lastTouch = 0; - }; + return ( +
{ + props.fileClick(props._id, props, true); + }} + onContextMenu={onContextMenu} + onTouchStart={onTouchStart} + onTouchMove={onTouchMove} + onTouchEnd={onTouchEnd} + > + {contextMenuState.selected && ( +
+ +
+ )} +
+ {hasThumbnail ? ( + + ) : ( + + + + )} + {!hasThumbnail && ( +
+

{fileExtension}

+
+ )} +
+
+

+ {capitalize(props.filename)} +

+ + Created {moment(props.uploadDate).calendar()} + +
+
+ ); +}; - onTouchEnd = () => { - if (this.lastTouch === 0) { - return; - } - - const date = new Date(); - const difference = date - this.lastTouch; - - this.lastTouch = 0; - - if (difference > 500) { - // this.selectContext(); - } - }; - - changeEditNameMode = 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; - } - - this.props.dispatch( - startRenameFile(this.props._id, folderName, this.props.metadata.drive) - ); - }; - - closeEditNameMode = () => { - this.setState(() => { - return { - ...this.state, - editNameMode: false, - }; - }); - }; - - changeDeleteMode = async () => { - 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 - ) - ); - } - }); - }; - - startMovingFile = async () => { - this.props.dispatch( - setMoverID( - this.props._id, - this.props.metadata.parent, - true, - this.props.metadata.drive, - this.props.metadata.personalFile - ) - ); - }; - - clickStopPropagation = (e) => { - e.stopPropagation(); - }; - - render() { - return ( - - ); - } -} - -const connectStateToProp = (state) => ({ - rightSelected: state.selectedItem.rightSelected, - selected: state.selectedItem.selected, -}); - -export default connect(connectStateToProp)(QuickAccessItemContainer); +export default QuickAccessItem; diff --git a/src/components/QuickAccessItem/index2.jsx b/src/components/QuickAccessItem/index2.jsx new file mode 100644 index 0000000..8c1a7de --- /dev/null +++ b/src/components/QuickAccessItem/index2.jsx @@ -0,0 +1,117 @@ +import QuickAccessItem from "."; +import { + setRightSelected, + setLastSelected, + setSelected, +} 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 Swal from "sweetalert2"; +import { startRenameFile, startRemoveFile } from "../../actions/files"; +import { setMoverID } from "../../actions/mover"; +import mobilecheck from "../../utils/mobileCheck"; +import { setMobileContextMenu } from "../../actions/mobileContextMenu"; + +const currentURL = env.url; + +class QuickAccessItemContainer extends React.Component { + constructor(props) { + super(props); + + this.failedToLoad = false; + + this.state = { + image: "/images/file-svg.svg", + imageClassname: "noSelect file__item-no-thumbnail", + contextSelected: false, + hasThumbnail: false, + }; + } + + changeEditNameMode = 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; + } + + this.props.dispatch( + startRenameFile(this.props._id, folderName, this.props.metadata.drive) + ); + }; + + closeEditNameMode = () => { + this.setState(() => { + return { + ...this.state, + editNameMode: false, + }; + }); + }; + + changeDeleteMode = async () => { + 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 + ) + ); + } + }); + }; + + startMovingFile = async () => { + this.props.dispatch( + setMoverID( + this.props._id, + this.props.metadata.parent, + true, + this.props.metadata.drive, + this.props.metadata.personalFile + ) + ); + }; + + // render() { + // return ( + // + // ); + // } +} + +const connectStateToProp = (state) => ({ + rightSelected: state.selectedItem.rightSelected, + selected: state.selectedItem.selected, +}); + +export default connect(connectStateToProp)(QuickAccessItemContainer); diff --git a/src/hooks/contextMenu.ts b/src/hooks/contextMenu.ts index 8197633..8807b4f 100644 --- a/src/hooks/contextMenu.ts +++ b/src/hooks/contextMenu.ts @@ -1,12 +1,12 @@ -import { useState } from "react"; +import { useRef, useState } from "react"; export const useContextMenu = () => { const [contextData, setContextData] = useState({ selected: false, X: 0, Y: 0, - lastTouched: 0, }); + const lastTouched = useRef(0); const onContextMenu = (e: React.MouseEvent) => { if (e) e.stopPropagation(); @@ -25,9 +25,44 @@ export const useContextMenu = () => { selected: false, X: 0, Y: 0, - lastTouched: 0, }); }; - return { ...contextData, onContextMenu, closeContextMenu }; + const onTouchStart = () => { + lastTouched.current = new Date().getTime(); + }; + + const onTouchMove = () => { + lastTouched.current = 0; + }; + + const onTouchEnd = () => { + if (lastTouched.current === 0) { + return; + } + + const date = new Date(); + const difference = date.getTime() - lastTouched.current; + + if (difference > 500) { + setContextData({ + ...contextData, + selected: true, + }); + } + }; + + const clickStopPropagation = (e: React.MouseEvent) => { + e.stopPropagation(); + }; + + return { + ...contextData, + onContextMenu, + closeContextMenu, + onTouchStart, + onTouchMove, + onTouchEnd, + clickStopPropagation, + }; };