From 15ce8bb3a27a9845cedd853856cb62a01a7d7587 Mon Sep 17 00:00:00 2001 From: hoseacodes Date: Mon, 12 Feb 2024 00:03:06 -0600 Subject: [PATCH] fix(*): add utils --- src/Utils/breakpoints.js | 12 ++-- src/Utils/helperFunctions.js | 77 +++++++++++++++++++++++ src/Utils/scroll.js | 7 +-- src/Utils/templateGame.js | 27 +++++++++ src/Utils/useMousePosition.js | 19 ++++++ src/Utils/useWindowSize.js | 20 ++++++ src/serviceWorker.js | 111 +++++++++++++++++----------------- 7 files changed, 208 insertions(+), 65 deletions(-) create mode 100644 src/Utils/helperFunctions.js create mode 100644 src/Utils/templateGame.js create mode 100644 src/Utils/useMousePosition.js create mode 100644 src/Utils/useWindowSize.js diff --git a/src/Utils/breakpoints.js b/src/Utils/breakpoints.js index 98bb5f0a..e62d1fc5 100644 --- a/src/Utils/breakpoints.js +++ b/src/Utils/breakpoints.js @@ -2,16 +2,16 @@ const size = { xs: '375px', sm: '768px', lg: '1200px', - } +}; const devicemin = { xs: `(min-width: ${size.xs})`, sm: `(min-width: ${size.sm})`, - lg: `(min-width: ${size.lg})` - } + lg: `(min-width: ${size.lg})`, +}; const devicemax = { xs: `(max-width: ${size.xs})`, sm: `(max-width: ${size.sm})`, - lg: `(max-width: ${size.lg})` - } + lg: `(max-width: ${size.lg})`, +}; -export {devicemax, devicemin} +export { devicemax, devicemin }; diff --git a/src/Utils/helperFunctions.js b/src/Utils/helperFunctions.js new file mode 100644 index 00000000..e635b42d --- /dev/null +++ b/src/Utils/helperFunctions.js @@ -0,0 +1,77 @@ +function copyTextToClipboard(text) { +var textArea = document.createElement("textarea"); + +// +// *** This styling is an extra step which is likely not required. *** +// +// Why is it here? To ensure: +// 1. the element is able to have focus and selection. +// 2. if element was to flash render it has minimal visual impact. +// 3. less flakyness with selection and copying which **might** occur if +// the textarea element is not visible. +// +// The likelihood is the element won't even render, not even a flash, +// so some of these are just precautions. However in IE the element +// is visible whilst the popup box asking the user for permission for +// the web page to copy to the clipboard. +// + +// Place in top-left corner of screen regardless of scroll position. +textArea.style.position = "fixed"; +textArea.style.top = 0; +textArea.style.left = 0; + +// Ensure it has a small width and height. Setting to 1px / 1em +// doesn't work as this gives a negative w/h on some browsers. +textArea.style.width = "2em"; +textArea.style.height = "2em"; + +// We don't need padding, reducing the size if it does flash render. +textArea.style.padding = 0; + +// Clean up any borders. +textArea.style.border = "none"; +textArea.style.outline = "none"; +textArea.style.boxShadow = "none"; + +// Avoid flash of white box if rendered for any reason. +textArea.style.background = "transparent"; + +textArea.value = text; + +document.body.appendChild(textArea); + +textArea.select(); + +try { + var successful = document.execCommand("copy"); + var msg = successful ? "successful" : "unsuccessful"; + // console.log("Copying text command was " + msg); + alert("Link copied to clipboard!"); +} catch (err) { + console.log("Oops, unable to copy"); +} + +document.body.removeChild(textArea); +} + +const responsive = { + superLargeDesktop: { + breakpoint: { max: 4000, min: 3000 }, + items: 1, + }, + desktop: { + breakpoint: { max: 3000, min: 1024 }, + items: 1, + }, + tablet: { + breakpoint: { max: 1024, min: 464 }, + items: 1, + }, + mobile: { + breakpoint: { max: 464, min: 0 }, + items: 1, + } +}; + +export { copyTextToClipboard, responsive }; \ No newline at end of file diff --git a/src/Utils/scroll.js b/src/Utils/scroll.js index 376e29d7..e69c35ed 100644 --- a/src/Utils/scroll.js +++ b/src/Utils/scroll.js @@ -1,4 +1,3 @@ - - // window.addEventListener('scroll', () => { - // document.body.style.setProperty('--scroll', window.pageYOffset / (document.body.offsetHeight - window.innerHeight)); - // }, false); +// window.addEventListener('scroll', () => { +// document.body.style.setProperty('--scroll', window.pageYOffset / (document.body.offsetHeight - window.innerHeight)); +// }, false); diff --git a/src/Utils/templateGame.js b/src/Utils/templateGame.js new file mode 100644 index 00000000..ce730741 --- /dev/null +++ b/src/Utils/templateGame.js @@ -0,0 +1,27 @@ +const templateGame = { + name: 'Game not found', + surname: '404', + price: '??.??', + desc: 'The game you tried to look for has not been found within our database. You can find a full list of our featured games in the browse section on our shop. Click the Store button in the top left corner to get back to the browse section. To avoid similar issues in the future, please do not try to access game pages by typing game names into the URL. The game might be called slightly different in our database, resulting in an error when trying to fetch the page data.', + link: 'https://gianlucajahn.github.io/react-ecommerce-store/browse', + release: 'No release date found', + platforms: 'None', + genre: 'None', + developers: 'None', + publishers: 'None', + inCart: false, + selected: false, + isHovered: false, + isLiked: false, + rating: 0, + id: 33, + cover: 'https://res.cloudinary.com/gianlucajahn/image/upload/c_scale,q_100,w_500/v1658843471/questionmark_wzexkq.png', + footage: [ + 'https://res.cloudinary.com/gianlucajahn/image/upload/v1658843471/questionmark_wzexkq.png', + 'https://res.cloudinary.com/gianlucajahn/image/upload/v1658843471/questionmark_wzexkq.png', + 'https://res.cloudinary.com/gianlucajahn/image/upload/v1658843471/questionmark_wzexkq.png', + 'https://res.cloudinary.com/gianlucajahn/image/upload/v1658843471/questionmark_wzexkq.png', + ], +}; + +export default templateGame; diff --git a/src/Utils/useMousePosition.js b/src/Utils/useMousePosition.js new file mode 100644 index 00000000..77e9abda --- /dev/null +++ b/src/Utils/useMousePosition.js @@ -0,0 +1,19 @@ +import { useState, useEffect } from 'react'; + +const useMousePosition = () => { + const [mousePosition, setMousePosition] = useState({ x: null, y: null }); + + const updateMousePosition = (ev) => { + setMousePosition({ x: ev.clientX, y: ev.clientY }); + }; + + useEffect(() => { + window.addEventListener('mousemove', updateMousePosition); + + return () => window.removeEventListener('mousemove', updateMousePosition); + }, []); + + return mousePosition; +}; + +export default useMousePosition; diff --git a/src/Utils/useWindowSize.js b/src/Utils/useWindowSize.js new file mode 100644 index 00000000..12b58fab --- /dev/null +++ b/src/Utils/useWindowSize.js @@ -0,0 +1,20 @@ +import { useState, useEffect } from 'react'; + +export default function useWindowSize() { + const [windowSize, setWindowSize] = useState({ + width: undefined, + height: undefined, + }); + useEffect(() => { + function handleResize() { + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + } + window.addEventListener('resize', handleResize); + handleResize(); + return () => window.removeEventListener('resize', handleResize); + }, []); + return windowSize; +} diff --git a/src/serviceWorker.js b/src/serviceWorker.js index b04b771a..62dfa8f2 100755 --- a/src/serviceWorker.js +++ b/src/serviceWorker.js @@ -10,54 +10,10 @@ // To learn more about the benefits of this model and instructions on how to // opt-in, read https://bit.ly/CRA-PWA -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { - // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); - if (publicUrl.origin !== window.location.origin) { - // Our service worker won't work if PUBLIC_URL is on a different origin - // from what our page is served on. This might happen if a CDN is used to - // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; - } - - window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' - ); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) - .then(registration => { + .then((registration) => { registration.onupdatefound = () => { const installingWorker = registration.installing; if (installingWorker == null) { @@ -70,8 +26,8 @@ function registerValidSW(swUrl, config) { // but the previous service worker will still serve the older // content until all client tabs are closed. console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', ); // Execute callback @@ -93,25 +49,35 @@ function registerValidSW(swUrl, config) { }; }; }) - .catch(error => { + .catch((error) => { console.error('Error during service worker registration:', error); }); } +const isLocalhost = Boolean( + window.location.hostname === 'localhost' + // [::1] is the IPv6 localhost address. + || window.location.hostname === '[::1]' + // 127.0.0.0/8 are considered localhost for IPv4. + || window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, + ), +); + function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { headers: { 'Service-Worker': 'script' }, }) - .then(response => { + .then((response) => { // Ensure service worker exists, and that we really are getting a JS file. const contentType = response.headers.get('content-type'); if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) + response.status === 404 + || (contentType !== null && contentType.indexOf('javascript') === -1) ) { // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister().then(() => { window.location.reload(); }); @@ -123,18 +89,53 @@ function checkValidServiceWorker(swUrl, config) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + 'No internet connection found. App is running in offline mode.', ); }); } +export function register(config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA', + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + + export function unregister() { if ('serviceWorker' in navigator) { navigator.serviceWorker.ready - .then(registration => { + .then((registration) => { registration.unregister(); }) - .catch(error => { + .catch((error) => { console.error(error.message); }); }