fix(core): optimize sidebar workspace card and avatar (#6324)
- adjust avatar size - unlogged avatar dark-mode - fix Tooltip console error - optimize syncing status animation
This commit is contained in:
@@ -192,19 +192,32 @@ const useSyncEngineSyncProgress = () => {
|
|||||||
),
|
),
|
||||||
active:
|
active:
|
||||||
currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD &&
|
currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD &&
|
||||||
(syncing || retrying || isOverCapacity),
|
((syncing && progress !== undefined) || isOverCapacity || !isOnline),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const WorkspaceInfo = ({ name }: { name: string }) => {
|
const WorkspaceInfo = ({ name }: { name: string }) => {
|
||||||
const { message, icon, active } = useSyncEngineSyncProgress();
|
const { message, active } = useSyncEngineSyncProgress();
|
||||||
const currentWorkspace = useService(Workspace);
|
const currentWorkspace = useService(Workspace);
|
||||||
const isCloud = currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD;
|
const isCloud = currentWorkspace.flavour === WorkspaceFlavour.AFFINE_CLOUD;
|
||||||
|
const { progress } = useDocEngineStatus();
|
||||||
|
|
||||||
// to make sure that animation will play first time
|
// to make sure that animation will play first time
|
||||||
const [delayActive, setDelayActive] = useState(false);
|
const [delayActive, setDelayActive] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDelayActive(active);
|
const delayOpen = 300;
|
||||||
|
const delayClose = 200;
|
||||||
|
let timer: ReturnType<typeof setTimeout>;
|
||||||
|
if (active) {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
setDelayActive(active);
|
||||||
|
}, delayOpen);
|
||||||
|
} else {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
setDelayActive(active);
|
||||||
|
}, delayClose);
|
||||||
|
}
|
||||||
|
return () => clearTimeout(timer);
|
||||||
}, [active]);
|
}, [active]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -221,9 +234,11 @@ const WorkspaceInfo = ({ name }: { name: string }) => {
|
|||||||
|
|
||||||
{/* when syncing/offline/... */}
|
{/* when syncing/offline/... */}
|
||||||
<div className={styles.workspaceInfo} data-type="events">
|
<div className={styles.workspaceInfo} data-type="events">
|
||||||
<div className={styles.workspaceActiveStatus}>
|
<Tooltip content={message}>
|
||||||
<Tooltip content={message}>{icon}</Tooltip>
|
<div className={styles.workspaceActiveStatus}>
|
||||||
</div>
|
<SyncingWorkspaceStatus progress={progress} />
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { globalStyle, style } from '@vanilla-extract/css';
|
|||||||
const wsSlideAnim = {
|
const wsSlideAnim = {
|
||||||
ease: 'cubic-bezier(.45,.21,0,1)',
|
ease: 'cubic-bezier(.45,.21,0,1)',
|
||||||
duration: '0.5s',
|
duration: '0.5s',
|
||||||
delay: '0.23s',
|
delay: '0s',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const container = style({
|
export const container = style({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { style } from '@vanilla-extract/css';
|
import { globalStyle, style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
export const workspaceAndUserWrapper = style({
|
export const workspaceAndUserWrapper = style({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -14,6 +14,12 @@ export const workspaceWrapper = style({
|
|||||||
|
|
||||||
export const userInfoWrapper = style({
|
export const userInfoWrapper = style({
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
width: 28,
|
width: 'auto',
|
||||||
height: 28,
|
height: 'auto',
|
||||||
|
padding: '4px 0',
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
globalStyle(`button.${userInfoWrapper} > span`, {
|
||||||
|
lineHeight: 0,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
import { memo } from 'react';
|
||||||
|
|
||||||
|
export const UnknownUserIcon = memo(
|
||||||
|
({ width = 20, height = 20 }: { width?: number; height?: number }) => {
|
||||||
|
const svgRaw = `<svg width="${width}" height="${height}" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g clip-path="url(#clip0_19485_742)">
|
<g clip-path="url(#clip0_19485_742)">
|
||||||
<rect width="20" height="20" rx="10" fill="currentColor" fill-opacity="0.1" />
|
<rect width="20" height="20" rx="10" fill="currentColor" fill-opacity="0.1" />
|
||||||
<path
|
<path
|
||||||
@@ -13,5 +17,9 @@
|
|||||||
<rect width="20" height="20" rx="10" fill="white" />
|
<rect width="20" height="20" rx="10" fill="white" />
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>`;
|
||||||
|
|
||||||
|
return <div dangerouslySetInnerHTML={{ __html: svgRaw }} />;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
UnknownUserIcon.displayName = 'UnknownUserIcon';
|
||||||
|
Before Width: | Height: | Size: 892 B After Width: | Height: | Size: 1.2 KiB |
@@ -18,11 +18,11 @@ import {
|
|||||||
} from '@affine/core/hooks/affine/use-current-user';
|
} from '@affine/core/hooks/affine/use-current-user';
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import { AccountIcon, SignOutIcon } from '@blocksuite/icons';
|
import { AccountIcon, SignOutIcon } from '@blocksuite/icons';
|
||||||
import { cssVar } from '@toeverything/theme';
|
|
||||||
import { useSetAtom } from 'jotai';
|
import { useSetAtom } from 'jotai';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import * as styles from './index.css';
|
import * as styles from './index.css';
|
||||||
|
import { UnknownUserIcon } from './unknow-user';
|
||||||
|
|
||||||
export const UserInfo = () => {
|
export const UserInfo = () => {
|
||||||
const { status } = useSession();
|
const { status } = useSession();
|
||||||
@@ -39,7 +39,7 @@ const AuthorizedUserInfo = () => {
|
|||||||
type="plain"
|
type="plain"
|
||||||
className={styles.userInfoWrapper}
|
className={styles.userInfoWrapper}
|
||||||
>
|
>
|
||||||
<Avatar size={20} name={user.name} url={user.avatarUrl} />
|
<Avatar size={24} name={user.name} url={user.avatarUrl} />
|
||||||
</Button>
|
</Button>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
@@ -61,11 +61,7 @@ const UnauthorizedUserInfo = () => {
|
|||||||
type="plain"
|
type="plain"
|
||||||
className={styles.userInfoWrapper}
|
className={styles.userInfoWrapper}
|
||||||
>
|
>
|
||||||
<Avatar
|
<UnknownUserIcon width={24} height={24} />
|
||||||
style={{ color: cssVar('black') }}
|
|
||||||
size={20}
|
|
||||||
url={'/imgs/unknown-user.svg'}
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user