Skip to content

Commit

Permalink
ntp: customizer drawer screens (#1303)
Browse files Browse the repository at this point in the history
* ntp: customizer drawer

* unused param
  • Loading branch information
shakyShane authored Dec 18, 2024
1 parent 735d634 commit 2012858
Show file tree
Hide file tree
Showing 21 changed files with 1,968 additions and 61 deletions.
98 changes: 88 additions & 10 deletions special-pages/pages/new-tab/app/components/BackgroundProvider.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { h } from 'preact';
import { Fragment, h } from 'preact';
import styles from './BackgroundReceiver.module.css';
import { values } from '../customizer/values.js';
import { useContext } from 'preact/hooks';
import { CustomizerContext } from '../customizer/CustomizerProvider.js';
import { detectThemeFromHex } from '../customizer/utils.js';

/**
* @import { BackgroundVariant, BrowserTheme } from "../../types/new-tab"
Expand All @@ -18,12 +20,22 @@ export function inferSchemeFrom(background, browserTheme, system) {
switch (background.kind) {
case 'default':
return { bg: browser, browser };
case 'gradient':
case 'color': {
const color = values.colors[background.value];
return { bg: color.colorScheme, browser };
}

case 'gradient': {
const gradient = values.gradients[background.value];
return { bg: gradient.colorScheme, browser };
}

case 'userImage':
return { bg: background.value.colorScheme, browser };

case 'hex':
console.log('not supported yet!');
return { bg: detectThemeFromHex(background.value), browser };
}
return { bg: browser, browser };
}

/**
Expand All @@ -50,13 +62,79 @@ export function BackgroundConsumer({ browser }) {
case 'default': {
return <div className={styles.root} data-testid="BackgroundConsumer" data-background-kind="default" data-theme={browser} />;
}
case 'hex':
case 'color':
case 'gradient':
case 'userImage':
case 'hex': {
return (
<div
class={styles.root}
data-animate="true"
data-testid="BackgroundConsumer"
style={{
backgroundColor: background.value,
}}
></div>
);
}
case 'color': {
const color = values.colors[background.value];
return (
<div
class={styles.root}
data-animate="true"
data-background-color={color.hex}
data-testid="BackgroundConsumer"
style={{
backgroundColor: color.hex,
}}
></div>
);
}
case 'gradient': {
const gradient = values.gradients[background.value];
return (
<Fragment key="gradient">
<div
class={styles.root}
data-animate="false"
data-testid="BackgroundConsumer"
style={{
backgroundColor: gradient.fallback,
backgroundImage: `url(${gradient.path})`,
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
}}
/>
<div
class={styles.root}
data-animate="false"
style={{
backgroundImage: `url(gradients/grain.png)`,
backgroundRepeat: 'repeat',
opacity: 0.5,
mixBlendMode: 'soft-light',
}}
></div>
</Fragment>
);
}
case 'userImage': {
const img = background.value;
return (
<div
class={styles.root}
data-animate="true"
data-testid="BackgroundConsumer"
style={{
backgroundImage: `url(${img.src})`,
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center center',
}}
></div>
);
}
default: {
console.warn('not supported yet!');
return <div className={styles.root} data-testid="BackgroundConsumer" data-background-kind="default" data-theme={browser} />;
console.warn('Unreachable!');
return <div className={styles.root}></div>;
}
}
}
69 changes: 66 additions & 3 deletions special-pages/pages/new-tab/app/customizer/CustomizerProvider.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { createContext, h } from 'preact';
import { signal, useSignal } from '@preact/signals';
import { useCallback } from 'preact/hooks';
import { effect, signal, useSignal } from '@preact/signals';
import { useThemes } from './themes.js';

/**
* @typedef {import('../../types/new-tab.js').CustomizerData} CustomizerData
* @typedef {import('../../types/new-tab.js').BackgroundData} BackgroundData
* @typedef {import('../../types/new-tab.js').ThemeData} ThemeData
* @typedef {import('../../types/new-tab.js').UserImageData} UserImageData
* @typedef {import('../service.hooks.js').State<CustomizerData, undefined>} State
* @typedef {import('../service.hooks.js').Events<CustomizerData, undefined>} Events
*/

/**
Expand All @@ -24,6 +30,17 @@ export const CustomizerContext = createContext({
userColor: null,
theme: 'system',
}),
/** @type {(bg: BackgroundData) => void} */
select: (bg) => {},
upload: () => {},
/**
* @type {(theme: ThemeData) => void}
*/
setTheme: (theme) => {},
/**
* @type {(id: string) => void}
*/
deleteImage: (id) => {},
});

/**
Expand All @@ -40,10 +57,56 @@ export function CustomizerProvider({ service, initialData, children }) {
const data = useSignal(initialData);
const { main, browser } = useThemes(data);

// todo: add data subscriptions here
effect(() => {
const unsub = service.onBackground((evt) => {
data.value = { ...data.value, background: evt.data.background };
});
const unsub1 = service.onTheme((evt) => {
data.value = { ...data.value, theme: evt.data.theme };
});
const unsub2 = service.onImages((evt) => {
data.value = { ...data.value, userImages: evt.data.userImages };
});
const unsub3 = service.onColor((evt) => {
data.value = { ...data.value, userColor: evt.data.userColor };
});

return () => {
unsub();
unsub1();
unsub2();
unsub3();
};
});

/** @type {(bg: BackgroundData) => void} */
const select = useCallback(
(bg) => {
service.setBackground(bg);
},
[service],
);

const upload = useCallback(() => {
service.upload();
}, [service]);

const setTheme = useCallback(
(theme) => {
service.setTheme(theme);
},
[service],
);

const deleteImage = useCallback(
(id) => {
service.deleteImage(id);
},
[service],
);

return (
<CustomizerContext.Provider value={{ data }}>
<CustomizerContext.Provider value={{ data, select, upload, setTheme, deleteImage }}>
<CustomizerThemesContext.Provider value={{ main, browser }}>{children}</CustomizerThemesContext.Provider>
</CustomizerContext.Provider>
);
Expand Down
Loading

0 comments on commit 2012858

Please sign in to comment.