-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sk.cl.upload site image #295
Conversation
- Add basic text - Add component definition - Add Modal and upload object Todo: Make it all look nicer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work guys!! A couple comments/questions about style and features:
src/components/treePage/treeInfo.tsx
Outdated
{userOwnsTree && treePresent && ( | ||
<TreePageUploadSiteImageButton siteData={siteData} /> | ||
)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ I think we decided to allow anybody to upload images for a site, so we don't need to check if userOwnsTree
here (sorry if the API doc said otherwise, I really need to clean that up 😞)
src/components/treePage/treeInfo.tsx
Outdated
interface TreeUploadProps { | ||
readonly siteData: SiteProps; | ||
} | ||
|
||
const TreePageUploadSiteImageButton: React.FC<TreeUploadProps> = ({ | ||
siteData, | ||
}) => { | ||
return <UploadSiteImageButton siteEntryId={siteData.entries[0].id} />; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Just curious, how come we have this extra component rather than directly using UploadSiteImageButton
? Was there some weird bug that didn't show the button without this?
|
||
const props: UploadProps = { | ||
name: 'file', | ||
multiple: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Do we want to allow users to upload multiple images at a time? It'd be nice quality of life feature for users, but it'd take a bit more work to upload each image and handle individual errors. If not, I think we should add the maxCount
prop as 1 (more info in the component doc) so it's clear to users that they can only upload one image at time.
<Modal | ||
title={t('uploadSiteImage.upload_title')} // pass on as input | ||
visible={showMenu} | ||
footer={null} | ||
onCancel={() => setShowMenu(false)} | ||
closeIcon={<StyledClose />} | ||
> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 Can we add a way for users to choose to upload their images anonymously? This would make it so when we view their images, it'll hide their username (as opposed to displaying it publicly). Something like a switch or a similar input would work well - make sure to update the API route to use this value as well!
return ( | ||
<> | ||
<GreenButton | ||
type="text" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ Just a quick style nitpick - can we change this button's type to primary
? This will keep the upload button's appearance consistent with the adopt button when we hover over it (white text on light green, vs. black text on white like it is now)
@@ -2186,4 +2186,61 @@ describe('Admin Protected Client Routes', () => { | |||
expect(result).toEqual(response); | |||
}); | |||
}); | |||
|
|||
describe('uploadImage', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks awesome! Just a couple comments:
|
||
const props: UploadProps = { | ||
name: 'file', | ||
multiple: false, | ||
multiple: true, | ||
beforeUpload: async (file) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Just curious, did making these functions async
make a difference on your end? When I got rid of the async/await, it didn't seem to make much of a difference, and looking at the upload props, it doesn't look like they need to be async functions - we should probably avoid async stuff if we can since it adds more complexity.
message.success('Sent!'); | ||
setShowMenu(!showMenu); | ||
if (imageToUpload.length > 0) { | ||
imageToUpload.forEach((image) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ Can we use Promise.allSettled
(mdn reference) to handle all of these requests? This way, we can wait until all of them finish and handle all the results together with something like this:
const requests: Promise<void>[] = [];
imageToUpload.forEach((image) => {
if (image) {
requests.push(
protectedApiClient.uploadImage(siteEntryId, image, anonymousUpload),
);
}
});
Promise.allSettled(requests)
.then((results) => {
// results contains a list of resolved promises
})
.finally(() => dispatch(getSiteData(id)));
@@ -102,6 +118,13 @@ const UploadSiteImageButton: React.FC<UploadImageProps> = ({ siteEntryId }) => { | |||
<ConfirmUpload onClick={onClickUploadSiteImage}> | |||
{t('uploadSiteImage.upload_button_message')} | |||
</ConfirmUpload> | |||
<Checkbox | |||
onChange={async (e: CheckboxChangeEvent) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Similar to the beforeChange
async function above - this seemed to work without being async, did it make a difference for you?
TODO: Fix remove image
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! I wasn't able to figure out a way to get selecting multiple files in the file dialog to work (but we can still upload multiple files, if you select them one-by-one). I think we should log this issue for next semester and take another look with fresh eyes, but you're absolutely welcome to look into it too if you'd like!
const [anonymousUpload, setAnonymousUpload] = useState(false); | ||
const dispatch = useDispatch(); | ||
const id = Number(useParams<TreeParams>().id); | ||
|
||
const props: UploadProps = { | ||
name: 'file', | ||
multiple: true, | ||
beforeUpload: async (file) => { | ||
beforeUpload: (_, fileList) => { | ||
console.log('before upload'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ Make sure to remove any console.log()
calls before you merge! It's a tiny optimization for production, but we'd still like to get rid of them if we can (also our linter will throw a fit if it finds any console.log()
calls 🤷)
Checklist
yarn run check
yarn run test
Why
Resolves #241
This ticket allows the end users to upload their tree image to their adopted tree. Previously, there was no way of uploading tree images through the site and thus this will come in handy to users who want to upload their tree photos to share with other users.
This PR
This change adds an upload image component to the tree pages. Users are able to upload tree images that are converted to b64. The upload image component with its API client 'uploadImage' posts the uploaded image and siteEntryId to /api/v1/protected/sites/site_image/${siteEntryId}. Note that you have to adopt the tree to be able to upload a tree image.
Screenshots
Screen recording
Screen.Recording.2023-10-22.at.3.56.59.PM.mov
Verification Steps
To check if this upload component works, try uploading an image and go to AWS to see if the image shows up in folder 'sfft-user-upload' - (the content you defined in 'aws_s3_upload_dir' in server.properties from the backend). Additionally, there are three tests we could run in protectedApiClient.test to test upload image API client.