[web] Search refactoring - Part x/x (#3203)
This commit is contained in:
@@ -86,9 +86,9 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
||||
|
||||
return (
|
||||
<SearchBarWrapper>
|
||||
{isMobileWidth ? (
|
||||
{isMobileWidth && !isInSearchMode ? (
|
||||
<SearchBarMobile
|
||||
show={!isInSearchMode}
|
||||
show={true}
|
||||
showSearchInput={showSearchInput}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import FileUploadOutlinedIcon from "@mui/icons-material/FileUploadOutlined";
|
||||
import { Button, ButtonProps, IconButton, styled } from "@mui/material";
|
||||
import { type UploadTypeSelectorIntent } from "components/Upload/UploadTypeSelector";
|
||||
import { t } from "i18next";
|
||||
import uploadManager from "services/upload/uploadManager";
|
||||
|
||||
interface UploadButtonProps {
|
||||
openUploader: (intent?: UploadTypeSelectorIntent) => void;
|
||||
text?: string;
|
||||
color?: ButtonProps["color"];
|
||||
disableShrink?: boolean;
|
||||
icon?: JSX.Element;
|
||||
}
|
||||
export const UploadButton: React.FC<UploadButtonProps> = ({
|
||||
openUploader,
|
||||
text,
|
||||
color,
|
||||
disableShrink,
|
||||
icon,
|
||||
}) => {
|
||||
const onClickHandler = () => openUploader();
|
||||
|
||||
return (
|
||||
<UploadButton_
|
||||
$disableShrink={disableShrink}
|
||||
style={{
|
||||
cursor: !uploadManager.shouldAllowNewUpload() && "not-allowed",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
sx={{ whiteSpace: "nowrap" }}
|
||||
onClick={onClickHandler}
|
||||
disabled={!uploadManager.shouldAllowNewUpload()}
|
||||
className="desktop-button"
|
||||
color={color ?? "secondary"}
|
||||
startIcon={icon ?? <FileUploadOutlinedIcon />}
|
||||
>
|
||||
{text ?? t("upload")}
|
||||
</Button>
|
||||
|
||||
<IconButton
|
||||
onClick={onClickHandler}
|
||||
disabled={!uploadManager.shouldAllowNewUpload()}
|
||||
className="mobile-button"
|
||||
>
|
||||
{icon ?? <FileUploadOutlinedIcon />}
|
||||
</IconButton>
|
||||
</UploadButton_>
|
||||
);
|
||||
};
|
||||
|
||||
const UploadButton_ = styled("div")<{ $disableShrink: boolean }>`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 1s ease;
|
||||
cursor: pointer;
|
||||
& .mobile-button {
|
||||
display: none;
|
||||
}
|
||||
${({ $disableShrink }) =>
|
||||
!$disableShrink &&
|
||||
`@media (max-width: 624px) {
|
||||
& .mobile-button {
|
||||
display: inline-flex;
|
||||
}
|
||||
& .desktop-button {
|
||||
display: none;
|
||||
}
|
||||
}`}
|
||||
`;
|
||||
@@ -45,6 +45,7 @@ import type { User } from "@ente/shared/user/types";
|
||||
import ArrowBack from "@mui/icons-material/ArrowBack";
|
||||
import FileUploadOutlinedIcon from "@mui/icons-material/FileUploadOutlined";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import type { ButtonProps, IconButtonProps } from "@mui/material";
|
||||
import { Box, Button, IconButton, Typography, styled } from "@mui/material";
|
||||
import AuthenticateUserModal from "components/AuthenticateUserModal";
|
||||
import Collections from "components/Collections";
|
||||
@@ -1084,9 +1085,9 @@ export default function Gallery() {
|
||||
) : (
|
||||
<NormalNavbarContents
|
||||
openSidebar={openSidebar}
|
||||
setIsInSearchMode={setIsInSearchMode}
|
||||
openUploader={openUploader}
|
||||
isInSearchMode={isInSearchMode}
|
||||
setIsInSearchMode={setIsInSearchMode}
|
||||
collections={collections}
|
||||
files={files}
|
||||
updateSearch={updateSearch}
|
||||
@@ -1276,49 +1277,48 @@ const NormalNavbarContents: React.FC<NormalNavbarContentsProps> = ({
|
||||
openSidebar,
|
||||
openUploader,
|
||||
isInSearchMode,
|
||||
setIsInSearchMode,
|
||||
collections,
|
||||
files,
|
||||
updateSearch,
|
||||
setIsInSearchMode,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{!isInSearchMode && (
|
||||
<IconButton onClick={openSidebar}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
<SearchBar
|
||||
isInSearchMode={isInSearchMode}
|
||||
setIsInSearchMode={setIsInSearchMode}
|
||||
collections={collections}
|
||||
files={files}
|
||||
updateSearch={updateSearch}
|
||||
/>
|
||||
{!isInSearchMode && <UploadButton onClick={openUploader} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
}) => (
|
||||
<>
|
||||
{!isInSearchMode && <SidebarButton onClick={openSidebar} />}
|
||||
<SearchBar
|
||||
isInSearchMode={isInSearchMode}
|
||||
setIsInSearchMode={setIsInSearchMode}
|
||||
collections={collections}
|
||||
files={files}
|
||||
updateSearch={updateSearch}
|
||||
/>
|
||||
{!isInSearchMode && <UploadButton onClick={openUploader} />}
|
||||
</>
|
||||
);
|
||||
|
||||
interface UploadButtonProps {
|
||||
onClick: () => void;
|
||||
}
|
||||
export const UploadButton: React.FC<UploadButtonProps> = ({ onClick }) => {
|
||||
const SidebarButton: React.FC<IconButtonProps> = (props) => (
|
||||
<IconButton {...props}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
const UploadButton: React.FC<ButtonProps & IconButtonProps> = (props) => {
|
||||
const disabled = !uploadManager.shouldAllowNewUpload();
|
||||
const isMobileWidth = useIsMobileWidth();
|
||||
|
||||
const icon = <FileUploadOutlinedIcon />;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{isMobileWidth ? (
|
||||
<IconButton onClick={onClick} disabled={disabled}>
|
||||
{<FileUploadOutlinedIcon />}
|
||||
<IconButton {...props} disabled={disabled}>
|
||||
{icon}
|
||||
</IconButton>
|
||||
) : (
|
||||
<Button
|
||||
onClick={onClick}
|
||||
{...props}
|
||||
disabled={disabled}
|
||||
color={"secondary"}
|
||||
startIcon={<FileUploadOutlinedIcon />}
|
||||
startIcon={icon}
|
||||
>
|
||||
{t("upload")}
|
||||
</Button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NavbarBase, SelectionBar } from "@/base/components/Navbar";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import { useIsTouchscreen } from "@/base/hooks";
|
||||
import { useIsMobileWidth, useIsTouchscreen } from "@/base/hooks";
|
||||
import log from "@/base/log";
|
||||
import downloadManager from "@/new/photos/services/download";
|
||||
import { EnteFile } from "@/new/photos/types/file";
|
||||
@@ -27,6 +27,7 @@ import CloseIcon from "@mui/icons-material/Close";
|
||||
import DownloadIcon from "@mui/icons-material/Download";
|
||||
import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
|
||||
import MoreHoriz from "@mui/icons-material/MoreHoriz";
|
||||
import type { ButtonProps, IconButtonProps } from "@mui/material";
|
||||
import { Box, Button, IconButton, Stack, Tooltip } from "@mui/material";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import bs58 from "bs58";
|
||||
@@ -41,7 +42,6 @@ import FullScreenDropZone from "components/FullScreenDropZone";
|
||||
import { LoadingOverlay } from "components/LoadingOverlay";
|
||||
import PhotoFrame from "components/PhotoFrame";
|
||||
import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
|
||||
import { UploadButton } from "components/Upload/UploadButton";
|
||||
import Uploader from "components/Upload/Uploader";
|
||||
import { UploadSelectorInputs } from "components/UploadSelectorInputs";
|
||||
import { t } from "i18next";
|
||||
@@ -62,6 +62,7 @@ import {
|
||||
syncPublicFiles,
|
||||
verifyPublicCollectionPassword,
|
||||
} from "services/publicCollectionService";
|
||||
import uploadManager from "services/upload/uploadManager";
|
||||
import { Collection } from "types/collection";
|
||||
import {
|
||||
SelectedState,
|
||||
@@ -170,9 +171,11 @@ export default function PublicCollectionGallery() {
|
||||
return updater;
|
||||
};
|
||||
|
||||
const openUploader = () => {
|
||||
setUploadTypeSelectorView(true);
|
||||
};
|
||||
const onAddPhotos = useMemo(() => {
|
||||
return publicCollection?.publicURLs?.[0]?.enableCollect
|
||||
? () => setUploadTypeSelectorView(true)
|
||||
: undefined;
|
||||
}, [publicCollection]);
|
||||
|
||||
const closeUploadTypeSelectorView = () => {
|
||||
setUploadTypeSelectorView(false);
|
||||
@@ -331,26 +334,20 @@ export default function PublicCollectionGallery() {
|
||||
}, [publicCollection, publicFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
if (publicCollection?.publicURLs?.[0]?.enableCollect) {
|
||||
setPhotoListFooter({
|
||||
item: (
|
||||
<CenteredFlex sx={{ marginTop: "56px" }}>
|
||||
<UploadButton
|
||||
disableShrink
|
||||
openUploader={openUploader}
|
||||
text={t("ADD_MORE_PHOTOS")}
|
||||
color="accent"
|
||||
icon={<AddPhotoAlternateOutlined />}
|
||||
/>
|
||||
</CenteredFlex>
|
||||
),
|
||||
itemType: ITEM_TYPE.FOOTER,
|
||||
height: 104,
|
||||
});
|
||||
} else {
|
||||
setPhotoListFooter(null);
|
||||
}
|
||||
}, [publicCollection]);
|
||||
setPhotoListFooter(
|
||||
onAddPhotos
|
||||
? {
|
||||
item: (
|
||||
<CenteredFlex sx={{ marginTop: "56px" }}>
|
||||
<AddMorePhotosButton onClick={onAddPhotos} />
|
||||
</CenteredFlex>
|
||||
),
|
||||
itemType: ITEM_TYPE.FOOTER,
|
||||
height: 104,
|
||||
}
|
||||
: null,
|
||||
);
|
||||
}, [onAddPhotos]);
|
||||
|
||||
const syncWithRemote = async () => {
|
||||
const collectionUID = getPublicCollectionUID(token.current);
|
||||
@@ -551,12 +548,7 @@ export default function PublicCollectionGallery() {
|
||||
getFolderSelectorInputProps,
|
||||
}}
|
||||
/>
|
||||
<SharedAlbumNavbar
|
||||
showUploadButton={
|
||||
publicCollection?.publicURLs?.[0]?.enableCollect
|
||||
}
|
||||
openUploader={openUploader}
|
||||
/>
|
||||
<SharedAlbumNavbar onAddPhotos={onAddPhotos} />
|
||||
<PhotoFrame
|
||||
page={PAGES.SHARED_ALBUMS}
|
||||
files={publicFiles}
|
||||
@@ -610,24 +602,28 @@ export default function PublicCollectionGallery() {
|
||||
);
|
||||
}
|
||||
|
||||
function SharedAlbumNavbar({ showUploadButton, openUploader }) {
|
||||
interface SharedAlbumNavbarProps {
|
||||
/**
|
||||
* If provided, then an "Add Photos" button will be shown in the navbar.
|
||||
*/
|
||||
onAddPhotos: React.MouseEventHandler<HTMLButtonElement> | undefined;
|
||||
}
|
||||
const SharedAlbumNavbar: React.FC<SharedAlbumNavbarProps> = ({
|
||||
onAddPhotos,
|
||||
}) => {
|
||||
return (
|
||||
<NavbarBase>
|
||||
<FluidContainer>
|
||||
<EnteLinkLogo />
|
||||
</FluidContainer>
|
||||
{showUploadButton ? (
|
||||
<UploadButton
|
||||
openUploader={openUploader}
|
||||
icon={<AddPhotoAlternateOutlined />}
|
||||
text={t("ADD_PHOTOS")}
|
||||
/>
|
||||
{onAddPhotos ? (
|
||||
<AddPhotosButton onClick={onAddPhotos} />
|
||||
) : (
|
||||
<GoToEnte />
|
||||
)}
|
||||
</NavbarBase>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const EnteLinkLogo: React.FC = () => {
|
||||
return (
|
||||
@@ -648,6 +644,52 @@ const EnteLinkLogo: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const AddPhotosButton: React.FC<ButtonProps & IconButtonProps> = (props) => {
|
||||
const disabled = !uploadManager.shouldAllowNewUpload();
|
||||
const isMobileWidth = useIsMobileWidth();
|
||||
|
||||
const icon = <AddPhotoAlternateOutlined />;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{isMobileWidth ? (
|
||||
<IconButton {...props} disabled={disabled}>
|
||||
{icon}
|
||||
</IconButton>
|
||||
) : (
|
||||
<Button
|
||||
{...props}
|
||||
disabled={disabled}
|
||||
color={"secondary"}
|
||||
startIcon={icon}
|
||||
>
|
||||
{t("ADD_PHOTOS")}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* A visually different variation of {@link AddPhotosButton}. It also does not
|
||||
* shrink on mobile sized screens.
|
||||
*/
|
||||
const AddMorePhotosButton: React.FC<ButtonProps> = (props) => {
|
||||
const disabled = !uploadManager.shouldAllowNewUpload();
|
||||
return (
|
||||
<Box>
|
||||
<Button
|
||||
{...props}
|
||||
disabled={disabled}
|
||||
color={"accent"}
|
||||
startIcon={<AddPhotoAlternateOutlined />}
|
||||
>
|
||||
{t("ADD_MORE_PHOTOS")}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const GoToEnte: React.FC = () => {
|
||||
// Touchscreen devices are overwhemingly likely to be Android or iOS.
|
||||
const isTouchscreen = useIsTouchscreen();
|
||||
|
||||
Reference in New Issue
Block a user