Refactor backgrounds state

This commit is contained in:
Georgi Gardev
2023-11-20 00:19:00 +02:00
parent e242029644
commit 044847f706
3 changed files with 69 additions and 58 deletions

View File

@@ -4,7 +4,11 @@ import { Show } from 'solid-js';
import { useSettings } from '~/state/settings-provider';
export function FavoriteBackground() {
const { onFavoriteBackground, onUnfavoriteBackground, isBackgroundSaved } = useSettings();
const {
onFavoriteBackground,
onUnfavoriteBackground,
isBackgroundFavorite: isBackgroundSaved,
} = useSettings();
return (
<Show

View File

@@ -1,4 +1,4 @@
import { createMemo } from 'solid-js';
import { Accessor, createEffect, createMemo, createSignal } from 'solid-js';
import { getRandomBackground } from '~/api/unsplash';
import { BACKGROUND_FETCH_MINS } from '~/config';
import { sample } from '~/lib/array';
@@ -6,7 +6,16 @@ import { createLocalStore } from '~/lib/create-local-store';
import { Background, BackgroundStorage } from '~/types';
import { Settings } from './settings-provider';
export function createBackgrounds(appSettings: Settings) {
export type BackgroundsState = {
currentBackground: Accessor<Background | undefined>;
onNextBackground(): void;
favoriteBackgrounds: Background[];
onFavoriteBackground(): void;
onUnfavoriteBackground(): void;
isBackgroundFavorite: Accessor<boolean>;
};
export function createBackgrounds(appSettings: Settings): BackgroundsState {
const [backgrounds, setBackgrounds] = createLocalStore<BackgroundStorage>(
'start-page-background',
{ fetched_at: 0, backgrounds: null }
@@ -34,13 +43,41 @@ export function createBackgrounds(appSettings: Settings) {
sample(backgrounds.backgrounds ?? [])
);
const isBackgroundSaved = (id: string) => Boolean(favoriteBackgrounds.find((b) => b.id === id));
const [currentBackground, setCurrentBackground] = createSignal(
appSettings.useSavedBackgrounds ? sample(favoriteBackgrounds) : currentRandomBackground()
);
const onUnfavoriteBackground = (id: string) =>
setFavroiteBackgrounds((prev) => prev.filter((b) => b.id !== id));
createEffect(() =>
// Change background when appSettings.useSavedBackgrounds changes
setCurrentBackground(
appSettings.useSavedBackgrounds ? sample(favoriteBackgrounds) : currentRandomBackground()
)
);
const onNextBackground = () => {
if (appSettings.useSavedBackgrounds && favoriteBackgrounds.length < 2) {
return;
}
let background = currentBackground();
while (background === currentBackground()) {
background = appSettings.useSavedBackgrounds
? sample(favoriteBackgrounds)
: sample(backgrounds.backgrounds ?? []);
}
setCurrentBackground(background);
};
const isCurrentBackgroundFavorite = () => {
if (!currentBackground()) {
return false;
}
return Boolean(favoriteBackgrounds.find((b) => b.id === currentBackground()!.id));
};
const onFavoriteBackground = () => {
if (!currentRandomBackground()) {
if (!currentBackground()) {
return;
}
@@ -52,12 +89,19 @@ export function createBackgrounds(appSettings: Settings) {
});
};
const onUnfavoriteCurrentBackground = () => {
if (!currentBackground()) {
return;
}
setFavroiteBackgrounds((prev) => prev.filter((b) => b.id !== currentBackground()!.id));
};
return {
backgrounds,
currentRandomBackground,
currentBackground,
onFavoriteBackground,
favoriteBackgrounds,
isBackgroundSaved,
onUnfavoriteBackground,
isBackgroundFavorite: isCurrentBackgroundFavorite,
onUnfavoriteBackground: onUnfavoriteCurrentBackground,
onNextBackground,
};
}

View File

@@ -3,8 +3,7 @@ import { SetStoreFunction } from 'solid-js/store';
import { sample } from '~/lib/array';
import { createLocalStore } from '~/lib/create-local-store';
import { Background } from '~/types';
import { createBackgrounds } from './create-backgrounds';
import { ap } from 'ramda';
import { BackgroundsState, createBackgrounds } from './create-backgrounds';
export type Settings = {
showLocations: boolean;
@@ -13,15 +12,9 @@ export type Settings = {
unsplashQuery: string;
};
type SettingsContextType = {
type SettingsContextType = BackgroundsState & {
appSettings: Settings;
setAppSettings: SetStoreFunction<Settings>;
currentBackground: Accessor<Background | undefined>;
onNextBackground(): void;
favoriteBackgrounds: Background[];
onFavoriteBackground(): void;
onUnfavoriteBackground(): void;
isBackgroundSaved: Accessor<boolean>;
};
const SettingsContext = createContext<SettingsContextType>({
@@ -37,7 +30,7 @@ const SettingsContext = createContext<SettingsContextType>({
favoriteBackgrounds: [],
onFavoriteBackground: () => {},
onUnfavoriteBackground: () => {},
isBackgroundSaved: () => false,
isBackgroundFavorite: () => false,
});
export function SettingsProvider(props: { children: JSX.Element }) {
@@ -49,55 +42,25 @@ export function SettingsProvider(props: { children: JSX.Element }) {
});
const {
backgrounds,
currentRandomBackground,
currentBackground,
onFavoriteBackground,
favoriteBackgrounds,
isBackgroundSaved,
onUnfavoriteBackground,
isBackgroundFavorite,
onNextBackground,
} = createBackgrounds(appSettings);
const [currentBackground, setCurrentBackground] = createSignal(
appSettings.useSavedBackgrounds ? sample(favoriteBackgrounds) : currentRandomBackground()
);
createEffect(() =>
setCurrentBackground(
appSettings.useSavedBackgrounds ? sample(favoriteBackgrounds) : currentRandomBackground()
)
);
const onNextBackground = () => {
if (appSettings.useSavedBackgrounds && favoriteBackgrounds.length < 2) {
return;
}
let background = currentBackground();
while (background === currentBackground()) {
background = appSettings.useSavedBackgrounds
? sample(favoriteBackgrounds)
: sample(backgrounds.backgrounds ?? []);
}
setCurrentBackground(background);
};
const isCurrentBackgroundSaved = () =>
Boolean(currentBackground() && isBackgroundSaved(currentBackground()!.id));
const onUnfavoriteCurrentBackground = () =>
currentBackground() && onUnfavoriteBackground(currentBackground()!.id);
return (
<SettingsContext.Provider
value={{
appSettings,
setAppSettings,
currentBackground,
onNextBackground,
favoriteBackgrounds,
onFavoriteBackground,
onUnfavoriteBackground: onUnfavoriteCurrentBackground,
isBackgroundSaved: isCurrentBackgroundSaved,
appSettings,
setAppSettings,
onUnfavoriteBackground,
isBackgroundFavorite,
}}
>
{props.children}