mirror of
https://github.com/mue/mue.git
synced 2026-07-17 05:54:14 +02:00
212 lines
6.0 KiB
JavaScript
212 lines
6.0 KiB
JavaScript
import variables from 'config/variables';
|
|
import { supportsAVIF } from './avifSupport';
|
|
import { getOfflineImage } from './offlineImage';
|
|
import { randomColourStyleBuilder } from './randomColour';
|
|
import videoCheck from './videoCheck';
|
|
|
|
const parseJSON = (key, fallback = null) => {
|
|
try {
|
|
return JSON.parse(localStorage.getItem(key)) || fallback;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fetches image data from the configured API
|
|
*/
|
|
export async function fetchAPIImageData(excludedPun = null) {
|
|
const api = localStorage.getItem('backgroundAPI') || 'mue';
|
|
const quality = localStorage.getItem('apiQuality') || 'high';
|
|
const categories = parseJSON('apiCategories', localStorage.getItem('apiCategories'));
|
|
const excludes = [...parseJSON('backgroundExclude', []), ...(excludedPun ? [excludedPun] : [])];
|
|
|
|
const baseURL = `${variables.constants.API_URL}/images`;
|
|
const collection = localStorage.getItem('unsplashCollections');
|
|
|
|
const url = (api === 'unsplash' || api === 'pexels')
|
|
? `${baseURL}/unsplash?${collection ? `collections=${collection}` : `categories=${categories || ''}`}&quality=${quality}`
|
|
: `${baseURL}/random?categories=${categories || ''}&quality=${quality}&excludes=${excludes}`;
|
|
|
|
try {
|
|
const accept = `application/json, ${await supportsAVIF() ? 'image/avif' : 'image/webp'}`;
|
|
const data = await (await fetch(url, { headers: { accept } })).json();
|
|
|
|
return {
|
|
url: data.file,
|
|
type: 'api',
|
|
currentAPI: api,
|
|
photoInfo: {
|
|
hidden: false,
|
|
category: data.category,
|
|
credit: data.photographer,
|
|
location: data.location.name,
|
|
camera: data.camera,
|
|
url: data.file,
|
|
photographerURL: api === 'unsplash' ? data.photographer_page : undefined,
|
|
photoURL: api === 'unsplash' ? data.photo_page : undefined,
|
|
latitude: data.location.latitude,
|
|
longitude: data.location.longitude,
|
|
views: data.views,
|
|
downloads: data.downloads,
|
|
likes: data.likes,
|
|
description: data.description,
|
|
colour: data.colour,
|
|
blur_hash: data.blur_hash,
|
|
pun: data.pun,
|
|
},
|
|
};
|
|
} catch (error) {
|
|
console.error('Failed to fetch API image:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets background data based on current configuration
|
|
*/
|
|
export async function getBackgroundData() {
|
|
const isOffline = localStorage.getItem('offlineMode') === 'true' || localStorage.getItem('showWelcome') === 'true';
|
|
|
|
// Handle favourited background
|
|
const fav = parseJSON('favourite');
|
|
if (fav) {
|
|
if (fav.type === 'random_colour' || fav.type === 'random_gradient') {
|
|
return { type: 'colour', style: `background:${fav.url}` };
|
|
}
|
|
return { url: fav.url, photoInfo: { ...fav, url: fav.url } };
|
|
}
|
|
|
|
const type = localStorage.getItem('backgroundType');
|
|
|
|
switch (type) {
|
|
case 'api':
|
|
return getAPIBackground(isOffline);
|
|
|
|
case 'colour':
|
|
return getColourBackground();
|
|
|
|
case 'random_colour':
|
|
case 'random_gradient':
|
|
return randomColourStyleBuilder(type);
|
|
|
|
case 'custom':
|
|
return getCustomBackground(isOffline);
|
|
|
|
case 'photo_pack':
|
|
return getPhotoPackBackground(isOffline);
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets solid colour background
|
|
*/
|
|
function getColourBackground() {
|
|
let colour = localStorage.getItem('customBackgroundColour');
|
|
|
|
// Migrate legacy format
|
|
if (colour?.startsWith('{')) {
|
|
try {
|
|
colour = JSON.parse(colour).gradient[0].colour;
|
|
localStorage.setItem('customBackgroundColour', colour);
|
|
} catch {
|
|
colour = 'rgb(0,0,0)';
|
|
}
|
|
}
|
|
|
|
return { type: 'colour', style: `background: ${colour || 'rgb(0,0,0)'}` };
|
|
}
|
|
|
|
/**
|
|
* Gets API background with caching
|
|
*/
|
|
async function getAPIBackground(isOffline) {
|
|
if (isOffline) return getOfflineImage('api');
|
|
|
|
// Use cached next image if available
|
|
const cached = parseJSON('nextImage');
|
|
const data = cached || await fetchAPIImageData();
|
|
|
|
if (!data) return getOfflineImage('api');
|
|
|
|
localStorage.setItem('currentBackground', JSON.stringify(data));
|
|
localStorage.setItem('nextImage', null);
|
|
|
|
// Pre-fetch next image
|
|
fetchAPIImageData(data.photoInfo.pun).then((next) => {
|
|
if (next) localStorage.setItem('nextImage', JSON.stringify(next));
|
|
});
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Gets custom background
|
|
*/
|
|
function getCustomBackground(isOffline) {
|
|
let backgrounds = parseJSON('customBackground');
|
|
|
|
// Migrate legacy format
|
|
if (!Array.isArray(backgrounds)) {
|
|
const saved = localStorage.getItem('customBackground');
|
|
backgrounds = saved ? [saved] : [];
|
|
localStorage.setItem('customBackground', JSON.stringify(backgrounds));
|
|
}
|
|
|
|
if (backgrounds.length === 0) return null;
|
|
|
|
const selected = backgrounds[Math.floor(Math.random() * backgrounds.length)];
|
|
|
|
if (isOffline && !selected.startsWith('data:')) return getOfflineImage('custom');
|
|
|
|
const data = {
|
|
url: selected,
|
|
type: 'custom',
|
|
video: videoCheck(selected),
|
|
photoInfo: { hidden: true },
|
|
};
|
|
|
|
localStorage.setItem('currentBackground', JSON.stringify(data));
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Gets photo pack background
|
|
*/
|
|
function getPhotoPackBackground(isOffline) {
|
|
if (isOffline) return getOfflineImage('photo_pack');
|
|
|
|
const photos = parseJSON('installed', []).flatMap((item) =>
|
|
item.type === 'photos' && item.photos ? item.photos : []
|
|
);
|
|
|
|
if (photos.length === 0) return null;
|
|
|
|
const interval = localStorage.getItem('backgroundchange');
|
|
const startTime = Number(localStorage.getItem('backgroundStartTime'));
|
|
const shouldRefresh = !interval || interval === 'refresh' || startTime + Number(interval) < Date.now();
|
|
|
|
let index;
|
|
if (shouldRefresh) {
|
|
index = Math.floor(Math.random() * photos.length);
|
|
localStorage.setItem('marketplaceNumber', index);
|
|
} else {
|
|
index = Number(localStorage.getItem('marketplaceNumber')) || 0;
|
|
}
|
|
|
|
const photo = photos[index];
|
|
|
|
return photo ? {
|
|
url: photo.url.default,
|
|
type: 'photo_pack',
|
|
photoInfo: {
|
|
hidden: false,
|
|
credit: photo.photographer,
|
|
location: photo.location,
|
|
},
|
|
} : null;
|
|
}
|