{"id":31947354,"url":"https://github.com/ecgan/react-image-gallery","last_synced_at":"2026-04-17T08:31:15.651Z","repository":{"id":39023237,"uuid":"247249223","full_name":"ecgan/react-image-gallery","owner":"ecgan","description":"Image gallery app built with React, custom React Hooks, and Flickr SDK.","archived":false,"fork":false,"pushed_at":"2023-01-24T03:51:04.000Z","size":11998,"stargazers_count":0,"open_issues_count":25,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T11:35:25.123Z","etag":null,"topics":["ant-design","flickr","flickr-sdk","image-gallery","react","react-hooks","react-testing-library"],"latest_commit_sha":null,"homepage":"https://ecgan.github.io/react-image-gallery/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ecgan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-14T09:40:44.000Z","updated_at":"2020-04-16T08:57:28.000Z","dependencies_parsed_at":"2023-02-13T16:30:39.955Z","dependency_job_id":null,"html_url":"https://github.com/ecgan/react-image-gallery","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/ecgan/react-image-gallery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecgan%2Freact-image-gallery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecgan%2Freact-image-gallery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecgan%2Freact-image-gallery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecgan%2Freact-image-gallery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecgan","download_url":"https://codeload.github.com/ecgan/react-image-gallery/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecgan%2Freact-image-gallery/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31921755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ant-design","flickr","flickr-sdk","image-gallery","react","react-hooks","react-testing-library"],"created_at":"2025-10-14T11:31:01.695Z","updated_at":"2026-04-17T08:31:15.631Z","avatar_url":"https://github.com/ecgan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Image Gallery\n\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\nA mobile-first image gallery Progressive Web App (PWA) built with React, React Hooks and Flickr.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshot.png\" alt=\"App main screenshot\" width=\"25%\"/\u003e\n\u003c/p\u003e\n\n## Motivation\n\nThis app was built as part of an interview assignment. The assignment document is [here](https://github.com/ecgan/react-image-gallery/blob/master/docs/Frontend%20Developer%20Exercise.pdf).\n\nA quick summary:\n\n\u003e Basic functional requirements:\n\u003e\n\u003e - Display the photos loaded from the API in a grid containing 3 images in a row\n\u003e - Search functionality\n\u003e - Filter functionality (e.g. page size, category, tags, etc.)\n\u003e - Pagination\n\u003e\n\u003e Nice to have functional requirements:\n\u003e\n\u003e - Responsiveness\n\u003e - Infinite/Continuous Scroll\n\nThis app fulfills all of the above. It took me about one weekend in December 2019 to complete most of the app.\n\n## Usage\n\n### Prerequisite\n\nThis app uses the Flickr API services. To run this app on your own, you need to sign up for Flickr and request an API key [here](https://www.flickr.com/services/apps/create/).\n\n### Running this app locally\n\n1. Checkout this code repository.\n2. Create a `.env` file in the root folder, and put in the following:\n\n    ```text\n    HTTPS=true   # true to run local server in https mode.\n    PORT=3811    # port number for the local server to listen on.\n    REACT_APP_FLICKR_API_KEY=\u003cYOUR FLICKR API KEY HERE\u003e\n    ```\n  \n    For more info on the `.env` file and the environment variables, visit the following pages on create-react-app site:\n  \n    - [Adding Custom Environment Variables](https://create-react-app.dev/docs/adding-custom-environment-variables/)\n    - [Advanced Configuration](https://create-react-app.dev/docs/advanced-configuration/).\n\n3. Run `npm install` to install the dependencies.\n4. Run `npm run start` to start the app in local server.\n\n### Deploying the app\n\n1. Make sure you have the `.env` file with `REACT_APP_FLICKR_API_KEY` specified inside.\n2. Run `npm run build`. The production app will be generated in the `build` folder.\n3. Deploy the files in the `build` folder onto the hosting of your choice, e.g [Amazon S3](https://aws.amazon.com/s3/), [Google Cloud Storage](https://cloud.google.com/storage), or [Firebase Hosting](https://firebase.google.com/products/hosting).\n\n## Features\n\nFrom user perspective, this app is pretty simple and does what it says in the requirements. Users can search for photos by keyword, filter the photos by date taken, and click on the photo thumbnail to view larger version. As users scroll through the list, more photos will be loaded.\n\nHowever, as a person who cares about user experience, there are a few things that I've put in to make it better.\n\n### Progressive Web App\n\nThis image gallery web app is built as a progressive web app, meaning:\n\n- The app is loaded and cached locally. This makes subsequent load faster and can be run offline.\n- The app can be added to the home screen of your mobile phone. Users are able to access the app quickly without having to open the web browser.\n\n### Display Recent Photos When There Is No Search/Filter\n\nWhen users first start the app, there is no search term and no filter being set. The app will load recent latest photos from Flickr API. With this, users will be seeing some photos even though they haven't entered anything yet.\n\n### Infinite Scroll\n\nWhen the app makes a request to Flickr API, it will request 30 photos at a time. This means users will see 10 rows of three images. As users scroll near to the bottom of the list, the app will make another request to get the next 30 photos, and then append it to the bottom of the list. This gives users the \"infinite scroll\" experience.\n\n### Error Handling\n\nImagine you are searching for some waterfall photos in the app. While scrolling down through the list of hundreds of photos, your network connection is down.\n\nThe app will show you an error message saying that the request failed. However, it doesn't stop you from scrolling up and viewing the previously loaded photos.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/request-failed-try-again.png\" alt=\"Request failed with error.\" width=\"25%\"/\u003e\n\u003c/p\u003e\n\nWhen your network connection is up again, you can click on the \"Try again\" button, and you will continue where you were left off. You don't need to start all over again.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/request-failed-tried-ok.png\" alt=\"Tried succcessful after request failed.\" width=\"25%\"/\u003e\n\u003c/p\u003e\n\n## Technical Implementation\n\nThe above features are nice and fancy, but the things under the hood are even better.\n\n### Custom `useFlickr` React Hook\n\nThe most important core piece of code to support the features above lies in the custom `useFlickr` React Hook that I build.\n\n```javascript\nconst query = {\n  text: '', // search term.\n  min_taken_date: 0, // taken start date in unix timestamp format.\n  max_taken_date: 0  // taken end date in unix timestamp format.\n}\n\nconst { loading, error, data, fetchMore, refetch } = useFlickr(query)\n```\n\nInside `useFlickr`, it uses `useReducer` React Hook to maintain state. It uses `useEffect` React Hook to call Flickr SDK which will fire HTTP request to Flickr API service.\n\n`loading` will be true when there is an ongoing request to Flickr API. `error` is the error object thrown by the Flickr API. `data` contains the photos returned from the current query.\n\nWhen users scroll to the bottom of the list and triggers the infinite scroll, `fetchMore` will be called. It will request the next 30 photos for the current search query and append them to the existing list of photos in `data`.\n\nWhen users hit an error and then click on the \"Try again\" button, `refetch` will be called. It will re-request the current set of 30 photos for the current search query and append them to the list upon success.\n\nWhen users change the search term or the date filter, the list of photos in `data` will be cleared and then updated with the new result.\n\n**Request cancellation** is also supported. If users change the search term or the date filter while there is an in-flight request, the in-flight request will be aborted, and a new request will be fired for the new query.\n\nThe `useFlickr` hook signature is inspired by [Apollo Graphql's `useQuery` React Hook](https://www.apollographql.com/docs/react/api/react-hooks/#usequery).\n\n### Testing\n\nTesting is done using [React Testing Library](https://testing-library.com/docs/react-testing-library/intro). Currently there is 90%+ code coverage.\n\n## Future Work\n\n- Use [Cypress](https://www.cypress.io/) for end-to-end testing.\n- Make use of React Context to provide Flickr client.\n- Upgrade to [Ant Design 4.x](https://ant.design/) version.\n\n## Issues / Questions\n\nFeel free to open a GitHub issue, or reach out to me on [Twitter](https://twitter.com/ecgan) or [LinkedIn](https://www.linkedin.com/in/ecgan).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecgan%2Freact-image-gallery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecgan%2Freact-image-gallery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecgan%2Freact-image-gallery/lists"}