Skip to content

Commit

Permalink
fix: fixed image size and group type text (#790)
Browse files Browse the repository at this point in the history
  • Loading branch information
mishramonalisha76 authored Oct 17, 2023
1 parent 2a05dfe commit b088d6d
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ChatViewComponentTest = () => {
return (
<div>
<h2>Chat UI Test page</h2>
{/* <CreateGroupModal onClose={()=>{console.log('in close')}} /> */}
<CreateGroupModal onClose={()=>{console.log('in close')}} />
<ChatViewComponentCard>
<ChatViewComponent onGetTokenClick={() => console.log("BOIIII RETURNNNSSSSS")} chatId='4ac5ab85c9c3d57adbdf2dba79357e56b2f9ef0256befe750d9f93af78d2ca68' limit={10} isConnected={true} />
</ChatViewComponentCard>
Expand Down
2 changes: 2 additions & 0 deletions packages/uiweb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"livekit-client": "^1.13.3",
"moment": "^2.29.4",
"react-icons": "^4.10.1",
"react-easy-crop": "^4.1.4",
"react-image-file-resizer": "^0.4.7",
"react-toastify": "^9.1.3",
"react-twitter-embed": "^4.0.4",
"uuid": "^9.0.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// React + Web3 Essentials
import React, { Fragment, useCallback, useState } from "react";

// External Packages
import Cropper from "react-easy-crop";
import styledComponents from "styled-components";
import Resizer from "react-image-file-resizer";

type CropType = {
x: number;
y: number;
}

type CroppedAreaPixels = {
height: number;
width: number;
x: number;
y: number;
}

const AutoImageClipper = (props: { imageSrc: any; onImageCropped: any; width: any; height: any; }) => {
const { imageSrc, onImageCropped, width, height } = props;
const [crop, setCrop] = useState<CropType>({ x: 0, y: 0 });
const [zoom, setZoom] = useState<number>(1);
const [croppedAreaPixels, setCroppedAreaPixels] = useState<CroppedAreaPixels|null>(null);
const [croppedImage, setCroppedImage] = useState<string>('');
const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
setCroppedAreaPixels(croppedAreaPixels);
}, []);

React.useEffect(() => {
async function showCroppedImage() {
try {
if (imageSrc) {
const croppedImage = await getCroppedImg(imageSrc, croppedAreaPixels!);
const image = await resizeFile(croppedImage);
onImageCropped(image);
} else {
return "Nothing";
}
} catch (e) {
console.error(e);
}
}
showCroppedImage();
}, [crop]);

async function getCroppedImg(imageSrc:string, pixelCrop: { height: any; width: any; x: any; y: any; }) {
const image = await createImage(imageSrc);
const canvas = document.createElement("canvas");
canvas.width = pixelCrop?.width;
canvas.height = pixelCrop?.height;
const ctx = canvas.getContext("2d");
const fileName = "none.jpg";

ctx!.drawImage(
image as CanvasImageSource,
pixelCrop.x,
pixelCrop.y,
pixelCrop.width,
pixelCrop.height,
0,
0,
pixelCrop.width,
pixelCrop.height
);

// As Base64 string
// return canvas.toDataURL('image/jpeg');

// As a blob
return new Promise((resolve, reject) => {
canvas.toBlob((file) => {
// resolve(URL.createObjectURL(file));
resolve(
new File([file!], fileName, {
type: "image/jpeg",
lastModified: Date.now()
})
);
}, "image/jpeg");
});
}

const resizeFile = (file: any) => {
return new Promise((resolve) => {
Resizer.imageFileResizer(
file,
128,
128,
"JPEG",
80,
0,
(uri) => {
resolve(uri);
setCroppedImage(uri as unknown as string);
},
"base64"
);
});
};

const createImage = (url: string) => {
return new Promise((resolve, reject) => {
const image = new Image();
image.addEventListener("load", () => resolve(image));
image.addEventListener("error", (error) => reject(error));
image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox
image.src = url;
});
};

const onZoomChange = (zoom: React.SetStateAction<number>) => {
setZoom(zoom);
};
return (
<Fragment>
<Container>
<Cropper
image={imageSrc}
crop={crop}
zoom={zoom}
aspect={1}
onCropChange={setCrop}
onCropComplete={onCropComplete}
onZoomChange={onZoomChange}
style={{
containerStyle: {
width: width ? width : "0.1px",
height: height ? height : "0.1px",
position: "relative",
borderRadius: "16px"
}
}}
/>
</Container>
</Fragment>
);
};

const Container = styledComponents.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;

export default AutoImageClipper;
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { Image } from '../../../config/styles';
import { ProfilePicture, device } from '../../../config';
import { CriteriaValidationErrorType } from '../types';
import AutoImageClipper from './AutoImageClipper';

export const CREATE_GROUP_STEP_KEYS = {
INPUT_DETAILS: 1,
Expand Down Expand Up @@ -71,11 +72,14 @@ export const CreateGroupModal: React.FC<CreateGroupModalProps> = ({
}, [activeComponent]);

const useDummyGroupInfo = false;
const [groupInputDetails, setGroupInputDetails] = useState<GroupInputDetailsType>({
groupName: useDummyGroupInfo ? 'This is duumy group name' : '',
groupDescription: useDummyGroupInfo ? 'This is dummy group description for testing' : '',
groupImage: useDummyGroupInfo ? ProfilePicture : ''
})
const [groupInputDetails, setGroupInputDetails] =
useState<GroupInputDetailsType>({
groupName: useDummyGroupInfo ? 'This is duumy group name' : '',
groupDescription: useDummyGroupInfo
? 'This is dummy group description for testing'
: '',
groupImage: useDummyGroupInfo ? ProfilePicture : '',
});

const renderComponent = () => {
switch (activeComponent) {
Expand Down Expand Up @@ -167,6 +171,8 @@ const CreateGroupDetail = ({
useState<CriteriaValidationErrorType>({});
const fileUploadInputRef = useRef<HTMLInputElement>(null);
const isMobile = useMediaQuery(device.mobileL);
const [isImageUploaded, setIsImageUploaded] = useState<boolean>(false);
const [imageSrc, setImageSrc] = useState<string | null>();

const handleChange = (e: Event) => {
if (!(e.target instanceof HTMLInputElement)) {
Expand All @@ -179,15 +185,22 @@ const CreateGroupDetail = ({
(e.target as HTMLInputElement).files &&
((e.target as HTMLInputElement).files as FileList).length
) {
setIsImageUploaded(true);
setGroupInputDetails({
groupDescription,
groupName,
groupImage: '',
});
const reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);

reader.onloadend = function () {
setGroupInputDetails({
groupDescription,
groupName,
groupImage: reader.result as string,
});
setImageSrc(reader.result as string);
// setGroupInputDetails({
// groupDescription,
// groupName,
// groupImage: reader.result as string,
// });
};
}
};
Expand Down Expand Up @@ -220,7 +233,6 @@ const CreateGroupDetail = ({
});
return;
}

}

if (handleNext) {
Expand All @@ -245,22 +257,37 @@ const CreateGroupDetail = ({
<ModalHeader title="Create Group" handleClose={onClose} />

<UploadContainer onClick={handleUpload}>
{!groupImage && (
{isImageUploaded ? (
groupImage ? (
<UpdatedImageContainer>
<Image
src={groupImage}
objectFit="contain"
alt="group image"
width="100%"
height="100%"
/>
</UpdatedImageContainer>
) : (
<AutoImageClipper
imageSrc={imageSrc}
onImageCropped={(croppedImage: string) =>
setGroupInputDetails({
groupDescription,
groupName,
groupImage: croppedImage,
})
}
width={undefined}
height={undefined}
/>
)
) : (
<ImageContainer theme={theme}>
<AiTwotoneCamera fontSize={40} color={'rgba(87, 93, 115, 1)'} />
</ImageContainer>
)}
{groupImage && (
<UpdatedImageContainer>
<Image
src={groupImage}
objectFit="contain"
alt="group image"
width="100%"
height="100%"
/>
</UpdatedImageContainer>
)}

<FileInput
type="file"
accept="image/*"
Expand Down Expand Up @@ -327,24 +354,32 @@ export const GatingRulesInformation = () => {
//use the theme
const UploadContainer = styled.div`
width: fit-content;
min-width:128px;
min-height:128px;
cursor: pointer;
align-self: center;
`;

const ImageContainer = styled.div<{ theme: IChatTheme }>`
margin-top: 10px;
width: fit-content;
cursor: pointer;
border-radius: 32px;
background: ${(props) => props.theme.backgroundColor.modalHoverBackground};
padding: 40px;
width: 128px;
cursor: pointer;
height: 128px;
max-height: 128px;
display:flex;
align-items:center;
justify-content:center;
`;
const UpdatedImageContainer = styled.div`
margin-top: 10px;
width: 112px;
width: 128px;
cursor: pointer;
height: 112px;
height: 128px;
overflow: hidden;
max-height: 128px;
border-radius: 32px;
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ import { ProfilePicture } from '../../../config';

const GROUP_TYPE_OPTIONS: Array<OptionDescription> = [
{
heading: 'Open',
subHeading: 'Anyone can join',
heading: 'Public',
subHeading: 'Anyone can view chats, even without joining',
value: 'open',
},
{
heading: 'Encrypted',
subHeading: 'Users must join group to view',
heading: 'Private',
subHeading: 'Encrypted Chats, Users must join group to view',
value: 'encrypted',
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const validateCustomEndpointData = async (
condition: Rule
): Promise<CriteriaValidationErrorType> => {
const { data, type, subcategory } = condition;
let errors: CriteriaValidationErrorType = {};
const errors: CriteriaValidationErrorType = {};

if (!(data as PushData).url) {
return { url: 'URL is missing' };
Expand Down Expand Up @@ -77,7 +77,7 @@ const validateGUILDData = async (
condition: Rule
): Promise<CriteriaValidationErrorType> => {
const { data } = condition;
let errors: CriteriaValidationErrorType = {};
const errors: CriteriaValidationErrorType = {};

// Check for guild ID presence
if (!(data as GuildData).id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InfuraAPIKey } from "packages/uiweb/src/lib/config";
import { InfuraAPIKey } from "../../../../config";

const getInfuraUrlFor = (network: string, key: string) =>
`https://${network}.infura.io/v3/${key}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const OptionDescripton = ({ heading, subHeading,value }: OptionDescription) => {
color={theme.textColor?.modalSubHeadingText}
fontWeight="400"
fontSize="12px"
width='132px'
lineHeight='130%'
>
{subHeading}
</Span>
Expand Down

0 comments on commit b088d6d

Please sign in to comment.