fix: workspace avatar url won't update (#1817)

This commit is contained in:
Himself65
2023-04-04 12:46:33 -05:00
committed by GitHub
parent 37169ae37d
commit 89f53190db
18 changed files with 1189 additions and 102 deletions

View File

@@ -2,6 +2,7 @@ import type { StorybookConfig } from '@storybook/react-vite';
import { fileURLToPath } from 'node:url';
import { mergeConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
export default {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
@@ -11,6 +12,7 @@ export default {
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-storysource',
'@storybook/addon-coverage',
'storybook-dark-mode',
],
framework: {
@@ -19,6 +21,7 @@ export default {
async viteFinal(config, { configType }) {
return mergeConfig(config, {
plugins: [
vanillaExtractPlugin(),
tsconfigPaths({
root: fileURLToPath(new URL('../../../', import.meta.url)),
}),

View File

@@ -30,6 +30,7 @@
"@mui/icons-material": "^5.11.11",
"@mui/material": "^5.11.15",
"@toeverything/hooks": "workspace:*",
"clsx": "^1.2.1",
"lit": "^2.7.0",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
@@ -39,6 +40,7 @@
},
"devDependencies": {
"@storybook/addon-actions": "^7.0.2",
"@storybook/addon-coverage": "^0.0.8",
"@storybook/addon-essentials": "^7.0.2",
"@storybook/addon-interactions": "^7.0.2",
"@storybook/addon-links": "^7.0.2",
@@ -53,8 +55,11 @@
"@types/react": "^18.0.31",
"@types/react-dnd": "^3.0.2",
"@types/react-dom": "18.0.11",
"@vanilla-extract/css": "^1.11.0",
"@vitejs/plugin-react": "^3.1.0",
"concurrently": "^8.0.1",
"jest-mock": "^29.5.0",
"serve": "^14.2.0",
"storybook": "^7.0.2",
"storybook-dark-mode": "^3.0.0",
"typescript": "^5.0.3",

View File

@@ -51,12 +51,6 @@ const Template: StoryFn<EditorProps> = (args: EditorProps) => {
};
export const Empty = Template.bind({});
Empty.play = async ({ canvasElement }) => {
await new Promise<void>(resolve => {
document.addEventListener('blocksuite:ready', () => resolve(), {
once: true,
});
});
const editorContainer = canvasElement.querySelector(
'[data-testid="editor-test-page0"]'
) as HTMLDivElement;

View File

@@ -0,0 +1,19 @@
import { style } from '@vanilla-extract/css';
export const avatarStyle = style({
color: '#fff',
borderRadius: '50%',
overflow: 'hidden',
display: 'inline-block',
verticalAlign: 'middle',
});
export const avatarTextStyle = style({
border: '1px solid #fff',
color: '#fff',
borderRadius: '50%',
display: 'inline-flex',
lineHeight: '1',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
});

View File

@@ -1,9 +1,12 @@
import type { AffineWorkspace, LocalWorkspace } from '@affine/workspace/type';
import type { Workspace } from '@blocksuite/store';
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-blocksuite-workspace-avatar-url';
import clsx from 'clsx';
import type React from 'react';
import { memo } from 'react';
import { avatarStyle, avatarTextStyle } from './index.css';
function stringToColour(str: string) {
str = str || 'affine';
let colour = '#';
@@ -29,13 +32,12 @@ interface AvatarProps {
size: number;
name: string;
avatar_url: string;
style?: React.CSSProperties;
className?: string;
}
export const Avatar: React.FC<AvatarProps> = memo<AvatarProps>(function Avatar({
size: _size,
avatar_url,
style,
name,
...props
}) {
@@ -47,20 +49,16 @@ export const Avatar: React.FC<AvatarProps> = memo<AvatarProps>(function Avatar({
{avatar_url ? (
<div
{...props}
className={clsx(avatarStyle, props.className)}
style={{
...style,
width: sizeStr,
height: sizeStr,
color: '#fff',
borderRadius: '50%',
overflow: 'hidden',
display: 'inline-block',
verticalAlign: 'middle',
}}
>
<picture>
<img
style={{ width: sizeStr, height: sizeStr }}
width={size}
height={size}
src={avatar_url}
alt=""
referrerPolicy="no-referrer"
@@ -70,20 +68,12 @@ export const Avatar: React.FC<AvatarProps> = memo<AvatarProps>(function Avatar({
) : (
<div
{...props}
className={avatarTextStyle}
style={{
...style,
width: sizeStr,
height: sizeStr,
border: '1px solid #fff',
color: '#fff',
fontSize: Math.ceil(0.5 * size) + 'px',
background: stringToColour(name || 'AFFiNE'),
borderRadius: '50%',
display: 'inline-flex',
lineHeight: '1',
justifyContent: 'center',
alignItems: 'center',
userSelect: 'none',
}}
>
{(name || 'AFFiNE').substring(0, 1)}
@@ -93,14 +83,14 @@ export const Avatar: React.FC<AvatarProps> = memo<AvatarProps>(function Avatar({
);
});
export type WorkspaceUnitAvatarProps = {
export type WorkspaceAvatarProps = {
size?: number;
workspace: LocalWorkspace | AffineWorkspace | null;
style?: React.CSSProperties;
className?: string;
};
export type BlockSuiteWorkspaceAvatar = Omit<
WorkspaceUnitAvatarProps,
WorkspaceAvatarProps,
'workspace'
> & {
workspace: Workspace;
@@ -109,7 +99,6 @@ export type BlockSuiteWorkspaceAvatar = Omit<
export const BlockSuiteWorkspaceAvatar: React.FC<BlockSuiteWorkspaceAvatar> = ({
size = 20,
workspace,
style,
...props
}) => {
const [avatar] = useBlockSuiteWorkspaceAvatarUrl(workspace);
@@ -120,15 +109,13 @@ export const BlockSuiteWorkspaceAvatar: React.FC<BlockSuiteWorkspaceAvatar> = ({
size={size}
name={workspace.meta.name ?? 'Untitled'}
avatar_url={avatar ?? ''}
style={style}
/>
);
};
export const WorkspaceAvatar: React.FC<WorkspaceUnitAvatarProps> = ({
export const WorkspaceAvatar: React.FC<WorkspaceAvatarProps> = ({
size = 20,
workspace,
style,
...props
}) => {
if (workspace && 'blockSuiteWorkspace' in workspace) {
@@ -137,11 +124,8 @@ export const WorkspaceAvatar: React.FC<WorkspaceUnitAvatarProps> = ({
{...props}
size={size}
workspace={workspace.blockSuiteWorkspace}
style={style}
/>
);
}
return (
<Avatar {...props} size={size} name="UNKNOWN" avatar_url="" style={style} />
);
return <Avatar {...props} size={size} name="UNKNOWN" avatar_url="" />;
};

View File

@@ -2,7 +2,7 @@ import { WorkspaceFlavour } from '@affine/workspace/type';
import { Workspace } from '@blocksuite/store';
import type { Meta, StoryFn } from '@storybook/react';
import type { WorkspaceUnitAvatarProps } from '../components/workspace-avatar';
import type { WorkspaceAvatarProps } from '../components/workspace-avatar';
import { WorkspaceAvatar } from '../components/workspace-avatar';
export default {
@@ -17,30 +17,63 @@ export default {
},
},
},
} satisfies Meta<WorkspaceUnitAvatarProps>;
} satisfies Meta<WorkspaceAvatarProps>;
const blockSuiteWorkspace = new Workspace({
const basicBlockSuiteWorkspace = new Workspace({
id: 'blocksuite-local',
blobOptionsGetter: (_: string) => undefined,
});
blockSuiteWorkspace.meta.setName('Hello World');
basicBlockSuiteWorkspace.meta.setName('Hello World');
export const Basic: StoryFn<WorkspaceUnitAvatarProps> = props => {
export const Basic: StoryFn<WorkspaceAvatarProps> = props => {
return (
<div>
<WorkspaceAvatar
{...props}
workspace={{
flavour: WorkspaceFlavour.LOCAL,
id: 'local',
blockSuiteWorkspace,
providers: [],
}}
/>
</div>
<WorkspaceAvatar
{...props}
workspace={{
flavour: WorkspaceFlavour.LOCAL,
id: 'local',
blockSuiteWorkspace: basicBlockSuiteWorkspace,
providers: [],
}}
/>
);
};
Basic.args = {
size: 40,
};
const avatarBlockSuiteWorkspace = new Workspace({
id: 'blocksuite-local',
blobOptionsGetter: (_: string) => undefined,
});
avatarBlockSuiteWorkspace.meta.setName('Hello World');
avatarBlockSuiteWorkspace.blobs.then(async blobs => {
if (blobs) {
const buffer = await (
await fetch(new URL('@affine-test/fixtures/smile.png', import.meta.url))
).arrayBuffer();
const id = await blobs.set(new Blob([buffer], { type: 'image/png' }));
avatarBlockSuiteWorkspace.meta.setAvatar(id);
}
});
export const BlobExample: StoryFn<WorkspaceAvatarProps> = props => {
return (
<WorkspaceAvatar
{...props}
workspace={{
flavour: WorkspaceFlavour.LOCAL,
id: 'local',
blockSuiteWorkspace: avatarBlockSuiteWorkspace,
providers: [],
}}
/>
);
};
BlobExample.args = {
size: 40,
};