made right section and main scetion into functional components and fixed styling

This commit is contained in:
subnub
2024-06-24 20:56:37 -04:00
parent b4b191b3a5
commit 9699a35f59
14 changed files with 506 additions and 1028 deletions
+1
View File
@@ -149,6 +149,7 @@ export const startSetSelectedItem = (
id,
drive,
personalFile,
data: results.data,
})
);
})
+9
View File
@@ -25,6 +25,15 @@ export const getFoldersList = async ({
return response.data;
};
export const getFolderInfo = async ({
queryKey,
}: QueryFunctionContext<[string, { id: string | undefined }]>) => {
const [_key, { id }] = queryKey;
if (!id) return undefined;
const response = await axios.get(`/folder-service/info/${id}`);
return response.data;
};
// PATCH
export const renameFolder = async (folderID: string, name: string) => {
+3 -3
View File
@@ -3,10 +3,10 @@ import Folders from "../Folders";
import { useFiles } from "../../hooks/files";
import { useInfiniteScroll } from "../../hooks/infiniteScroll";
import Files from "../Files";
import { useEffect, useState } from "react";
import { memo, useEffect, useState } from "react";
import SpinnerPage from "../SpinnerPage";
const DataForm = () => {
const DataForm = memo(() => {
const {
fetchNextPage: filesFetchNextPage,
isFetchingNextPage,
@@ -45,6 +45,6 @@ const DataForm = () => {
)}
</div>
);
};
});
export default DataForm;
+32 -7
View File
@@ -1,12 +1,15 @@
import { useDispatch, useSelector } from "react-redux";
import { disableListView, enableListView } from "../../actions/filter";
import { useFiles } from "../../hooks/files";
import { useUtils } from "../../hooks/utils";
import SpinnerImage from "../SpinnerImage";
import React from "react";
import React, { memo, useMemo } from "react";
import FileItem from "../FileItem";
import ParentBar from "../ParentBar";
import { useParams } from "react-router-dom";
import classNames from "classnames";
const Files = () => {
const Files = memo(() => {
const { data: files } = useFiles();
const parent = useSelector((state) => state.parent.parent);
const listView = useSelector((state) => state.filter.listView);
@@ -14,6 +17,8 @@ const Files = () => {
const loading = useSelector((state) => state.main.loading);
const loadingMore = useSelector((state) => state.main.loadingMoreItems);
const search = useSelector((state) => state.filter.search);
const { isHome } = useUtils();
const dispatch = useDispatch();
const changeListViewMode = () => {
@@ -27,9 +32,22 @@ const Files = () => {
<div className="mt-8">
<div>
<div className="flex justify-between items-center mb-[20px]">
<h2 className="m-0 text-[22px] font-medium">
{search !== "" ? "Files" : "Home Files"}
</h2>
{isHome && (
<h2 className="m-0 text-[22px] font-medium">
{search !== "" ? "Files" : "Home Files"}
</h2>
)}
{!isHome && (
<React.Fragment>
<div className="hidden sm:block">
<ParentBar />
</div>
<h2 className="block sm:hidden m-0 text-[22px] font-medium">
Files
</h2>
</React.Fragment>
)}
<div>
<ul className="flex items-center list-none m-0 p-0">
<li className="mr-4" onClick={changeListViewMode}>
@@ -83,7 +101,14 @@ const Files = () => {
</div>
{!listView ? (
<div className="grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px] justify-center xs:justify-normal">
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
files?.pages[0]?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal"
)}
>
{files?.pages.map((filePage, index) => (
<React.Fragment key={index}>
{filePage.map((file) => (
@@ -139,6 +164,6 @@ const Files = () => {
</div>
</div>
);
};
});
export default Files;
+15 -10
View File
@@ -2,12 +2,13 @@ import { useDispatch, useSelector } from "react-redux";
import { useFolders } from "../../hooks/folders";
import { setSortBy } from "../../actions/filter";
import FolderItem from "../FolderItem";
import { useCallback, useEffect } from "react";
import { memo, useCallback, useEffect } from "react";
import ParentBar from "../ParentBar";
import classNames from "classnames";
const Folder = () => {
const Folders = memo(() => {
const { data: folders } = useFolders();
const sortBy = useSelector((state) => state.filter.sortBy);
const parent = useSelector((state) => state.parent.parent);
const dispatch = useDispatch();
const switchOrderSortBy = useCallback(() => {
@@ -64,10 +65,7 @@ const Folder = () => {
);
return (
<div
className="mt-8"
// style={props.loading ? { display: "none" } : { display: "block" }}
>
<div className="mt-8">
<div className="flex flex-row mb-[20px] justify-between text-[#212b36] items-center">
<h2 className="m-0 text-[22px] font-medium">
{folders?.length === 0 ? "No Folders" : "Folders"}
@@ -109,13 +107,20 @@ const Folder = () => {
</div>
</div>
<div className="grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px] justify-center xs:justify-normal">
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
folders?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal"
)}
>
{folders?.map((folder) => (
<FolderItem folder={folder} key={folder._id} />
))}
</div>
</div>
);
};
});
export default Folder;
export default Folders;
+64 -57
View File
@@ -1,73 +1,80 @@
import React from "react";
import { useNavigate } from "react-router-dom";
const Header = (props) => (
<header>
<div className="container">
<div className="outer__header">
<div className="left__header">
<div className="logo__wrapper">
<a onClick={props.goHome}>
<img
className="header__icon"
src="/images/mydrive-logo.png"
alt="logo"
const Header = (props) => {
const navigate = useNavigate();
return (
<header>
<div className="container">
<div className="outer__header">
<div className="left__header">
<div className="logo__wrapper">
<a onClick={() => navigate("/")}>
<img
className="header__icon"
src="/images/mydrive-logo.png"
alt="logo"
/>
</a>
</div>
<div className="search__wrapper">
<a href="#">
<img src="/assets/searchicon.svg" alt="search" />
</a>
<input
type="text"
onChange={props.searchOnChange}
value={props.search}
placeholder="Search"
onFocus={props.showSuggested}
onBlur={props.hideSuggested}
/>
</a>
</div>
<div className="search__wrapper">
<a href="#">
<img src="/assets/searchicon.svg" alt="search" />
</a>
<input
type="text"
onChange={props.searchOnChange}
value={props.search}
placeholder="Search"
onFocus={props.showSuggested}
onBlur={props.hideSuggested}
/>
<div
className="search__files--dropdown"
style={
props.state.focused && props.searchValue.length !== 0
? { display: "block" }
: { display: "none" }
}
>
<div
onMouseDown={props.selectSuggestedByParent}
className="elem__search--files search__filter--local"
className="search__files--dropdown"
style={
props.state.focused && props.searchValue.length !== 0
? { display: "block" }
: { display: "none" }
}
>
<a>
Search for{" "}
<span className="file__name">{props.searchValue}</span>
<span className="spacer">
<img src="/assets/spacer.svg" alt="spacer" />
</span>
</a>
<div
onMouseDown={props.selectSuggestedByParent}
className="elem__search--files search__filter--local"
>
<a>
Search for{" "}
<span className="file__name">{props.searchValue}</span>
<span className="spacer">
<img src="/assets/spacer.svg" alt="spacer" />
</span>
</a>
</div>
</div>
</div>
</div>
</div>
<div className="right__header">
<div className="profile__info">
<div className="settings__button">
<a onClick={props.goToSettings}>
<img src="/assets/settings.svg" alt="settings" />
</a>
</div>
<div className="profile__wrapper">
<div className="profile__button">
<a style={{ backgroundColor: "#3c85ee" }}>
<span style={{ color: "#fff" }}>{props.getProfilePic()}</span>
<div className="right__header">
<div className="profile__info">
<div className="settings__button">
<a onClick={props.goToSettings}>
<img src="/assets/settings.svg" alt="settings" />
</a>
</div>
<div className="profile__wrapper">
<div className="profile__button">
<a style={{ backgroundColor: "#3c85ee" }}>
<span style={{ color: "#fff" }}>
{props.getProfilePic()}
</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
);
</header>
);
};
export default Header;
-119
View File
@@ -1,119 +0,0 @@
import DataForm from "../Dataform";
import RightSection from "../RightSection";
import MoverMenu from "../MoverMenu";
import PopupWindow from "../PopupWindow";
import React from "react";
import LeftSection from "../LeftSection";
const MainSection = React.forwardRef((props, ref) => {
return (
<div className="content__block">
<div
className="overlay"
style={
props.leftSectionMode === "open" || props.rightSectionMode === "open"
? { display: "block" }
: { display: "none" }
}
></div>
<div className="small__switcher--content">
<a onClick={props.switchLeftSectionMode} className="menu__button">
<i className="fas fa-bars"></i>
</a>
<a onClick={props.switchRightSectionMode} className="image__viewer">
<i className="fas fa-images"></i>
</a>
</div>
<div
className="file__container"
style={
props.routeType === "search"
? { flexDirection: "column" }
: { flexDirection: "row" }
}
>
{true ? undefined : (
<div className="file__control--panel empty__control--panel">
<div className="file__get--started">
<div className="get__started--image">
<img src="/assets/get_startedfile.svg" alt="get" />
</div>
<h6>All your files in one place</h6>
<p>Drag and drop a file to get started</p>
</div>
</div>
)}
{props.routeType === "search" ? (
<div
className="file__control--panel folder__view"
style={{ paddingBottom: "0", marginBottom: "-50px" }}
>
<div className="results__files">
<h2>
<span className="counter__result">
{props.files.length + props.folders.length >= 50
? "50+"
: props.files.length + props.folders.length}
</span>{" "}
<span className="result__word">results</span> for{" "}
<span className="result__search--word">
{props.cachedSearch}
</span>
</h2>
<p className="searching__result">
You are searching in{" "}
<span className="root__parent">
{props.parent === "/"
? "Home"
: props.parentNameList.length !== 0
? props.parentNameList[props.parentNameList.length - 1]
: "Unknown"}
</span>{" "}
<span className="spacer">
<img
style={{
height: "11px",
marginTop: "2px",
display: "none",
}}
src="/assets/smallspacer.svg"
alt="spacer"
/>
</span>
<span className="current__folder"></span>{" "}
<a
href="#"
style={{ display: "none" }}
className="search__filter--global"
>
Show results from everywhere
</a>
</p>
</div>
</div>
) : undefined}
{props.showPopup ? (
<PopupWindow downloadFile={props.downloadFile} />
) : undefined}
{props.moverID.length === 0 ? undefined : <MoverMenu />}
<div className="flex flex-row h-screen w-screen pt-16">
<LeftSection goHome={() => {}} />
<DataForm />
<RightSection
folderClick={props.folderClick}
fileClick={props.fileClick}
downloadFile={props.downloadFile}
/>
</div>
</div>
</div>
);
});
export default MainSection;
+107 -293
View File
@@ -1,302 +1,116 @@
import { startLoadMoreFiles } from "../../actions/files";
import {
startSetSelectedItem,
setLastSelected,
} from "../../actions/selectedItem";
import {
setLoading,
setLeftSectionMode,
setRightSectionMode,
} from "../../actions/main";
import { setPopupFile } from "../../actions/popupFile";
import mobileCheck from "../../utils/mobileCheck";
import MainSection from "./MainSection";
import env from "../../enviroment/envFrontEnd";
import axios from "../../axiosInterceptor";
import { connect } from "react-redux";
// import { history } from "../../routers/AppRouter";
import React from "react";
import { getUpdateSettingsID } from "../../utils/updateSettings";
import withNavigate from "../HocComponent";
import DataForm from "../Dataform";
import RightSection from "../RightSection";
import MoverMenu from "../MoverMenu";
import PopupWindow from "../PopupWindow";
import React, { memo } from "react";
import LeftSection from "../LeftSection";
import { useSelector } from "react-redux";
class MainSectionContainer extends React.Component {
constructor(props) {
super(props);
const MainSection = memo(() => {
const moverID = useSelector((state) => state.mover.id);
const showPopup = useSelector((state) => state.popupFile.showPopup);
return (
<div>
{/* <div
className="overlay"
style={
props.leftSectionMode === "open" || props.rightSectionMode === "open"
? { display: "block" }
: { display: "none" }
}
></div>
<div className="small__switcher--content">
<a onClick={props.switchLeftSectionMode} className="menu__button">
<i className="fas fa-bars"></i>
</a>
<a onClick={props.switchRightSectionMode} className="image__viewer">
<i className="fas fa-images"></i>
</a>
</div> */}
<div
className="flex h-full"
// style={
// props.routeType === "search"
// ? { flexDirection: "column" }
// : { flexDirection: "row" }
// }
>
{/* {true ? undefined : (
<div className="file__control--panel empty__control--panel">
<div className="file__get--started">
<div className="get__started--image">
<img src="/assets/get_startedfile.svg" alt="get" />
</div>
<h6>All your files in one place</h6>
<p>Drag and drop a file to get started</p>
</div>
</div>
)} */}
this.doubleClickFoldersMobile = false;
this.lastSettingsUpdateID = "";
}
{/* {props.routeType === "search" ? (
<div
className="file__control--panel folder__view"
style={{ paddingBottom: "0", marginBottom: "-50px" }}
>
<div className="results__files">
<h2>
<span className="counter__result">
{props.files.length + props.folders.length >= 50
? "50+"
: props.files.length + props.folders.length}
</span>{" "}
<span className="result__word">results</span> for{" "}
<span className="result__search--word">
{props.cachedSearch}
</span>
</h2>
<p className="searching__result">
You are searching in{" "}
<span className="root__parent">
{props.parent === "/"
? "Home"
: props.parentNameList.length !== 0
? props.parentNameList[props.parentNameList.length - 1]
: "Unknown"}
</span>{" "}
<span className="spacer">
<img
style={{
height: "11px",
marginTop: "2px",
display: "none",
}}
src="/assets/smallspacer.svg"
alt="spacer"
/>
</span>
<span className="current__folder"></span>{" "}
<a
href="#"
style={{ display: "none" }}
className="search__filter--global"
>
Show results from everywhere
</a>
</p>
</div>
</div>
) : undefined} */}
folderClick = (id, folder, bypass = false) => {
const currentDate = Date.now();
const mobile = mobileCheck();
const selectedID = this.props.selected;
{showPopup ? <PopupWindow /> : undefined}
const doubleClickMobile =
localStorage.getItem("double-click-folders") || false;
{moverID.length === 0 ? undefined : <MoverMenu />}
if (
(currentDate - this.props.lastSelected < 1500 && selectedID === id) ||
(mobile && !doubleClickMobile) ||
bypass
) {
this.props.navigate(`/folder/${id}`);
} else {
const isGoogleDrive = folder.drive;
<div className="flex flex-row h-screen w-screen pt-16">
<LeftSection goHome={() => {}} />
this.props.dispatch(
startSetSelectedItem(id, false, false, isGoogleDrive)
);
}
};
<DataForm />
fileClick = (fileID, file, fromQuickItems = false, bypass = false) => {
const currentDate = Date.now();
let selectedFileID = fileID;
if (fromQuickItems) {
selectedFileID = "quick-" + fileID;
}
const isMobile = mobileCheck();
console.log("file", file);
if (
(currentDate - this.props.lastSelected < 1500 &&
selectedFileID === this.props.selected) ||
bypass
) {
this.props.dispatch(setPopupFile({ showPopup: true, ...file }));
} else {
const isGoogleDrive = file.metadata.drive;
this.props.dispatch(
startSetSelectedItem(fileID, true, fromQuickItems, isGoogleDrive)
);
}
};
scrollEvent = (e) => {
//if (!mobileCheck()) return;
return;
const scrollY = window.pageYOffset;
const windowY = document.documentElement.scrollHeight;
let limit = window.localStorage.getItem("list-size") || 50;
limit = parseInt(limit);
if (this.props.loading) return;
if (windowY / 2 < scrollY && this.props.allowLoadMoreItems) {
console.log("load more main");
if (this.props.files.length >= limit) {
const parent = this.props.parent;
const search = this.props.filter.search;
const sortBy = this.props.filter.sortBy;
const lastFileDate =
this.props.files[this.props.files.length - 1].uploadDate;
const lastFileName =
this.props.files[this.props.files.length - 1].filename;
this.props.dispatch(setLoading(true));
this.props.dispatch(
startLoadMoreFiles(parent, sortBy, search, lastFileDate, lastFileName)
);
}
}
};
componentDidMount = () => {
window.addEventListener("scroll", this.scrollEvent);
window.addEventListener("resize", this.resizeEvent);
this.getSettings();
};
componentDidUpdate = () => {
// console.log("update ID main", getUpdateSettingsID());
// if (this.lastSettingsUpdateID !== getUpdateSettingsID()) {
// console.log("Settings Update!");
// this.getSettings();
// }
// this.lastSettingsUpdateID = getUpdateSettingsID();
// console.log("update settings id", updateSettingsID);
// console.log("Main Section Updated", this.props.resetSettingsMain);
// if (this.lastSettingsUpdateID !== this.props.resetSettingsMain) {
// console.log("Settings Update!");
// this.getSettings();
// }
// this.lastSettingsUpdateID = this.props.resetSettingsMain;
};
getSettings = () => {
this.doubleClickFoldersMobile =
localStorage.getItem("double-click-folders") || false;
};
componentWillUnmount = () => {
window.removeEventListener("scroll", this.scrollEvent);
};
resizeEvent = () => {
if (this.props.leftSectionMode === "open")
this.props.dispatch(setLeftSectionMode(""));
if (this.props.rightSectionMode === "open")
this.props.dispatch(setRightSectionMode(""));
};
downloadFile = (fileID, file) => {
const isGoogle = file.metadata.drive;
const isGoogleDoc = file.metadata.googleDoc;
const isPersonal = file.metadata.personalFile;
this.props.dispatch(setLastSelected(0));
axios
.post("/user-service/get-token")
.then((response) => {
let finalUrl = isGoogle
? !isGoogleDoc
? `/file-service-google/download/${fileID}`
: `/file-service-google-doc/download/${fileID}`
: !isPersonal
? `/file-service/download/${fileID}`
: `/file-service-personal/download/${fileID}`;
finalUrl = `http://localhost:3000${finalUrl}`;
console.log("download file", finalUrl);
const link = document.createElement("a");
document.body.appendChild(link);
link.href = finalUrl;
link.setAttribute("type", "hidden");
link.setAttribute("download", true);
link.click();
})
.catch((e) => {
console.log("Download file get refresh token error", e);
});
// axios.get(currentURL +'/file-service/download/get-token')
// .then((response) => {
// const tempToken = response.data.tempToken;
// const finalUrl =
// isGoogle ? !isGoogleDoc ? currentURL + `/file-service-google/download/${fileID}` : currentURL + `/file-service-google-doc/download/${fileID}`
// : !isPersonal ? currentURL + `/file-service/download/${fileID}` : currentURL + `/file-service-personal/download/${fileID}`
// const link = document.createElement('a');
// document.body.appendChild(link);
// link.href = finalUrl;
// link.setAttribute('type', 'hidden');
// link.setAttribute("download", true);
// link.click();
// }).catch((err) => {
// console.log(err)
// })
};
loadMoreItems = () => {
return;
console.log("load more main");
if (mobileCheck()) return;
let limit = window.localStorage.getItem("list-size") || 50;
limit = parseInt(limit);
if (this.props.loading) {
return;
}
if (this.props.files.length >= limit) {
const parent = this.props.parent;
const search = this.props.filter.search;
const sortBy = this.props.filter.sortBy;
const lastFileDate =
this.props.files[this.props.files.length - 1].uploadDate;
const lastFileName =
this.props.files[this.props.files.length - 1].filename;
const lastPageToken =
this.props.files[this.props.files.length - 1].pageToken;
const isGoogle = this.props.filter.isGoogle;
this.props.dispatch(
startLoadMoreFiles(
parent,
sortBy,
search,
lastFileDate,
lastFileName,
lastPageToken,
isGoogle
)
);
}
};
switchLeftSectionMode = () => {
const leftSectionMode = this.props.leftSectionMode;
if (leftSectionMode === "" || leftSectionMode === "close") {
this.props.dispatch(setLeftSectionMode("open"));
} else {
this.props.dispatch(setLeftSectionMode("close"));
}
};
switchRightSectionMode = () => {
const rightSectionMode = this.props.rightSectionMode;
if (rightSectionMode === "" || rightSectionMode === "close") {
this.props.dispatch(setRightSectionMode("open"));
} else {
this.props.dispatch(setRightSectionMode("close"));
}
};
render() {
return (
<MainSection
folderClick={this.folderClick}
fileClick={this.fileClick}
downloadFile={this.downloadFile}
loadMoreItems={this.loadMoreItems}
switchLeftSectionMode={this.switchLeftSectionMode}
switchRightSectionMode={this.switchRightSectionMode}
{...this.props}
/>
);
}
}
const connectPropToState = (state) => ({
filter: state.filter,
files: state.files,
folders: state.folders,
allowLoadMoreItems: state.main.loadMoreItems,
loading: state.main.loading,
showPopup: state.popupFile.showPopup,
quickFiles: state.quickFiles,
selected: state.selectedItem.selected,
lastSelected: state.selectedItem.lastSelected,
parent: state.parent.parent,
parentNameList: state.parent.parentNameList,
moverID: state.mover.id,
routeType: state.main.currentRouteType,
cachedSearch: state.main.cachedSearch,
leftSectionMode: state.main.leftSectionMode,
rightSectionMode: state.main.rightSectionMode,
// resetSettingsMain: state.main.resetSettingsMain
<RightSection />
</div>
</div>
</div>
);
});
export default connect(connectPropToState)(withNavigate(MainSectionContainer));
export default MainSection;
+52 -14
View File
@@ -1,17 +1,55 @@
import React from "react";
import React, { memo, useMemo } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useUtils } from "../../hooks/utils";
import { useFolder } from "../../hooks/folders";
import Spinner from "../Spinner";
const ParentBar = (props) => (
<div className="path__files">
<a onClick={props.homeClick}>myDrive</a>
<span className="spacer__path">
<img src="/assets/spacer.svg" alt="spacer" />
</span>
<p onClick={props.onFolderClick} className="current__folder">
{props.parentNameList.length !== 0
? props.parentNameList[props.parentNameList.length - 1]
: "No Name"}
</p>
</div>
);
const ParentBar = memo(() => {
const { data: folder, isLoading } = useFolder();
console.log("folder", folder);
const navigate = useNavigate();
const { isHome } = useUtils();
if (isHome || !folder) {
return <div></div>;
}
const goHome = () => {
navigate("/home");
};
const goToFolder = () => {
navigate(`/folder/${folder?._id}`);
};
// TODO: Decide how to handle loading
// if (!isLoading) {
// return <div className="flex">
// </div>
// }
return (
<div className="w-full items-center hidden sm:flex">
<div className="flex items-center">
<a
className="text-[#637381] text-[18px] leading-[21px] font-medium m-0 no-underline animate cursor-pointer"
onClick={goHome}
>
myDrive
</a>
<span className="inline-flex m-[0px_10px]">
<img src="/assets/spacer.svg" alt="spacer" />
</span>
<p
onClick={goToFolder}
className="text-[#212b36] text-[18px] leading-[21px] font-medium m-0 whitespace-nowrap max-w-[300px] overflow-hidden text-ellipsis cursor-pointer"
>
{folder.name}
</p>
</div>
</div>
);
});
export default ParentBar;
+11 -8
View File
@@ -1,20 +1,20 @@
import { useSelector } from "react-redux";
import QuickAccessItem from "../QuickAccessItem";
import React, { useState } from "react";
import React, { memo, useMemo, useState } from "react";
import { useQuickFiles } from "../../hooks/files";
import classNames from "classnames";
import { useParams } from "react-router-dom";
import { useUtils } from "../../hooks/utils";
const QuickAccess = (props) => {
const QuickAccess = memo(() => {
const { data: quickfilesList } = useQuickFiles();
const currentRouteType = useSelector((state) => state.main.currentRouteType);
const [quickAccessExpanded, setQuickAccessExpanded] = useState(false);
const { isHome } = useUtils();
return (
<div
className="overflow-hidden"
style={
currentRouteType === "home" ? { display: "block" } : { display: "none" }
}
style={isHome ? { display: "block" } : { display: "none" }}
>
<div className="flex flex-row items-center justify-between mb-4">
<h2 className=" text-[#212b36] text-[22px] font-medium">
@@ -39,7 +39,10 @@ const QuickAccess = (props) => {
<div
className={classNames(
"grid animate-movement grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px] justify-center xs:justify-normal",
"grid animate-movement grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
quickfilesList?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal",
{
"max-h-36 sm:max-h-40": !quickAccessExpanded,
"max-h-[720px] sm:max-h-[665px] quickAccessOne:max-h-[1000px] quickAccessTwo:max-h-[660px] quickAccessThree:max-h-[490px]":
@@ -53,6 +56,6 @@ const QuickAccess = (props) => {
</div>
</div>
);
};
});
export default QuickAccess;
@@ -1,136 +0,0 @@
import bytes from "bytes";
import moment from "moment";
import React from "react";
import ContextMenu from "../ContextMenu";
import classNames from "classnames";
class RightSection extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div
onClick={this.props.closeContext}
ref={this.props.rightSectionRef}
style={
this.props.rightSectionMode === ""
? {}
: this.props.rightSectionMode === "open"
? { right: "0px" }
: { right: "-260px" }
}
className={classNames(
"!hidden mobileMode:!flex",
this.props.selectedItem.name === ""
? "file__details empty__details"
: "file__details"
)}
>
{this.props.selectedItem.name === "" ? (
<div className="file__details--inner">
<span>
<img src="/assets/filedetailsicon.svg" alt="filedetailsicon" />
</span>
<p>Select a file or folder to view its details</p>
</div>
) : (
<div className="file__info--wrap">
<img
className={
this.props.selected === ""
? "section__title-image section__title-image--gone"
: "section__title-image"
}
src="/images/close_icon.png"
onClick={this.props.resetSelected}
/>
<div className="file__type">
<img src="/assets/typedetailed1.svg" alt="typedetailed1" />
</div>
<div className="file__name">
<p>{this.props.selectedItem.name}</p>
</div>
<div className="file__information">
<div className="elem__file--info">
<span>Type</span>
<span>
{this.props.selectedItem.size
? this.props.getFileExtension(this.props.selectedItem.name)
: "Folder"}
</span>
</div>
<div
className="elem__file--info"
style={
!this.props.selectedItem.size
? { display: "none" }
: { display: "flex" }
}
>
<span>Size</span>
<span>{bytes(this.props.selectedItem.size)}</span>
</div>
<div className="elem__file--info">
<span>Created</span>
<span>{moment(this.props.selectedItem.date).format("L")}</span>
</div>
<div className="elem__file--info">
<span>Location</span>
<span>
{this.props.selectedItem.drive
? "Google Drive"
: this.props.selectedItem.personalFile
? "Amazon S3"
: "myDrive"}
</span>
</div>
<div
className="elem__file--info"
style={
!this.props.selectedItem.size
? { display: "none" }
: { display: "flex" }
}
>
<span>Privacy</span>
<span>
{this.props.selectedItem.link ? "Public" : "Only you"}
</span>
</div>
</div>
<div className="file__control">
<a onClick={this.props.openItem}>
{this.props.selectedItem.file ? "Open File" : "Open Folder"}
</a>
<div className="file__settings">
<a onClick={this.props.selectContext}>
<i className="fas fa-ellipsis-h" aria-hidden="true"></i>
</a>
</div>
</div>
<div
className="context__menu--wrapper"
onClick={this.props.clickTest}
>
<ContextMenu
gridMode={true}
folderMode={!this.props.selectedItem.file}
contextSelected={this.props.state.contextSelected}
closeContext={this.props.closeContext}
downloadFile={this.props.downloadFile}
file={this.props.selectedItem.data}
changeEditNameMode={this.props.changeEditNameMode}
startMovingFile={this.props.startMoveFolder}
changeDeleteMode={this.props.changeDeleteMode}
/>
</div>
</div>
)}
</div>
);
}
}
export default RightSection;
+184 -379
View File
@@ -1,394 +1,199 @@
import RightSection from "./RightSection";
import RightSectionDetail from "../RightSectionDetail";
import {
editFileMetadata,
startRemoveFile,
startRenameFile,
} from "../../actions/files";
import bytes from "bytes";
import moment from "moment";
import React, { memo, useMemo } from "react";
import ContextMenu from "../ContextMenu";
import classNames from "classnames";
import { useDispatch, useSelector } from "react-redux";
import { resetSelectedItem } from "../../actions/selectedItem";
import env from "../../enviroment/envFrontEnd";
import axios from "../../axiosInterceptor";
import { connect } from "react-redux";
import React from "react";
import { setRightSectionMode } from "../../actions/main";
import Swal from "sweetalert2";
import { startRemoveFolder, startRenameFolder } from "../../actions/folders";
import { setMoverID } from "../../actions/mover";
import mobilecheck from "../../utils/mobileCheck";
import { setMobileContextMenu } from "../../actions/mobileContextMenu";
import { getFileExtension } from "../../utils/files";
import { useContextMenu } from "../../hooks/contextMenu";
import { setPopupFile } from "../../actions/popupFile";
import { useNavigate } from "react-router-dom";
class RightSectionContainer extends React.Component {
constructor(props) {
super(props);
const RightSection = memo(() => {
const selectedItem = useSelector((state) => state.selectedItem);
const navigate = useNavigate();
const dispatch = useDispatch();
this.state = {
optimizing: false,
optimizing_finished: false,
optimizing_removed: false,
contextSelected: false,
};
const formattedName = useMemo(() => {
if (!selectedItem) return "";
const name = selectedItem.name;
const maxLength = 66;
const ellipsis = "...";
if (name.length <= maxLength) {
return name;
}
this.prevID = "";
const startLength = Math.ceil((maxLength - ellipsis.length) / 2);
const endLength = Math.floor((maxLength - ellipsis.length) / 2);
this.rightSectionRef = React.createRef();
}
const start = name.slice(0, startLength);
const end = name.slice(-endLength);
getFileExtension = (filename) => {
const filenameSplit = filename.split(".");
return `${start}${ellipsis}${end}`;
}, [selectedItem?.name, selectedItem?.file]);
if (filenameSplit.length > 1) {
const extension = filenameSplit[filenameSplit.length - 1];
const formattedDate = useMemo(
() => moment(selectedItem.date).format("L"),
[selectedItem?.date, moment]
);
return extension.toUpperCase();
const fileSize = useMemo(() => {
if (!selectedItem || !selectedItem.size) return 0;
return bytes(selectedItem.size);
}, [selectedItem?.size, bytes]);
const fileExtension = useMemo(() => {
if (!selectedItem?.file) return null;
return getFileExtension(selectedItem.name);
}, [selectedItem?.file, selectedItem?.name, getFileExtension]);
const {
onContextMenu,
closeContextMenu,
onTouchStart,
onTouchMove,
onTouchEnd,
clickStopPropagation,
...contextMenuState
} = useContextMenu();
const resetSelected = () => {
dispatch(resetSelectedItem());
};
const openItem = (e) => {
if (selectedItem.file) {
dispatch(setPopupFile({ showPopup: true, ...selectedItem.data }));
} else {
return "Unknown";
navigate(`/folder/${selectedItem.data._id}`);
}
};
getSidebarClassName = (value) => {
if (value === "gone") {
return "section section--right section--no-animation";
} else if (value) {
return "section section--right";
} else {
return "section section--right section--minimized";
}
};
removeTranscodeVideo = (props, e) => {
const data = { id: props.selectedItem.id };
axios
.delete("/file-service/transcode-video/remove", {
data,
})
.then(() => {
this.props.dispatch(
editFileMetadata(props.selectedItem.id, { transcoded: undefined })
);
this.setState(() => ({
...this.state,
optimizing: false,
optimizing_finished: false,
optimizing_removed: true,
}));
})
.catch((err) => {
console.log(err);
});
};
transcodeVideo = (props, e) => {
const config = {
file: { _id: props.selectedItem.id },
};
const data = { file: { _id: props.selectedItem.id } };
this.setState(() => ({
...this.state,
optimizing: true,
}));
axios
.post("/file-service/transcode-video", data, config)
.then((response) => {
const data = response.data;
if (data === "Finished") {
this.props.dispatch(
editFileMetadata(props.selectedItem.id, {
isVideo: true,
transcoded: true,
})
);
this.setState(() => ({
...this.state,
optimizing: false,
optimizing_finished: true,
optimizing_removed: false,
}));
}
})
.catch((err) => {
console.log(err);
});
};
getTranscodeButton = (props) => {
if (!props.selectedItem.isVideo || !env.enableVideoTranscoding) {
return undefined;
}
if (this.state.optimizing && !this.state.optimizing_finished) {
return (
<div>
<button disabled className="button--small button--small--disabled">
Optimizing
</button>
return (
<div
className={classNames(
"!hidden mobileMode:!flex min-w-[260px] max-w-[260px] border-l border-[#e8eef2] p-[25px] bg-white right-0 justify-center relative",
selectedItem.name === "" ? "flex justify-center items-center" : ""
)}
>
{selectedItem.name === "" ? (
<div className="flex flex-col justify-center items-center text-center">
<span>
<img src="/assets/filedetailsicon.svg" alt="filedetailsicon" />
</span>
<p className="text-[#637381] text-[16px] leading-[24px] font-normal m-0 mt-[30px]">
Select a file or folder to view its details
</p>
</div>
);
} else if (
(props.selectedItem.transcoded || this.state.optimizing_finished) &&
!this.state.optimizing_removed
) {
return (
<div>
<button
onClick={(e) => this.removeTranscodeVideo(props, e)}
className="button--small"
>
Unoptimize Video
</button>
) : (
<div className="w-[210px]">
<div className="flex flex-row">
<div>
<img
className="flex w-auto max-w-full"
src="/assets/typedetailed1.svg"
alt="typedetailed1"
/>
</div>
<img
className="w-[30px] h-[30px] ml-8 cursor-pointer absolute right-3"
src="/images/close_icon.png"
onClick={resetSelected}
/>
</div>
<div className="m-[20px_0]">
<p className="m-0 text-[#212b36] text-[16px] font-bold max-h-[90px] overflow-hidden text-ellipsis block break-all">
{formattedName}
</p>
</div>
<div>
<div className="flex mb-[7px] justify-start">
<span className="text-[#637381] text-[13px] font-normal mr-[35px] leading-[20px] min-w-[50px]">
Type
</span>
<span className="text-[#212b36] text-[13px] font-normal leading-[20px]">
{selectedItem.size ? fileExtension : "Folder"}
</span>
</div>
<div
className="flex mb-[7px] justify-start"
style={
!selectedItem.size ? { display: "none" } : { display: "flex" }
}
>
<span className="text-[#637381] text-[13px] font-normal mr-[35px] leading-[20px] min-w-[50px]">
Size
</span>
<span className="text-[#212b36] text-[13px] font-normal leading-[20px]">
{fileSize}
</span>
</div>
<div className="flex mb-[7px] justify-start">
<span className="text-[#637381] text-[13px] font-normal mr-[35px] leading-[20px] min-w-[50px]">
Created
</span>
<span className="text-[#212b36] text-[13px] font-normal leading-[20px]">
{formattedDate}
</span>
</div>
<div className="flex mb-[7px] justify-start">
<span className="text-[#637381] text-[13px] font-normal mr-[35px] leading-[20px] min-w-[50px]">
Location
</span>
<span className="text-[#212b36] text-[13px] font-normal leading-[20px]">
{selectedItem.drive
? "Google Drive"
: selectedItem.personalFile
? "Amazon S3"
: "myDrive"}
</span>
</div>
<div
className="flex mb-[7px] justify-start"
style={
!selectedItem.size ? { display: "none" } : { display: "flex" }
}
>
<span className="text-[#637381] text-[13px] font-normal mr-[35px] leading-[20px] min-w-[50px]">
Privacy
</span>
<span className="text-[#212b36] text-[13px] font-normal leading-[20px]">
{selectedItem.link ? "Public" : "Only you"}
</span>
</div>
</div>
<div className="mt-[15px] flex items-center">
<a
className="w-[80px] h-[40px] inline-flex items-center justify-center border border-[#3c85ee] rounded-[4px] text-[#3c85ee] text-[15px] font-medium no-underline animate"
onClick={openItem}
>
Open
</a>
<div className="ml-[15px] px-[20px]">
<a
className="w-[40px] h-[40px] rounded-[4px] inline-flex items-center justify-center border border-[#919eab] text-[#919eab] no-underline animate"
onClick={onContextMenu}
>
<i className="fas fa-ellipsis-h" aria-hidden="true"></i>
</a>
</div>
</div>
{contextMenuState.selected && (
<div onClick={clickStopPropagation}>
<ContextMenu
gridMode={true}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
folderMode={!selectedItem.file}
file={selectedItem.data}
folder={selectedItem.data}
/>
</div>
)}
</div>
);
} else {
return (
<div>
<button
onClick={(e) => this.transcodeVideo(props, e)}
className="button--small"
>
Optimize Video
</button>
</div>
);
}
};
getPublicStatus = () => {
if (this.props.selectedItem.linkType === "one") {
return (
<RightSectionDetail first={false} title="One Time Link" body="True" />
);
} else {
return <RightSectionDetail first={false} title="Public" body="True" />;
}
};
resetState = () => {
if (this.prevID !== "" && this.prevID !== this.props.selectedItem.id) {
this.setState(() => ({
...this.state,
optimizing: false,
optimizing_finished: false,
}));
}
};
resetSelected = () => {
this.props.dispatch(resetSelectedItem());
};
handleClickOutside = (e) => {
if (
this.rightSectionRef &&
!this.rightSectionRef.current.contains(event.target)
) {
if (this.props.rightSectionMode === "open") {
this.props.dispatch(setRightSectionMode("close"));
this.closeContext();
}
}
};
componentDidMount = () => {
document.addEventListener("mousedown", this.handleClickOutside);
};
componentWillUnmount = () => {
document.removeEventListener("mousedown", this.handleClickOutside);
};
openItem = (e) => {
if (this.props.selectedItem.file) {
this.props.fileClick(
this.props.selectedItem.id,
this.props.selectedItem.data,
false,
true
);
} else {
this.props.folderClick(
this.props.selectedItem.id,
this.props.selectedItem.data,
true
);
}
};
closeContext = () => {
this.setState(() => {
return {
...this.state,
contextSelected: false,
};
});
};
selectContext = (e) => {
if (e) e.stopPropagation();
if (e) e.preventDefault();
// if (mobilecheck()) {
// this.props.dispatch(setMobileContextMenu(this.props.selectedItem.file, this.props.selectedItem.data));
// return;
// }
console.log("right props", this.props.selectedItem);
this.setState(() => {
return {
...this.state,
contextSelected: !this.state.contextSelected,
};
});
};
clickStopPropagation = (e) => {
if (e) e.stopPropagation();
};
clickTest = (e) => {
console.log("click test");
};
changeEditNameMode = async () => {
let inputValue = this.props.selectedItem.name;
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.selectedItem.drive
const parent = this.props.selectedItem.file
? this.props.selectedItem.data.metadata.parent
: this.props.selectedItem.data.parent;
this.props.selectedItem.file
? this.props.dispatch(
startRenameFile(
this.props.selectedItem.id,
folderName,
this.props.selectedItem.drive
)
)
: this.props.dispatch(
startRenameFolder(
this.props.selectedItem.id,
folderName,
this.props.selectedItem.drive,
parent
)
);
//this.props.dispatch(startRenameFolder(this.props.selectedItem.data._id, folderName, this.props.selectedItem.data.));
};
startMoveFolder = async () => {
const parent = this.props.selectedItem.file
? this.props.selectedItem.data.metadata.parent
: this.props.selectedItem.data.parent;
const isPersonal = this.props.selectedItem.file
? this.props.selectedItem.data.metadata.personalFile
: this.props.selectedItem.data.personalFolder;
this.props.dispatch(
setMoverID(
this.props.selectedItem.id,
parent,
this.props.selectedItem.file,
this.props.selectedItem.drive,
isPersonal
)
);
};
changeDeleteMode = async () => {
const parent = this.props.selectedItem.file
? this.props.selectedItem.data.metadata.parent
: this.props.selectedItem.data.parent;
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.selectedItem.file
? this.props.dispatch(
startRemoveFile(
this.props.selectedItem.id,
this.props.selectedItem.drive,
this.props.selectedItem.data.metadata.personalFile
)
)
: this.props.dispatch(
startRemoveFolder(
this.props.selectedItem.id,
[
...this.props.selectedItem.data.parentList,
this.props.selectedItem.id,
],
this.props.selectedItem.drive,
parent,
this.props.selectedItem.data.metadata.personalFolder
)
);
}
});
};
render() {
return (
<RightSection
getPublicStatus={this.getPublicStatus}
getTranscodeButton={this.getTranscodeButton}
getFileExtension={this.getFileExtension}
getSidebarClassName={this.getSidebarClassName}
resetState={this.resetState}
resetSelected={this.resetSelected}
openItem={this.openItem}
rightSectionRef={this.rightSectionRef}
clickStopPropagation={this.clickStopPropagation}
closeContext={this.closeContext}
selectContext={this.selectContext}
changeEditNameMode={this.changeEditNameMode}
startMoveFolder={this.startMoveFolder}
changeDeleteMode={this.changeDeleteMode}
clickTest={this.clickTest}
state={this.state}
{...this.props}
/>
);
}
}
const connectPropToState = (state) => ({
selectedItem: state.selectedItem,
showSideBar: state.main.showSideBar,
selected: state.main.selected,
rightSectionMode: state.main.rightSectionMode,
)}
</div>
);
});
export default connect(connectPropToState)(RightSectionContainer);
export default RightSection;
+16 -2
View File
@@ -1,6 +1,6 @@
import { useQuery, useQueryClient } from "react-query";
import { useParams } from "react-router-dom";
import { getFoldersList } from "../api/foldersAPI";
import { getFolderInfo, getFoldersList } from "../api/foldersAPI";
import { useSelector } from "react-redux";
export const useFolders = () => {
@@ -40,9 +40,23 @@ export const useFoldersClient = () => {
],
});
};
return {
...foldersReactClientQuery,
invalidateFoldersCache,
};
};
export const useFolder = () => {
const params = useParams();
const folderQuery = useQuery(
[
"folder",
{
id: params.id,
},
],
getFolderInfo
);
return { ...folderQuery };
};
+12
View File
@@ -0,0 +1,12 @@
import { useMemo } from "react";
import { useParams } from "react-router-dom";
export const useUtils = () => {
const params = useParams();
const isHome = useMemo(() => {
return !params.id;
}, [params.id]);
return { isHome };
};