refactor(background): Further code readaability improvements

This commit is contained in:
alexsparkes
2024-11-26 21:56:20 +00:00
parent 89526d19b9
commit 2e2670f275
4 changed files with 457 additions and 369 deletions

View File

@@ -1,199 +1,70 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import variables from 'config/variables';
import PhotoInformation from './components/PhotoInformation';
import EventBus from 'utils/eventbus';
import { getOfflineImage } from './api/getOfflineImage';
import { supportsAVIF } from './api/avif';
import videoCheck from './api/videoCheck';
import { randomColourStyleBuilder } from './api/randomColour';
import { decodeBlurHash } from 'fast-blurhash';
import defaults from './options/default';
import Stats from 'features/stats/api/stats';
import BackgroundImage from './components/BackgroundImage';
import BackgroundVideo from './components/BackgroundVideo';
import './scss/index.scss';
import useBackgroundAPI from './api/useBackgroundAPI';
import { handleBackgroundType, applyBackground } from './api/backgroundTypeHandlers';
import {
resetElements,
handleBackgroundVisibility,
handleBackgroundEffectEvent,
} from './api/backgroundHelpers';
const initialState = {
blob: null,
style: '',
url: '',
currentAPI: '',
firstTime: false,
photoInfo: {
hidden: false,
offline: false,
photographerURL: '',
photoURL: '',
},
type: '',
video: false,
};
const Background = () => {
const [state, setState] = useState({
blob: null,
style: '',
url: '',
currentAPI: '',
firstTime: false,
photoInfo: {
hidden: false,
offline: false,
photographerURL: '',
photoURL: '',
},
type: '',
video: false,
});
const [backgroundState, setBackgroundState] = useState(initialState);
const blobRef = useRef(null);
const getAPIImageData = useCallback(async (currentPun) => {
let apiCategories;
try {
apiCategories = JSON.parse(localStorage.getItem('apiCategories'));
} catch (error) {
apiCategories = localStorage.getItem('apiCategories');
}
const backgroundAPI = localStorage.getItem('backgroundAPI') || defaults.backgroundAPI;
const apiQuality = localStorage.getItem('apiQuality') || defaults.apiQuality;
let backgroundExclude = JSON.parse(localStorage.getItem('backgroundExclude'));
if (!Array.isArray(backgroundExclude)) {
backgroundExclude = [];
}
if (currentPun) {
backgroundExclude.push(currentPun);
}
let requestURL;
switch (backgroundAPI) {
case 'unsplash':
case 'pexels':
const collection =
localStorage.getItem('unsplashCollections') || defaults.unsplashCollections;
requestURL = collection
? `${variables.constants.API_URL}/images/unsplash?collections=${collection}&quality=${apiQuality}`
: `${variables.constants.API_URL}/images/unsplash?categories=${apiCategories || ''}&quality=${apiQuality}`;
break;
default:
requestURL = `${variables.constants.API_URL}/images/random?categories=${apiCategories || ''}&quality=${apiQuality}&excludes=${backgroundExclude}`;
break;
}
const accept = `application/json, ${supportsAVIF() ? 'image/avif' : 'image/webp'}`;
try {
const response = await fetch(requestURL, { headers: { accept } });
const data = await response.json();
let photoURL, photographerURL;
if (backgroundAPI === 'unsplash') {
photoURL = data.photo_page;
photographerURL = data.photographer_page;
}
return {
url: data.file,
type: 'api',
currentAPI: backgroundAPI,
photoInfo: {
hidden: false,
category: data.category,
credit: data.photographer,
location: data.location.name,
camera: data.camera,
url: data.file,
photographerURL,
photoURL,
latitude: data.location.latitude || null,
longitude: data.location.longitude || null,
views: data.views || null,
downloads: data.downloads || null,
likes: data.likes || null,
description: data.description || null,
colour: data.colour,
blur_hash: data.blur_hash,
pun: data.pun || null,
},
};
} catch (e) {
setState(getOfflineImage('api'));
Stats.postEvent('background', 'image', 'offline');
return null;
}
}, []);
const { getAPIImageData } = useBackgroundAPI(setBackgroundState);
const setBackground = useCallback(async () => {
// Clean up previous blob URL
if (blobRef.current) {
URL.revokeObjectURL(blobRef.current);
blobRef.current = null;
}
const backgroundImage = document.getElementById('backgroundImage');
const blurhashOverlay = document.getElementById('blurhashOverlay');
const backgroundImageActual = document.getElementById('backgroundImageActual');
const photoInformation = document.querySelector('.photoInformation');
const elements = {
backgroundImage: document.getElementById('backgroundImage'),
blurhashOverlay: document.getElementById('blurhashOverlay'),
backgroundImageActual: document.getElementById('backgroundImageActual'),
photoInformation: document.querySelector('.photoInformation'),
};
// Reset elements to default state
backgroundImageActual.style.opacity = 0;
blurhashOverlay.style.backgroundImage = '';
blurhashOverlay.style.backgroundColor = '';
resetElements(elements.backgroundImageActual, elements.blurhashOverlay);
// Handle different background types
try {
switch (state.type) {
case 'api':
// Handle API image with blurhash
if (state.url) {
if (localStorage.getItem('bgtransition') === 'false') {
if (photoInformation) {
photoInformation.style.display = 'flex';
}
backgroundImage.style.background = `url(${state.url})`;
return;
}
await applyBackground(backgroundState, elements);
// Set blurhash overlay if available
if (state.photoInfo.blur_hash) {
blurhashOverlay.style.backgroundColor = state.photoInfo.colour;
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(32, 32);
imageData.data.set(decodeBlurHash(state.photoInfo.blur_hash, 32, 32));
ctx.putImageData(imageData, 0, 0);
blurhashOverlay.style.backgroundImage = `url(${canvas.toDataURL()})`;
}
// Load actual image
const newBlob = URL.createObjectURL(await (await fetch(state.url)).blob());
blobRef.current = newBlob;
backgroundImageActual.src = newBlob;
}
break;
case 'colour':
case 'random_colour':
case 'random_gradient':
backgroundImage.style.background = state.style;
backgroundImageActual.src = '';
Stats.postEvent('background', 'colour', 'set');
break;
case 'custom':
case 'photo_pack':
if (state.url) {
backgroundImage.style.background = `url(${state.url})`;
if (photoInformation && !state.photoInfo.hidden) {
photoInformation.style.display = 'flex';
}
}
Stats.postEvent('background', state.type, 'set');
break;
default:
// Fallback to solid color
backgroundImage.style.background = state.style || 'rgb(0,0,0)';
Stats.postEvent('background', 'colour', 'set');
}
// Set up image load handler for all image types
if (backgroundImageActual.src) {
backgroundImageActual.onload = () => {
backgroundImageActual.style.opacity = 1;
blurhashOverlay.style.opacity = 0;
if (elements.backgroundImageActual.src) {
elements.backgroundImageActual.onload = () => {
elements.backgroundImageActual.style.opacity = 1;
elements.blurhashOverlay.style.opacity = 0;
Stats.postEvent('feature', 'background-image', 'shown');
};
}
} catch (error) {
console.error('Error setting background:', error);
// Fallback to solid black background
backgroundImage.style.background = 'rgb(0,0,0)';
elements.backgroundImage.style.background = 'rgb(0,0,0)';
}
}, [state]);
}, [backgroundState]);
const getBackground = useCallback(async () => {
let offline = localStorage.getItem('offlineMode') === 'true';
@@ -201,206 +72,68 @@ const Background = () => {
offline = true;
}
const setFavourited = ({ type, url, credit, location, camera, pun, offline }) => {
if (type === 'random_colour' || type === 'random_gradient') {
setState({
type: 'colour',
style: url,
});
} else {
setState({
url,
photoInfo: {
credit,
location,
camera,
pun,
offline,
url,
},
});
}
Stats.postEvent('background', 'favourite', 'set');
};
const favourited = JSON.parse(localStorage.getItem('favourite'));
if (favourited) {
setFavourited(favourited);
setFavouritedBackground(favourited);
return;
}
const type = localStorage.getItem('backgroundType') || defaults.backgroundType;
switch (type) {
case 'api':
if (offline) {
setState(getOfflineImage('api'));
Stats.postEvent('background', 'image', 'offline');
return;
}
let data = JSON.parse(localStorage.getItem('nextImage')) || (await getAPIImageData());
localStorage.setItem('nextImage', null);
if (data) {
setState(data);
localStorage.setItem('currentBackground', JSON.stringify(data));
localStorage.setItem(
'nextImage',
JSON.stringify(await getAPIImageData(data.photoInfo.pun)),
);
Stats.postEvent('background', 'image', 'api');
}
break;
case 'colour':
let customBackgroundColour = localStorage.getItem('customBackgroundColour');
if (customBackgroundColour && customBackgroundColour.startsWith('{')) {
const customBackground = JSON.parse(customBackgroundColour);
try {
localStorage.setItem('customBackgroundColour', customBackground.gradient[0].colour);
customBackgroundColour = customBackground.gradient.colour;
} catch (e) {
customBackgroundColour = 'rgb(0,0,0)';
}
}
setState({
type: 'colour',
style: customBackgroundColour || 'rgb(0,0,0)',
});
Stats.postEvent('background', 'colour', 'custom');
break;
case 'random_colour':
case 'random_gradient':
const randomStyle = randomColourStyleBuilder(type);
setState({
type: 'colour',
style: randomStyle,
});
Stats.postEvent('background', 'colour', 'random');
break;
case 'custom':
let customBackground = [];
const customSaved = localStorage.getItem('customBackground') || defaults.customBackground;
try {
customBackground = JSON.parse(customSaved);
} catch (e) {
if (customSaved !== '') {
customBackground = [customSaved];
}
localStorage.setItem('customBackground', JSON.stringify(customBackground));
}
customBackground = customBackground[Math.floor(Math.random() * customBackground.length)];
if (offline && !customBackground.startsWith('data:')) {
setState(getOfflineImage('custom'));
Stats.postEvent('background', 'image', 'offline');
return;
}
if (
customBackground !== '' &&
customBackground !== 'undefined' &&
customBackground !== undefined
) {
const object = {
url: customBackground,
type: 'custom',
video: videoCheck(customBackground),
photoInfo: {
hidden: true,
},
};
setState(object);
localStorage.setItem('currentBackground', JSON.stringify(object));
Stats.postEvent('background', 'image', 'custom');
}
break;
case 'photo_pack':
if (offline) {
setState(getOfflineImage('photo'));
Stats.postEvent('background', 'image', 'offline');
return;
}
const photoPack = [];
const installed = JSON.parse(localStorage.getItem('installed'));
installed.forEach((item) => {
if (item.type === 'photos') {
const photos = item.photos.map((photo) => photo);
photoPack.push(...photos);
}
});
if (photoPack.length === 0) {
setState(getOfflineImage('photo'));
Stats.postEvent('background', 'image', 'offline');
return;
}
const photo = photoPack[Math.floor(Math.random() * photoPack.length)];
setState({
url: photo.url.default,
type: 'photo_pack',
video: videoCheck(photo.url.default),
photoInfo: {
photographer: photo.photographer,
},
});
Stats.postEvent('background', 'image', 'photo_pack');
break;
default:
break;
}
await handleBackgroundType(type, offline, getAPIImageData, setBackgroundState);
}, [getAPIImageData]);
const setFavouritedBackground = ({ type, url, credit, location, camera, pun, offline }) => {
if (type === 'random_colour' || type === 'random_gradient') {
setBackgroundState({
type: 'colour',
style: url,
});
} else {
setBackgroundState({
url,
photoInfo: {
credit,
location,
camera,
pun,
offline,
url,
},
});
}
Stats.postEvent('background', 'favourite', 'set');
};
const handleRefreshEvent = useCallback(
(data) => {
const element = document.getElementById('backgroundImage');
const refresh = () => {
element.classList.remove('fade-in');
setState({
url: '',
style: '',
type: '',
video: false,
photoInfo: {
hidden: true,
},
});
setBackgroundState(initialState);
getBackground();
};
if (data === 'welcomeLanguage') {
localStorage.setItem('welcomeImage', JSON.stringify(state));
localStorage.setItem('welcomeImage', JSON.stringify(backgroundState));
}
if (data === 'background') {
if (localStorage.getItem('background') === 'false') {
if (state.photoInfo.hidden === false) {
document.querySelector('.photoInformation').style.display = 'none';
}
if (state.video === true) {
document.getElementById('backgroundVideo').style.display = 'none';
} else {
element.style.display = 'none';
}
return;
}
if (state.video === true) {
document.getElementById('backgroundVideo').style.display = 'block';
} else {
if (state.photoInfo.hidden === false) {
try {
document.querySelector('.photoInformation').style.display = 'flex';
} catch (e) {
// Disregard exception
}
}
element.style.display = 'block';
}
handleBackgroundVisibility(backgroundState, element);
const backgroundType = localStorage.getItem('backgroundType') || defaults.backgroundType;
if (state.photoInfo.offline !== true) {
if (backgroundState.photoInfo.offline !== true) {
if (
backgroundType !== state.type ||
(state.type === 'api' && localStorage.getItem('backgroundAPI') !== state.currentAPI) ||
(state.type === 'custom' && localStorage.getItem('customBackground') !== state.url) ||
JSON.parse(localStorage.getItem('backgroundExclude')).includes(state.photoInfo.pun)
backgroundType !== backgroundState.type ||
(backgroundState.type === 'api' &&
localStorage.getItem('backgroundAPI') !== backgroundState.currentAPI) ||
(backgroundState.type === 'custom' &&
localStorage.getItem('customBackground') !== backgroundState.url) ||
JSON.parse(localStorage.getItem('backgroundExclude')).includes(
backgroundState.photoInfo.pun,
)
) {
refresh();
return;
}
} else if (backgroundType !== state.type) {
} else if (backgroundType !== backgroundState.type) {
refresh();
return;
}
@@ -413,29 +146,12 @@ const Background = () => {
refresh();
}
},
[state, getBackground],
[backgroundState, getBackground],
);
const handleBackgroundEffectEvent = useCallback(() => {
const element = document.getElementById('backgroundImage');
const backgroundFilterSetting =
localStorage.getItem('backgroundFilter') || defaults.backgroundFilter;
const backgroundFilter = backgroundFilterSetting && backgroundFilterSetting !== 'none';
const filterValue = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%) ${
backgroundFilter
? backgroundFilterSetting + '(' + localStorage.getItem('backgroundFilterAmount') + '%)'
: ''
}`;
if (state.video === true) {
document.getElementById('backgroundVideo').style.filter = filterValue;
} else {
element.style.filter = filterValue;
}
}, [state.video]);
useEffect(() => {
if (localStorage.getItem('welcomeTab')) {
setState(JSON.parse(localStorage.getItem('welcomeImage')));
setBackgroundState(JSON.parse(localStorage.getItem('welcomeImage')));
return;
}
getBackground();
@@ -449,23 +165,27 @@ const Background = () => {
EventBus.off('refresh', handleRefreshEvent);
EventBus.off('backgroundeffect', handleBackgroundEffectEvent);
};
}, [handleRefreshEvent, handleBackgroundEffectEvent]);
}, [handleRefreshEvent]);
useEffect(() => {
if (state.video !== true) {
if (backgroundState.video !== true) {
setBackground();
}
}, [state, setBackground]);
}, [backgroundState, setBackground]);
if (state.video === true) {
return <BackgroundVideo url={state.url} />;
if (backgroundState.video === true) {
return <BackgroundVideo url={backgroundState.url} />;
}
return (
<>
<BackgroundImage />
{state.photoInfo && state.photoInfo.credit && (
<PhotoInformation info={state.photoInfo} api={state.currentAPI} url={state.url} />
{backgroundState.photoInfo && backgroundState.photoInfo.credit && (
<PhotoInformation
info={backgroundState.photoInfo}
api={backgroundState.currentAPI}
url={backgroundState.url}
/>
)}
</>
);

View File

@@ -0,0 +1,262 @@
import { decodeBlurHash } from 'fast-blurhash';
import { getOfflineImage } from './getOfflineImage';
import { supportsAVIF } from './avif';
import videoCheck from './videoCheck';
import { randomColourStyleBuilder } from './randomColour';
import defaults from '../options/default';
import variables from 'config/variables';
import Stats from 'features/stats/api/stats';
export const getRequestURL = (backgroundAPI, apiCategories, apiQuality, backgroundExclude) => {
switch (backgroundAPI) {
case 'unsplash':
case 'pexels':
const collection =
localStorage.getItem('unsplashCollections') || defaults.unsplashCollections;
return collection
? `${variables.constants.API_URL}/images/unsplash?collections=${collection}&quality=${apiQuality}`
: `${variables.constants.API_URL}/images/unsplash?categories=${apiCategories || ''}&quality=${apiQuality}`;
default:
return `${variables.constants.API_URL}/images/random?categories=${apiCategories || ''}&quality=${apiQuality}&excludes=${backgroundExclude}`;
}
};
export const formatAPIData = (data, backgroundAPI) => {
let photoURL, photographerURL;
if (backgroundAPI === 'unsplash') {
photoURL = data.photo_page;
photographerURL = data.photographer_page;
}
return {
url: data.file,
type: 'api',
currentAPI: backgroundAPI,
photoInfo: {
hidden: false,
category: data.category,
credit: data.photographer,
location: data.location.name,
camera: data.camera,
url: data.file,
photographerURL,
photoURL,
latitude: data.location.latitude || null,
longitude: data.location.longitude || null,
views: data.views || null,
downloads: data.downloads || null,
likes: data.likes || null,
description: data.description || null,
colour: data.colour,
blur_hash: data.blur_hash,
pun: data.pun || null,
},
};
};
export const resetElements = (backgroundImageActual, blurhashOverlay) => {
backgroundImageActual.style.opacity = 0;
blurhashOverlay.style.backgroundImage = '';
blurhashOverlay.style.backgroundColor = '';
};
export const handleAPIBackground = async (
state,
backgroundImage,
blurhashOverlay,
backgroundImageActual,
photoInformation,
) => {
if (state.url) {
if (localStorage.getItem('bgtransition') === 'false') {
if (photoInformation) {
photoInformation.style.display = 'flex';
}
backgroundImage.style.background = `url(${state.url})`;
return;
}
if (state.photoInfo.blur_hash) {
blurhashOverlay.style.backgroundColor = state.photoInfo.colour;
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(32, 32);
imageData.data.set(decodeBlurHash(state.photoInfo.blur_hash, 32, 32));
ctx.putImageData(imageData, 0, 0);
blurhashOverlay.style.backgroundImage = `url(${canvas.toDataURL()})`;
}
const newBlob = URL.createObjectURL(await (await fetch(state.url)).blob());
backgroundImageActual.src = newBlob;
}
};
export const handleColourBackground = (state, backgroundImage) => {
backgroundImage.style.background = state.style;
Stats.postEvent('background', 'colour', 'set');
};
export const handleCustomBackground = (state, backgroundImage, photoInformation) => {
if (state.url) {
backgroundImage.style.background = `url(${state.url})`;
if (photoInformation && !state.photoInfo.hidden) {
photoInformation.style.display = 'flex';
}
}
Stats.postEvent('background', state.type, 'set');
};
export const handleDefaultBackground = (state, backgroundImage) => {
backgroundImage.style.background = state.style || 'rgb(0,0,0)';
Stats.postEvent('background', 'colour', 'set');
};
export const handleAPIBackgroundType = async (offline, getAPIImageData, setState) => {
if (offline) {
setState(getOfflineImage('api'));
Stats.postEvent('background', 'image', 'offline');
return;
}
let data = JSON.parse(localStorage.getItem('nextImage')) || (await getAPIImageData());
localStorage.setItem('nextImage', null);
if (data) {
setState(data);
localStorage.setItem('currentBackground', JSON.stringify(data));
localStorage.setItem('nextImage', JSON.stringify(await getAPIImageData(data.photoInfo.pun)));
Stats.postEvent('background', 'image', 'api');
}
};
export const handleColourBackgroundType = (setState) => {
let customBackgroundColour = localStorage.getItem('customBackgroundColour');
if (customBackgroundColour && customBackgroundColour.startsWith('{')) {
const customBackground = JSON.parse(customBackgroundColour);
try {
localStorage.setItem('customBackgroundColour', customBackground.gradient[0].colour);
customBackgroundColour = customBackground.gradient.colour;
} catch (e) {
customBackgroundColour = 'rgb(0,0,0)';
}
}
setState({
type: 'colour',
style: customBackgroundColour || 'rgb(0,0,0)',
});
Stats.postEvent('background', 'colour', 'custom');
};
export const handleRandomColourBackgroundType = (type, setState) => {
const randomStyle = randomColourStyleBuilder(type);
setState({
type: 'colour',
style: randomStyle,
});
Stats.postEvent('background', 'colour', 'random');
};
export const handleCustomBackgroundType = async (offline, setState) => {
let customBackground = [];
const customSaved = localStorage.getItem('customBackground') || defaults.customBackground;
try {
customBackground = JSON.parse(customSaved);
} catch (e) {
if (customSaved !== '') {
customBackground = [customSaved];
}
localStorage.setItem('customBackground', JSON.stringify(customBackground));
}
customBackground = customBackground[Math.floor(Math.random() * customBackground.length)];
if (offline && !customBackground.startsWith('data:')) {
setState(getOfflineImage('custom'));
Stats.postEvent('background', 'image', 'offline');
return;
}
if (customBackground) {
const object = {
url: customBackground,
type: 'custom',
video: videoCheck(customBackground),
photoInfo: {
hidden: true,
},
};
setState(object);
localStorage.setItem('currentBackground', JSON.stringify(object));
Stats.postEvent('background', 'image', 'custom');
}
};
export const handlePhotoPackBackgroundType = async (offline, setState) => {
if (offline) {
setState(getOfflineImage('photo'));
Stats.postEvent('background', 'image', 'offline');
return;
}
const photoPack = [];
const installed = JSON.parse(localStorage.getItem('installed'));
installed.forEach((item) => {
if (item.type === 'photos') {
const photos = item.photos.map((photo) => photo);
photoPack.push(...photos);
}
});
if (photoPack.length === 0) {
setState(getOfflineImage('photo'));
Stats.postEvent('background', 'image', 'offline');
return;
}
const photo = photoPack[Math.floor(Math.random() * photoPack.length)];
setState({
url: photo.url.default,
type: 'photo_pack',
video: videoCheck(photo.url.default),
photoInfo: {
photographer: photo.photographer,
},
});
Stats.postEvent('background', 'image', 'photo_pack');
};
export const handleBackgroundVisibility = (state, element) => {
if (localStorage.getItem('background') === 'false') {
if (state.photoInfo.hidden === false) {
document.querySelector('.photoInformation').style.display = 'none';
}
if (state.video === true) {
document.getElementById('backgroundVideo').style.display = 'none';
} else {
element.style.display = 'none';
}
return;
}
if (state.video === true) {
document.getElementById('backgroundVideo').style.display = 'block';
} else {
if (state.photoInfo.hidden === false) {
try {
document.querySelector('.photoInformation').style.display = 'flex';
} catch (e) {
// Disregard exception
}
}
element.style.display = 'block';
}
};
export const handleBackgroundEffectEvent = (state) => {
const element = document.getElementById('backgroundImage');
const backgroundFilterSetting =
localStorage.getItem('backgroundFilter') || defaults.backgroundFilter;
const backgroundFilter = backgroundFilterSetting && backgroundFilterSetting !== 'none';
const filterValue = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%) ${
backgroundFilter
? backgroundFilterSetting + '(' + localStorage.getItem('backgroundFilterAmount') + '%)'
: ''
}`;
if (state.video === true) {
document.getElementById('backgroundVideo').style.filter = filterValue;
} else {
element.style.filter = filterValue;
}
};

View File

@@ -0,0 +1,61 @@
import {
handleAPIBackground,
handleColourBackground,
handleCustomBackground,
handleDefaultBackground,
handleAPIBackgroundType,
handleColourBackgroundType,
handleRandomColourBackgroundType,
handleCustomBackgroundType,
handlePhotoPackBackgroundType,
} from './backgroundHelpers';
export const handleBackgroundType = async (type, offline, getAPIImageData, setState) => {
switch (type) {
case 'api':
await handleAPIBackgroundType(offline, getAPIImageData, setState);
break;
case 'colour':
handleColourBackgroundType(setState);
break;
case 'random_colour':
case 'random_gradient':
handleRandomColourBackgroundType(type, setState);
break;
case 'custom':
await handleCustomBackgroundType(offline, setState);
break;
case 'photo_pack':
await handlePhotoPackBackgroundType(offline, setState);
break;
default:
break;
}
};
export const applyBackground = async (backgroundState, elements) => {
const { backgroundImage, blurhashOverlay, backgroundImageActual, photoInformation } = elements;
switch (backgroundState.type) {
case 'api':
await handleAPIBackground(
backgroundState,
backgroundImage,
blurhashOverlay,
backgroundImageActual,
photoInformation,
);
break;
case 'colour':
case 'random_colour':
case 'random_gradient':
handleColourBackground(backgroundState, backgroundImage);
break;
case 'custom':
case 'photo_pack':
handleCustomBackground(backgroundState, backgroundImage, photoInformation);
break;
default:
handleDefaultBackground(backgroundState, backgroundImage);
}
};

View File

@@ -0,0 +1,45 @@
import { useCallback } from 'react';
import { getRequestURL, formatAPIData } from './backgroundHelpers';
import { getOfflineImage } from './getOfflineImage';
import { supportsAVIF } from './avif';
import defaults from '../options/default';
import Stats from 'features/stats/api/stats';
const useBackgroundAPI = (setBackgroundState) => {
const getAPIImageData = useCallback(
async (currentPun) => {
let apiCategories;
try {
apiCategories = JSON.parse(localStorage.getItem('apiCategories'));
} catch (error) {
apiCategories = localStorage.getItem('apiCategories');
}
const backgroundAPI = localStorage.getItem('backgroundAPI') || defaults.backgroundAPI;
const apiQuality = localStorage.getItem('apiQuality') || defaults.apiQuality;
let backgroundExclude = JSON.parse(localStorage.getItem('backgroundExclude')) || [];
if (currentPun) {
backgroundExclude.push(currentPun);
}
const requestURL = getRequestURL(backgroundAPI, apiCategories, apiQuality, backgroundExclude);
const accept = `application/json, ${supportsAVIF() ? 'image/avif' : 'image/webp'}`;
try {
const response = await fetch(requestURL, { headers: { accept } });
const data = await response.json();
return formatAPIData(data, backgroundAPI);
} catch (e) {
setBackgroundState(getOfflineImage('api'));
Stats.postEvent('background', 'image', 'offline');
return null;
}
},
[setBackgroundState],
);
return { getAPIImageData };
};
export default useBackgroundAPI;