mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
fix: shaky header (#3727)
This commit is contained in:
@@ -34,7 +34,6 @@
|
|||||||
"@mui/material": "^5.14.4",
|
"@mui/material": "^5.14.4",
|
||||||
"@react-hookz/web": "^23.1.0",
|
"@react-hookz/web": "^23.1.0",
|
||||||
"@toeverything/components": "^0.0.10",
|
"@toeverything/components": "^0.0.10",
|
||||||
"@types/lodash.throttle": "^4.1.7",
|
|
||||||
"async-call-rpc": "^6.3.1",
|
"async-call-rpc": "^6.3.1",
|
||||||
"cmdk": "^0.2.0",
|
"cmdk": "^0.2.0",
|
||||||
"css-spring": "^4.1.0",
|
"css-spring": "^4.1.0",
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
"jotai": "^2.3.1",
|
"jotai": "^2.3.1",
|
||||||
"jotai-devtools": "^0.6.1",
|
"jotai-devtools": "^0.6.1",
|
||||||
"lit": "^2.8.0",
|
"lit": "^2.8.0",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lottie-web": "^5.12.2",
|
"lottie-web": "^5.12.2",
|
||||||
"mini-css-extract-plugin": "^2.7.6",
|
"mini-css-extract-plugin": "^2.7.6",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
@@ -67,6 +66,7 @@
|
|||||||
"@sentry/webpack-plugin": "^2.6.2",
|
"@sentry/webpack-plugin": "^2.6.2",
|
||||||
"@svgr/webpack": "^8.0.1",
|
"@svgr/webpack": "^8.0.1",
|
||||||
"@swc/core": "^1.3.76",
|
"@swc/core": "^1.3.76",
|
||||||
|
"@types/lodash.debounce": "^4.0.7",
|
||||||
"@types/webpack-env": "^1.18.1",
|
"@types/webpack-env": "^1.18.1",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
"css-loader": "^6.8.1",
|
"css-loader": "^6.8.1",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
import { isDesktop } from '@affine/env/constant';
|
import { isDesktop } from '@affine/env/constant';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import throttle from 'lodash.throttle';
|
import debounce from 'lodash.debounce';
|
||||||
import type { MutableRefObject, ReactNode } from 'react';
|
import type { MutableRefObject, ReactNode } from 'react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
@@ -22,37 +22,52 @@ interface HeaderPros {
|
|||||||
|
|
||||||
const useIsTinyScreen = ({
|
const useIsTinyScreen = ({
|
||||||
mainContainer,
|
mainContainer,
|
||||||
leftDoms,
|
leftStatic,
|
||||||
|
leftSlot,
|
||||||
centerDom,
|
centerDom,
|
||||||
rightDoms,
|
rightStatic,
|
||||||
|
rightSlot,
|
||||||
}: {
|
}: {
|
||||||
mainContainer: HTMLElement;
|
mainContainer: HTMLElement;
|
||||||
leftDoms: MutableRefObject<HTMLElement | null>[];
|
leftStatic: MutableRefObject<HTMLElement | null>;
|
||||||
|
leftSlot: MutableRefObject<HTMLElement | null>[];
|
||||||
centerDom: MutableRefObject<HTMLElement | null>;
|
centerDom: MutableRefObject<HTMLElement | null>;
|
||||||
rightDoms: MutableRefObject<HTMLElement | null>[];
|
rightStatic: MutableRefObject<HTMLElement | null>;
|
||||||
|
rightSlot: MutableRefObject<HTMLElement | null>[];
|
||||||
}) => {
|
}) => {
|
||||||
const [isTinyScreen, setIsTinyScreen] = useState(false);
|
const [isTinyScreen, setIsTinyScreen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleResize = throttle(() => {
|
const handleResize = debounce(() => {
|
||||||
if (!centerDom.current) {
|
if (!centerDom.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const leftTotalWidth = leftDoms.reduce((accWidth, dom) => {
|
const leftStaticWidth = leftStatic.current?.clientWidth || 0;
|
||||||
|
const leftSlotWidth = leftSlot.reduce((accWidth, dom) => {
|
||||||
return accWidth + (dom.current?.clientWidth || 0);
|
return accWidth + (dom.current?.clientWidth || 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
const rightTotalWidth = rightDoms.reduce((accWidth, dom) => {
|
const rightStaticWidth = rightStatic.current?.clientWidth || 0;
|
||||||
|
|
||||||
|
const rightSlotWidth = rightSlot.reduce((accWidth, dom) => {
|
||||||
return accWidth + (dom.current?.clientWidth || 0);
|
return accWidth + (dom.current?.clientWidth || 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
if (!leftSlotWidth && !rightSlotWidth) {
|
||||||
|
if (isTinyScreen) {
|
||||||
|
setIsTinyScreen(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const containerRect = mainContainer.getBoundingClientRect();
|
const containerRect = mainContainer.getBoundingClientRect();
|
||||||
const centerRect = centerDom.current.getBoundingClientRect();
|
const centerRect = centerDom.current.getBoundingClientRect();
|
||||||
|
|
||||||
const offset = isTinyScreen ? 50 : 0;
|
|
||||||
if (
|
if (
|
||||||
leftTotalWidth + containerRect.left >= centerRect.left - offset ||
|
leftStaticWidth + leftSlotWidth + containerRect.left >=
|
||||||
containerRect.right - centerRect.right <= rightTotalWidth + offset
|
centerRect.left ||
|
||||||
|
containerRect.right - centerRect.right <=
|
||||||
|
rightSlotWidth + rightStaticWidth
|
||||||
) {
|
) {
|
||||||
setIsTinyScreen(true);
|
setIsTinyScreen(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -67,7 +82,19 @@ const useIsTinyScreen = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
resizeObserver.observe(mainContainer);
|
resizeObserver.observe(mainContainer);
|
||||||
}, [centerDom, isTinyScreen, leftDoms, mainContainer, rightDoms]);
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
centerDom,
|
||||||
|
isTinyScreen,
|
||||||
|
leftSlot,
|
||||||
|
leftStatic,
|
||||||
|
mainContainer,
|
||||||
|
rightSlot,
|
||||||
|
rightStatic,
|
||||||
|
]);
|
||||||
|
|
||||||
return isTinyScreen;
|
return isTinyScreen;
|
||||||
};
|
};
|
||||||
@@ -84,9 +111,11 @@ export const Header = ({ left, center, right }: HeaderPros) => {
|
|||||||
|
|
||||||
const isTinyScreen = useIsTinyScreen({
|
const isTinyScreen = useIsTinyScreen({
|
||||||
mainContainer: document.querySelector('.main-container') || document.body,
|
mainContainer: document.querySelector('.main-container') || document.body,
|
||||||
leftDoms: [sidebarSwitchRef, leftSlotRef],
|
leftStatic: sidebarSwitchRef,
|
||||||
|
leftSlot: [leftSlotRef],
|
||||||
centerDom: centerSlotRef,
|
centerDom: centerSlotRef,
|
||||||
rightDoms: [rightSlotRef, windowControlsRef],
|
rightSlot: [rightSlotRef],
|
||||||
|
rightStatic: windowControlsRef,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop;
|
const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop;
|
||||||
@@ -124,7 +153,6 @@ export const Header = ({ left, center, right }: HeaderPros) => {
|
|||||||
className={clsx({
|
className={clsx({
|
||||||
[style.headerCenter]: center,
|
[style.headerCenter]: center,
|
||||||
'is-window': isWindowsDesktop,
|
'is-window': isWindowsDesktop,
|
||||||
'has-min-width': !isTinyScreen,
|
|
||||||
})}
|
})}
|
||||||
ref={centerSlotRef}
|
ref={centerSlotRef}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export const headerCenter = style({
|
|||||||
height: '52px',
|
height: '52px',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
maxWidth: '60%',
|
maxWidth: '60%',
|
||||||
|
minWidth: '300px',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
transform: 'translateX(-50%)',
|
transform: 'translateX(-50%)',
|
||||||
left: '50%',
|
left: '50%',
|
||||||
@@ -56,9 +57,6 @@ export const headerCenter = style({
|
|||||||
'&.is-window': {
|
'&.is-window': {
|
||||||
maxWidth: '50%',
|
maxWidth: '50%',
|
||||||
},
|
},
|
||||||
'&.is-window.has-min-width': {
|
|
||||||
minWidth: '400px',
|
|
||||||
},
|
|
||||||
'&.shadow': {
|
'&.shadow': {
|
||||||
position: 'static',
|
position: 'static',
|
||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
@@ -76,6 +74,7 @@ export const headerSideContainer = style({
|
|||||||
},
|
},
|
||||||
'&.block': {
|
'&.block': {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
|
paddingBottom: '10px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -83,6 +82,8 @@ export const headerSideContainer = style({
|
|||||||
export const windowAppControlsWrapper = style({
|
export const windowAppControlsWrapper = style({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
marginLeft: '20px',
|
marginLeft: '20px',
|
||||||
|
// header padding right
|
||||||
|
transform: 'translateX(16px)',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const windowAppControl = style({
|
export const windowAppControl = style({
|
||||||
@@ -98,7 +99,6 @@ export const windowAppControl = style({
|
|||||||
'&[data-type="close"]': {
|
'&[data-type="close"]': {
|
||||||
width: '56px',
|
width: '56px',
|
||||||
paddingRight: '5px',
|
paddingRight: '5px',
|
||||||
marginRight: '-12px',
|
|
||||||
},
|
},
|
||||||
'&[data-type="close"]:hover': {
|
'&[data-type="close"]:hover': {
|
||||||
background: 'var(--affine-windows-close-button)',
|
background: 'var(--affine-windows-close-button)',
|
||||||
|
|||||||
19
yarn.lock
19
yarn.lock
@@ -247,7 +247,7 @@ __metadata:
|
|||||||
"@svgr/webpack": ^8.0.1
|
"@svgr/webpack": ^8.0.1
|
||||||
"@swc/core": ^1.3.76
|
"@swc/core": ^1.3.76
|
||||||
"@toeverything/components": ^0.0.10
|
"@toeverything/components": ^0.0.10
|
||||||
"@types/lodash.throttle": ^4.1.7
|
"@types/lodash.debounce": ^4.0.7
|
||||||
"@types/webpack-env": ^1.18.1
|
"@types/webpack-env": ^1.18.1
|
||||||
async-call-rpc: ^6.3.1
|
async-call-rpc: ^6.3.1
|
||||||
cmdk: ^0.2.0
|
cmdk: ^0.2.0
|
||||||
@@ -262,7 +262,7 @@ __metadata:
|
|||||||
jotai: ^2.3.1
|
jotai: ^2.3.1
|
||||||
jotai-devtools: ^0.6.1
|
jotai-devtools: ^0.6.1
|
||||||
lit: ^2.8.0
|
lit: ^2.8.0
|
||||||
lodash.throttle: ^4.1.1
|
lodash.debounce: ^4.0.8
|
||||||
lottie-web: ^5.12.2
|
lottie-web: ^5.12.2
|
||||||
mini-css-extract-plugin: ^2.7.6
|
mini-css-extract-plugin: ^2.7.6
|
||||||
next-themes: ^0.2.1
|
next-themes: ^0.2.1
|
||||||
@@ -12043,12 +12043,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/lodash.throttle@npm:^4.1.7":
|
"@types/lodash.debounce@npm:^4.0.7":
|
||||||
version: 4.1.7
|
version: 4.0.7
|
||||||
resolution: "@types/lodash.throttle@npm:4.1.7"
|
resolution: "@types/lodash.debounce@npm:4.0.7"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/lodash": "*"
|
"@types/lodash": "*"
|
||||||
checksum: 6e1b3836488fecbdc537b6ad9b3fe4855c7336b0fa388773cd57d486619f565a48cabc04b28677fd3819be3f2d13d2bb8f9d4428aa5632885c86cb99729bfd69
|
checksum: e873b2d77f89010876baba3437ef826b17221b98948e00b5590828334a481dea1c8f9d28543210e564adc53199584f42c3cb171f8b6c3614fefc0b4e0888679c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -23755,13 +23755,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lodash.throttle@npm:^4.1.1":
|
|
||||||
version: 4.1.1
|
|
||||||
resolution: "lodash.throttle@npm:4.1.1"
|
|
||||||
checksum: 129c0a28cee48b348aef146f638ef8a8b197944d4e9ec26c1890c19d9bf5a5690fe11b655c77a4551268819b32d27f4206343e30c78961f60b561b8608c8c805
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash.truncate@npm:^4.4.2":
|
"lodash.truncate@npm:^4.4.2":
|
||||||
version: 4.4.2
|
version: 4.4.2
|
||||||
resolution: "lodash.truncate@npm:4.4.2"
|
resolution: "lodash.truncate@npm:4.4.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user