Skip to content

Commit 3317454

Browse files
authored
fix: the client removed the data problem caused by iconContent (#32)
1 parent 4882b64 commit 3317454

File tree

4 files changed

+64
-33
lines changed

4 files changed

+64
-33
lines changed

src/components/_shared/view-icon/PageIcon.tsx

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import React, { useMemo } from 'react';
1+
import React, { useEffect, useMemo } from 'react';
22
import { ViewIcon, ViewIconType, ViewLayout } from '@/application/types';
33
import { ReactComponent as BoardSvg } from '@/assets/board.svg';
44
import { ReactComponent as CalendarSvg } from '@/assets/calendar.svg';
55
import { ReactComponent as DocumentSvg } from '@/assets/document.svg';
66
import { ReactComponent as GridSvg } from '@/assets/grid.svg';
77
import { ReactComponent as ChatSvg } from '@/assets/chat_ai.svg';
8-
import { isFlagEmoji } from '@/utils/emoji';
8+
import { getIcon, isFlagEmoji } from '@/utils/emoji';
99
import DOMPurify from 'dompurify';
1010
import { renderColor } from '@/utils/color';
1111

12-
function PageIcon ({
12+
function PageIcon({
1313
view,
1414
className,
1515
iconSize,
@@ -21,9 +21,10 @@ function PageIcon ({
2121
className?: string;
2222
iconSize?: number;
2323
}) {
24+
const [iconContent, setIconContent] = React.useState<string | undefined>(undefined);
2425

2526
const emoji = useMemo(() => {
26-
if (view.icon && view.icon.ty === ViewIconType.Emoji && view.icon.value) {
27+
if(view.icon && view.icon.ty === ViewIconType.Emoji && view.icon.value) {
2728
return view.icon.value;
2829
}
2930

@@ -34,10 +35,26 @@ function PageIcon ({
3435
return emoji ? isFlagEmoji(emoji) : false;
3536
}, [emoji]);
3637

38+
useEffect(() => {
39+
if(view.icon && view.icon.ty === ViewIconType.Icon && view.icon.value) {
40+
try {
41+
const json = JSON.parse(view.icon.value);
42+
const id = `${json.groupName}/${json.iconName}`;
43+
44+
void getIcon(id).then((item) => {
45+
setIconContent(item?.content.replaceAll('black', renderColor(json.color)).replace('<svg', '<svg width="100%" height="100%"'));
46+
});
47+
} catch(e) {
48+
console.error(e, view.icon);
49+
}
50+
} else {
51+
setIconContent(undefined);
52+
}
53+
}, [view.icon]);
54+
3755
const icon = useMemo(() => {
38-
if (view.icon && view.icon.ty === ViewIconType.Icon && view.icon.value) {
39-
const json = JSON.parse(view.icon.value);
40-
const cleanSvg = DOMPurify.sanitize(json.iconContent.replaceAll('black', renderColor(json.color)).replace('<svg', '<svg width="100%" height="100%"'), {
56+
if(iconContent) {
57+
const cleanSvg = DOMPurify.sanitize(iconContent, {
4158
USE_PROFILES: { svg: true, svgFilters: true },
4259
});
4360

@@ -52,19 +69,19 @@ function PageIcon ({
5269
}}
5370
/>;
5471
}
55-
}, [view.icon, iconSize, className]);
72+
}, [iconContent, iconSize, className]);
5673

57-
if (emoji) {
74+
if(emoji) {
5875
return <>
5976
<span className={`${isFlag ? 'icon' : ''} ${className || ''}`}>{emoji}</span>
6077
</>;
6178
}
6279

63-
if (icon) {
80+
if(icon) {
6481
return icon;
6582
}
6683

67-
switch (view.layout) {
84+
switch(view.layout) {
6885
case ViewLayout.AIChat:
6986
return <ChatSvg className={className} />;
7087
case ViewLayout.Grid:

src/components/app/outline/ViewItem.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const popoverProps: Origins = {
2121
},
2222
};
2323

24-
function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpand, onClickView }: {
24+
function ViewItem({ view, width, level = 0, renderExtra, expandIds, toggleExpand, onClickView }: {
2525
view: View;
2626
width: number;
2727
level?: number;
@@ -58,7 +58,7 @@ function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpan
5858
}, [isExpanded, level, toggleExpand, viewId]);
5959

6060
const renderItem = useMemo(() => {
61-
if (!view) return null;
61+
if(!view) return null;
6262
const { layout } = view;
6363

6464
return (
@@ -71,7 +71,7 @@ function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpan
7171
onMouseEnter={() => setHovered(true)}
7272
onMouseLeave={() => setHovered(false)}
7373
onClick={() => {
74-
if (layout === ViewLayout.AIChat) return;
74+
if(layout === ViewLayout.AIChat) return;
7575
onClickView?.(viewId);
7676
}}
7777
className={
@@ -129,7 +129,7 @@ function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpan
129129
}</div>;
130130
}, [toggleExpand, onClickView, isExpanded, expandIds, level, renderExtra, view?.children, width]);
131131

132-
const handleChangeIcon = useCallback(async (icon: { ty: ViewIconType, value: string }) => {
132+
const handleChangeIcon = useCallback(async(icon: { ty: ViewIconType, value: string }) => {
133133

134134
try {
135135
await updatePage?.(view.view_id, {
@@ -140,7 +140,7 @@ function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpan
140140
setIconPopoverAnchorEl(null);
141141

142142
// eslint-disable-next-line
143-
} catch (e: any) {
143+
} catch(e: any) {
144144
notify.error(e);
145145
}
146146
}, [updatePage, view.extra, view.name, view.view_id]);
@@ -169,14 +169,13 @@ function ViewItem ({ view, width, level = 0, renderExtra, expandIds, toggleExpan
169169
}}
170170
popoverProps={popoverProps}
171171
onSelectIcon={(icon) => {
172-
if (icon.ty === ViewIconType.Icon) {
172+
if(icon.ty === ViewIconType.Icon) {
173173
void handleChangeIcon({
174174
ty: ViewIconType.Icon,
175175
value: JSON.stringify({
176176
color: icon.color,
177177
groupName: icon.value.split('/')[0],
178178
iconName: icon.value.split('/')[1],
179-
iconContent: icon.content,
180179
}),
181180
});
182181
return;

src/components/editor/components/blocks/callout/CalloutIcon.tsx

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ import { ViewIconType } from '@/application/types';
44
import ChangeIconPopover from '@/components/_shared/view-icon/ChangeIconPopover';
55
import { CalloutNode } from '@/components/editor/editor.type';
66
import { renderColor } from '@/utils/color';
7-
import { isFlagEmoji } from '@/utils/emoji';
7+
import { getIcon, isFlagEmoji } from '@/utils/emoji';
88
import DOMPurify from 'dompurify';
9-
import React, { useCallback, useMemo, useRef } from 'react';
9+
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
1010
import { useReadOnly, useSlateStatic } from 'slate-react';
1111
import { Element } from 'slate';
1212

13-
function CalloutIcon ({ block: node }: { block: CalloutNode; className: string }) {
13+
function CalloutIcon({ block: node }: { block: CalloutNode; className: string }) {
1414
const ref = useRef<HTMLButtonElement>(null);
1515
const editor = useSlateStatic();
1616
const readOnly = useReadOnly() || editor.isElementReadOnly(node as unknown as Element);
1717
const blockId = node.blockId;
18+
const [iconContent, setIconContent] = React.useState<string | undefined>(undefined);
1819

1920
const [open, setOpen] = React.useState(false);
2021
const handleChangeIcon = useCallback((icon: {
@@ -28,12 +29,11 @@ function CalloutIcon ({ block: node }: { block: CalloutNode; className: string }
2829
const iconType = icon.ty === ViewIconType.Icon ? 'icon' : 'emoji';
2930
let value;
3031

31-
if (icon.ty === ViewIconType.Icon) {
32+
if(icon.ty === ViewIconType.Icon) {
3233
value = JSON.stringify({
3334
color: icon.color,
3435
groupName: icon.value.split('/')[0],
3536
iconName: icon.value.split('/')[1],
36-
iconContent: icon.content,
3737
});
3838

3939
} else {
@@ -51,7 +51,7 @@ function CalloutIcon ({ block: node }: { block: CalloutNode; className: string }
5151
const data = node.data;
5252

5353
const emoji = useMemo(() => {
54-
if (data.icon && data.icon_type !== 'icon') {
54+
if(data.icon && data.icon_type !== 'icon') {
5555
return data.icon;
5656
}
5757

@@ -62,10 +62,25 @@ function CalloutIcon ({ block: node }: { block: CalloutNode; className: string }
6262
return emoji ? isFlagEmoji(emoji) : false;
6363
}, [emoji]);
6464

65+
useEffect(() => {
66+
if(data.icon && data.icon_type === 'icon') {
67+
try {
68+
const json = JSON.parse(data.icon);
69+
const id = `${json.groupName}/${json.iconName}`;
70+
71+
void getIcon(id).then((item) => {
72+
setIconContent(item?.content.replaceAll('black', renderColor(json.color)).replace('<svg', '<svg width="100%" height="100%"'));
73+
});
74+
} catch(e) {
75+
console.error(e, data.icon);
76+
}
77+
} else {
78+
setIconContent(undefined);
79+
}
80+
}, [data.icon, data.icon_type]);
6581
const icon = useMemo(() => {
66-
if (data.icon && data.icon_type === 'icon') {
67-
const json = JSON.parse(data.icon);
68-
const cleanSvg = DOMPurify.sanitize(json.iconContent.replaceAll('black', renderColor(json.color)).replace('<svg', '<svg width="100%" height="100%"'), {
82+
if(iconContent) {
83+
const cleanSvg = DOMPurify.sanitize(iconContent, {
6984
USE_PROFILES: { svg: true, svgFilters: true },
7085
});
7186

@@ -78,16 +93,17 @@ function CalloutIcon ({ block: node }: { block: CalloutNode; className: string }
7893
__html: cleanSvg,
7994
}}
8095
/>;
96+
8197
}
8298

8399
return null;
84-
}, [data.icon, data.icon_type]);
100+
}, [iconContent]);
85101

86102
return (
87103
<>
88104
<span
89105
onClick={() => {
90-
if (readOnly) return;
106+
if(readOnly) return;
91107
setOpen(true);
92108
}}
93109
data-testid="callout-icon-button"

src/components/view-meta/AddIconCover.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ function AddIconCover({
4242
onClick={e => {
4343
setIconAnchorEl(e.currentTarget);
4444
}}
45-
startIcon={<AddIcon/>}
45+
startIcon={<AddIcon />}
4646
>{t('document.plugins.cover.addIcon')}</Button>}
4747
{!hasCover && <Button
4848
size={'small'}
4949
color={'inherit'}
5050
onClick={onAddCover}
51-
startIcon={<AddCover/>}
51+
startIcon={<AddCover />}
5252
>{t('document.plugins.cover.addCover')}</Button>}
5353

5454
</div>
@@ -62,14 +62,13 @@ function AddIconCover({
6262
iconEnabled={true}
6363
onSelectIcon={(icon) => {
6464
setIconAnchorEl(null);
65-
if (icon.ty === ViewIconType.Icon) {
65+
if(icon.ty === ViewIconType.Icon) {
6666
onUpdateIcon?.({
6767
ty: ViewIconType.Icon,
6868
value: JSON.stringify({
6969
color: icon.color,
7070
groupName: icon.value.split('/')[0],
7171
iconName: icon.value.split('/')[1],
72-
iconContent: icon.content,
7372
}),
7473
});
7574
return;

0 commit comments

Comments
 (0)