Skip to content

Commit

Permalink
feat: animationUr/product video everywhere except in the cards (#360)
Browse files Browse the repository at this point in the history
feat: animationUr/product video everywhere except in the cards (#360)
  • Loading branch information
albertfolch-redeemeum authored Oct 26, 2022
1 parent 73e47b9 commit ffbd295
Show file tree
Hide file tree
Showing 34 changed files with 592 additions and 107 deletions.
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ REACT_APP_DEFAULT_RESOLUTION_PERIOD_DAYS=15

REACT_APP_CREATE_PROFILE_CONFIGURATION=LENS

REACT_APP_GOOGLE_TAG_ID="GTM-ID"
REACT_APP_GOOGLE_TAG_ID="GTM-ID"

REACT_APP_IPFS_GATEWAY=https://bosonprotocol.infura-ipfs.io/ipfs/
4 changes: 2 additions & 2 deletions src/components/detail/DetailSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Button from "../../components/ui/Button";
import Grid from "../../components/ui/Grid";
import Image from "../../components/ui/Image";
import Typography from "../../components/ui/Typography";
import { fetchIpfsImages } from "../../lib/utils/base64";
import { fetchIpfsBase64Media } from "../../lib/utils/base64";
import { useIpfsStorage } from "../../lib/utils/hooks/useIpfsStorage";
import { SLIDER_OPTIONS } from "./const";
import { GlideSlide, GlideWrapper } from "./Detail.style";
Expand Down Expand Up @@ -38,7 +38,7 @@ export default function DetailSlider({ images }: Props) {
useEffect(() => {
(async () => {
try {
const imagesFromIpfs = await fetchIpfsImages(
const imagesFromIpfs = await fetchIpfsBase64Media(
images,
ipfsMetadataStorage
);
Expand Down
9 changes: 8 additions & 1 deletion src/components/detail/DetailWidget/DetailWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,19 @@ const DetailWidget: React.FC<IDetailWidget> = ({
const BASE_MODAL_DATA = useMemo(
() => ({
data: OFFER_DETAIL_DATA_MODAL,
animationUrl: offer.metadata.animationUrl || "",
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
exchange: exchange!,
image,
name
}),
[OFFER_DETAIL_DATA_MODAL, exchange, image, name]
[
OFFER_DETAIL_DATA_MODAL,
exchange,
image,
name,
offer.metadata.animationUrl
]
);

const handleOnGetSignerAddress = useCallback(
Expand Down
4 changes: 3 additions & 1 deletion src/components/exchange/Exchange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,16 @@ export default function Exchange({ offer, exchange, reload }: Props) {
data: OFFER_DETAIL_DATA_MODAL,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
exchange: exchange!,
animationUrl: offer.metadata.animationUrl || "",
image: offer.metadata.imageUrl,
name: offer.metadata.name
}),
[
OFFER_DETAIL_DATA_MODAL,
exchange,
offer.metadata.imageUrl,
offer.metadata.name
offer.metadata.name,
offer.metadata.animationUrl
]
);

Expand Down
6 changes: 6 additions & 0 deletions src/components/form/Field.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ export const CheckboxWrapper = styled.label.attrs((props: { error: any }) => ({
`}
`;

export const VideoPreview = styled.video`
background: ${colors.lightGrey};
height: 100%;
width: 100%;
object-fit: contain;
`;
export const ImagePreview = styled.img`
background: ${colors.lightGrey};
`;
110 changes: 89 additions & 21 deletions src/components/form/Upload/Upload.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useField } from "formik";
import { Image, Trash } from "phosphor-react";
import { Image, Trash, VideoCamera } from "phosphor-react";
import { useCallback, useEffect, useRef, useState } from "react";

import { colors } from "../../../lib/styles/colors";
import { loadAndSetImage } from "../../../lib/utils/base64";
import { loadAndSetMedia } from "../../../lib/utils/base64";
import bytesToSize from "../../../lib/utils/bytesToSize";
import BosonButton from "../../ui/BosonButton";
import Loading from "../../ui/Loading";
Expand All @@ -13,7 +13,8 @@ import {
FieldFileUploadWrapper,
FieldInput,
FileUploadWrapper,
ImagePreview
ImagePreview,
VideoPreview
} from "../Field.styles";
import type { UploadProps } from "../types";
import UploadedFiles from "./UploadedFiles";
Expand All @@ -38,13 +39,22 @@ function Upload({
onLoadSinglePreviewImage,
withUpload,
saveToIpfs,
loadImage,
loadMedia,
onLoading,
...props
}: UploadProps & WithUploadToIpfsProps) {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [preview, setPreview] = useState<string | null>();
const [field, meta, helpers] = useField(name);

const handleLoading = useCallback(
(loadingValue: boolean) => {
onLoading?.(loadingValue);
setIsLoading(loadingValue);
},
[onLoading]
);

const errorMessage = meta.error && meta.touched ? meta.error : "";
const displayError =
typeof errorMessage === typeof "string" && errorMessage !== "";
Expand All @@ -58,32 +68,71 @@ function Upload({
);

const files = field.value as UploadFileType[];
const mimetypes = accept.split(",").map((acc) => acc.trim());
const isImageOnly = mimetypes.every((mimetype) =>
mimetype.startsWith("image/")
);
const isVideoOnly = mimetypes.every((mimetype) =>
mimetype.startsWith("video/")
);

useEffect(() => {
onFilesSelect?.(files);
helpers.setValue(files);

if (!multiple && accept === "image/*" && files && files?.length !== 0) {
if (withUpload) {
loadIpfsImagePreview(files[0] as FileProps);
} else {
loadAndSetImage(files[0] as File, (base64Uri) => {
setPreview(base64Uri);
onLoadSinglePreviewImage?.(base64Uri);
});
if (!multiple && files && files?.length !== 0) {
if (isImageOnly) {
if (withUpload) {
loadIpfsImagePreview(files[0] as FileProps);
} else {
loadAndSetMedia(files[0] as File, (base64Uri) => {
setPreview(base64Uri);
onLoadSinglePreviewImage?.(base64Uri);
});
}
} else if (isVideoOnly) {
if (withUpload) {
loadIpfsVideo(files[0] as FileProps);
} else {
loadAndSetMedia(files[0] as File, (base64Uri) => {
setPreview(base64Uri);
});
}
}
}
}, [files]); // eslint-disable-line

const loadIpfsVideo = async (file: FileProps) => {
const fileSrc = file && file?.src ? file?.src : false;
if (!fileSrc) {
return false;
}
handleLoading(true);
try {
const imagePreview: string = await loadMedia(fileSrc || "");
setPreview(imagePreview);
} catch (error) {
console.error(error);
} finally {
handleLoading(false);
}
};

const loadIpfsImagePreview = async (file: FileProps) => {
const fileSrc = file && file?.src ? file?.src : false;
if (!fileSrc) {
return false;
}
const imagePreview: string = await loadImage(fileSrc || "");
setPreview(imagePreview);
setIsLoading(false);
onLoadSinglePreviewImage?.(imagePreview);
try {
handleLoading(true);
const imagePreview: string = await loadMedia(fileSrc || "");
setPreview(imagePreview);
onLoadSinglePreviewImage?.(imagePreview);
} catch (error) {
console.error(error);
} finally {
handleLoading(false);
}
};

const handleChooseFile = () => {
Expand Down Expand Up @@ -134,11 +183,11 @@ function Upload({

const handleSave = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
setIsLoading(true);
handleLoading(true);
const files: FileProps[] = await saveToIpfs(e);
setFiles(files);
},
[saveToIpfs, setFiles, setIsLoading]
[saveToIpfs, setFiles, handleLoading]
);

return (
Expand Down Expand Up @@ -171,10 +220,29 @@ function Upload({
<Loading size={2} />
) : (
<>
{field.value && field.value?.length !== 0 && preview && (
<ImagePreview src={preview} />
{field.value && field.value?.length !== 0 && preview ? (
<>
{isVideoOnly ? (
<VideoPreview
src={
"data:video/mp4;base64," +
preview?.substring(
"data:application/octet-stream;base64,".length
)
}
autoPlay
muted
loop
/>
) : (
<ImagePreview src={preview} />
)}
</>
) : isVideoOnly ? (
<VideoCamera size={24} />
) : (
<Image size={24} />
)}
<Image size={24} />
{placeholder && (
<Typography tag="p" style={{ marginBottom: "0" }}>
{placeholder}
Expand Down
16 changes: 9 additions & 7 deletions src/components/form/Upload/WithUploadToIpfs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface FileProps {
}
export interface WithUploadToIpfsProps {
saveToIpfs: (e: React.ChangeEvent<HTMLInputElement>) => FileProps[];
loadImage: (src: string) => string;
loadMedia: (src: string) => string;
removeFile: (src: string) => void;
}
export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
Expand All @@ -35,7 +35,7 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
) => {
const withUpload = props?.withUpload || false;

const { saveFile, loadImage, removeFile } = useSaveImageToIpfs();
const { saveFile, loadMedia, removeFile } = useSaveImageToIpfs();

const saveToIpfs = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -47,8 +47,10 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
const filesErrors: string[] = [];

for (const file of filesArray) {
const sizeValidation = MAX_FILE_SIZE;
const formatValidation = SUPPORTED_FORMATS;
const sizeValidation = Number(props.maxSize) || MAX_FILE_SIZE;
const formatValidation = props.accept
? props.accept.split(",").map((acc) => acc.trim())
: SUPPORTED_FORMATS;

if (file?.size > sizeValidation) {
const err = `File ${
Expand Down Expand Up @@ -87,18 +89,18 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(

return ipfsArray as FileProps[];
},
[saveFile]
[props.accept, props.maxSize, saveFile]
);

const newProps = useMemo(
() => ({
maxSize: MAX_FILE_SIZE,
supportFormats: SUPPORTED_FORMATS,
saveToIpfs,
loadImage,
loadMedia,
removeFile
}),
[saveToIpfs, loadImage, removeFile]
[saveToIpfs, loadMedia, removeFile]
);

if (withUpload) {
Expand Down
1 change: 1 addition & 0 deletions src/components/form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,5 @@ export interface UploadProps extends BaseProps {
wrapperProps?: React.HTMLAttributes<HTMLDivElement>;
onLoadSinglePreviewImage?: (base64Uri: string) => void;
withUpload?: boolean;
onLoading?: (loading: boolean) => void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface Props {
}
)[];
exchange: Exchange;
animationUrl: string;
image: string;
name: string;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Price from "../../../../price";
import Grid from "../../../../ui/Grid";
import Image from "../../../../ui/Image";
import SellerID from "../../../../ui/SellerID";
import Video from "../../../../ui/Video";

interface Props {
exchange: Exchange;
Expand Down Expand Up @@ -45,6 +46,7 @@ const StyledGrid = styled(Grid)`
export default function ExchangePreview({ exchange }: Props) {
const { offer } = exchange;
const { isLteS } = useBreakpoints();
const animationUrl = exchange?.offer.metadata.animationUrl || "";

return (
<StyledGrid
Expand All @@ -53,7 +55,21 @@ export default function ExchangePreview({ exchange }: Props) {
>
<Grid flexDirection={isLteS ? "column" : "row"}>
<ImageWrapper>
<Image src={offer.metadata.imageUrl} alt="Exchange image" />
{animationUrl ? (
<Video
src={animationUrl}
videoProps={{
muted: true,
loop: true,
autoPlay: true
}}
componentWhileLoading={() => (
<Image src={offer.metadata.imageUrl} alt="Exchange image" />
)}
/>
) : (
<Image src={offer.metadata.imageUrl} alt="Exchange image" />
)}
</ImageWrapper>
<Grid
flexDirection="column"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAccount } from "wagmi";

import { CONFIG } from "../../../../../lib/config";
import { colors } from "../../../../../lib/styles/colors";
import { loadAndSetImage } from "../../../../../lib/utils/base64";
import { loadAndSetMedia } from "../../../../../lib/utils/base64";
import { Profile } from "../../../../../lib/utils/hooks/lens/graphql/generated";
import useCustomCreateLensProfileMumbai from "../../../../../lib/utils/hooks/lens/profile/useCustomCreateLensProfileMumbai";
import useCustomCreateLensProfilePolygon from "../../../../../lib/utils/hooks/lens/profile/useCustomCreateLensProfilePolygon";
Expand Down Expand Up @@ -144,12 +144,12 @@ export default function CreateBosonLensAccountSummary({
});
useEffect(() => {
if (values.logo?.length) {
loadAndSetImage(values.logo[0], setLogoImage);
loadAndSetMedia(values.logo[0], setLogoImage);
}
}, [values.logo]);
useEffect(() => {
if (values.coverPicture?.length) {
loadAndSetImage(values.coverPicture[0], setCoverPicture);
loadAndSetMedia(values.coverPicture[0], setCoverPicture);
}
}, [values.coverPicture]);

Expand Down
Loading

0 comments on commit ffbd295

Please sign in to comment.