feat(mobile): pwa and browser theme-color optimization (#8168)

[AF-1325](https://linear.app/affine-design/issue/AF-1325/优化-pwa-体验), [AF-1317](https://linear.app/affine-design/issue/AF-1317/优化:-pwa-的顶部-status-bar-颜色应与背景保持一致), [AF-1318](https://linear.app/affine-design/issue/AF-1318/优化:pwa-的底部应当有符合设备安全高度的padding), [AF-1321](https://linear.app/affine-design/issue/AF-1321/更新一下-fail-的-pwa-icon)

- New `<SafeArea />` ui component
- New `useThemeColorV1` / `useThemeColorV2` hook:
    - to modify `<meta name="theme-color" />` with given theme key
This commit is contained in:
CatsJuice
2024-09-11 02:20:59 +00:00
parent 9038592715
commit 81ab8ac8b3
31 changed files with 329 additions and 133 deletions

View File

@@ -1,2 +1,4 @@
export { useAutoFocus, useAutoSelect } from './focus-and-select';
export { useRefEffect } from './use-ref-effect';
export * from './use-theme-color-meta';
export * from './use-theme-value';

View File

@@ -0,0 +1,45 @@
import { useLayoutEffect } from 'react';
import { useThemeValueV1, useThemeValueV2 } from './use-theme-value';
let meta: HTMLMetaElement | null = null;
function getMeta() {
if (meta) return meta;
const exists = document.querySelector('meta[name="theme-color"]');
if (exists) {
meta = exists as HTMLMetaElement;
return meta;
}
// create and append meta
meta = document.createElement('meta');
meta.name = 'theme-color';
document.head.append(meta);
return meta;
}
export const useThemeColorMeta = (color: string) => {
useLayoutEffect(() => {
const meta = getMeta();
const old = meta.content;
meta.content = color;
return () => {
meta.content = old;
};
}, [color]);
};
export const useThemeColorV1 = (
...args: Parameters<typeof useThemeValueV1>
) => {
useThemeColorMeta(useThemeValueV1(...args));
};
export const useThemeColorV2 = (
...args: Parameters<typeof useThemeValueV2>
) => {
useThemeColorMeta(useThemeValueV2(...args));
};

View File

@@ -0,0 +1,19 @@
import { type AffineTheme, darkTheme, lightTheme } from '@toeverything/theme';
import {
type AffineThemeKeyV2,
darkThemeV2,
lightThemeV2,
} from '@toeverything/theme/v2';
import { useTheme } from 'next-themes';
export const useThemeValueV2 = (key: AffineThemeKeyV2) => {
const { resolvedTheme } = useTheme();
return resolvedTheme === 'dark' ? darkThemeV2[key] : lightThemeV2[key];
};
export const useThemeValueV1 = (key: keyof Omit<AffineTheme, 'editorMode'>) => {
const { resolvedTheme } = useTheme();
return resolvedTheme === 'dark' ? darkTheme[key] : lightTheme[key];
};