Skip to content
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

Add useNetworkSpeed hook #32

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion components/Menu/MenuDynamicBg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {useContext} from 'react';
import clsx from 'clsx';
import {m, AnimatePresence} from 'framer-motion';
import Image from 'next/image';
import useNetworkSpeed from '@/lib/shared/useNetworkSpeed';
import {MenuContext} from './MenuContext';

// eslint-disable-next-line jsdoc/require-jsdoc
Expand All @@ -12,6 +13,8 @@ const dynamicBgCn = clsx('absolute', 'top-0', 'left-0', 'w-full', 'h-full', 'z-2
*/
export default function MenuDynamicBg() {
const {menuBg} = useContext(MenuContext);
const [, isFast] = useNetworkSpeed();
const src = isFast ? `/images/${menuBg}` : `/images/low-quality/${menuBg}`;

return (
<AnimatePresence mode="wait">
Expand All @@ -29,7 +32,7 @@ export default function MenuDynamicBg() {
}}
>
<Image
src={`/images/${menuBg}`}
src={src}
alt=""
placeholder="blur"
blurDataURL={`/images/blured/${menuBg}`}
Expand Down
48 changes: 48 additions & 0 deletions lib/shared/useNetworkSpeed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {useEffect, useState} from 'react';
import {isServer} from '@/utils/isServer';

const fastNetworkTypes = ['4g'];

// eslint-disable-next-line jsdoc/require-jsdoc
function isSupported() {
if (isServer()) {
return false;
}

return navigator && navigator.connection && navigator.connection.effectiveType;
}

/**
* @returns Network speed.
*/
function getNetworkType() {
if (!isSupported()) {
return '4g';
}

return navigator.connection!.effectiveType!;
}

/**
* Hook to get network speed.
* @returns Network speed.
*/
export default function useNetworkSpeed() {
const [networkType, setNetworkType] = useState(getNetworkType());
const isNetworkFast = fastNetworkTypes.includes(networkType);

// eslint-disable-next-line jsdoc/require-jsdoc
const handleNetworkChange = () => {
setNetworkType(getNetworkType());
};

useEffect(() => {
isSupported() && navigator.connection!.addEventListener('change', handleNetworkChange);

return () => {
isSupported() && navigator.connection!.removeEventListener('change', handleNetworkChange);
};
}, [setNetworkType]);

return [networkType, isNetworkFast];
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"lint:editorconfig": "npx editorconfig-checker",
"cypress": "cypress open",
"prepare": "husky install",
"blur-img": "node ./scripts/generateBlured.js"
"gen-img": "node ./scripts/generateImgVariations.js"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.0",
Expand Down
Binary file modified public/images/blured/top-menu.0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/blured/top-menu.1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/blured/top-menu.2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/blured/top-menu.3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/low-quality/top-menu.0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/low-quality/top-menu.1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/low-quality/top-menu.2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/low-quality/top-menu.3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 35 additions & 21 deletions scripts/generateBlured.js → scripts/generateImgVariations.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,21 @@ const colors = require('colors/safe');

const imagesDirName = 'public/images';
const bluredDirName = 'blured';
const lowQualityDirName = 'low-quality';
const pathImagesDir = `${process.cwd()}/${imagesDirName}`;
const pathBluredDir = `${pathImagesDir}/${bluredDirName}`;
const pathLowQualityDir = `${pathImagesDir}/${lowQualityDirName}`;

// Clear current blured images
!fs.existsSync(pathBluredDir) && fs.mkdirSync(pathBluredDir);
process.chdir(pathImagesDir);

const contents = getDirectoryContentFileNames(pathBluredDir);
for (const c of contents) {
fs.unlink(path.join(pathBluredDir, c), (err) => {
if (err) throw err;
});
}
// eslint-disable-next-line no-console
console.log(colors.green(`Cleaned up ${bluredDirName} directory`));
// Clear current variations
cleanupDir(pathBluredDir);
cleanupDir(pathLowQualityDir);

// Process gallery images and save into blured directory
// Create new variations
const images = getDirectoryContentFileNames(pathImagesDir);
// eslint-disable-next-line no-console
console.log(colors.gray('\nStarting process images...\n'));

process.chdir(pathImagesDir);
for (const i of images) {
processImage(i);
}
Expand All @@ -34,25 +29,29 @@ for (const i of images) {
function getDirectoryContentFileNames(dir) {
let fileNamesList = [];

fs.readdirSync(dir).forEach((file) => {
const fullPath = path.join(dir, file);
fs.readdirSync(dir)
.filter(x => !x.startsWith('.')) // ignore hidden files
.forEach((file) => {
const fullPath = path.join(dir, file);

if (!fs.lstatSync(fullPath).isDirectory()) {
fileNamesList.push(file);
}
});
if (!fs.lstatSync(fullPath).isDirectory()) {
fileNamesList.push(file);
}
});

return fileNamesList;
}

// eslint-disable-next-line jsdoc/require-jsdoc
function processImage(fileName) {
const pathToBlured = `${bluredDirName}/${fileName}`;
const pathToLowQuality = `${lowQualityDirName}/${fileName}`;

jimp.read(fileName)
.then((result) => {
return result
.quality(40)
.quality(30)
.write(pathToLowQuality)
.blur(30)
.write(pathToBlured);
})
Expand All @@ -62,6 +61,21 @@ function processImage(fileName) {
})
.then(() => {
// eslint-disable-next-line no-console
console.log(colors.green('Created blured image: ') + pathToBlured);
console.log(colors.green('Processed image: ') + fileName);
});
}

// eslint-disable-next-line jsdoc/require-jsdoc
function cleanupDir(dir) {
!fs.existsSync(dir) && fs.mkdirSync(dir);
process.chdir(dir);

const contents = getDirectoryContentFileNames(dir);
for (const c of contents) {
fs.unlink(path.join(dir, c), (err) => {
if (err) throw err;
});
}
// eslint-disable-next-line no-console
console.log(colors.green(`Cleaned up ${dir} directory`));
}
13 changes: 13 additions & 0 deletions types/network-information-api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable jsdoc/require-jsdoc */
declare interface Navigator extends NavigatorNetworkInformation {}

type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';

interface NetworkInformation extends EventTarget {
readonly effectiveType?: EffectiveConnectionType;
onchange?: EventListener;
}

declare interface NavigatorNetworkInformation {
readonly connection?: NetworkInformation;
}