diff --git a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts index 05a034a22d..2ead86c53c 100644 --- a/frontend/appflowy_web_app/src/application/database-yjs/selector.ts +++ b/frontend/appflowy_web_app/src/application/database-yjs/selector.ts @@ -1,5 +1,5 @@ import { - FieldId, + FieldId, RowCoverType, SortId, YDatabase, YDatabaseField, YDatabaseMetas, YDatabaseRow, @@ -641,7 +641,10 @@ export function usePrimaryFieldId () { export interface RowMeta { documentId: string; - cover: string; + cover: { + data: string, + cover_type: RowCoverType, + } | null; icon: string; isEmptyDocument: boolean; } @@ -691,10 +694,10 @@ export const useRowMetaSelector = (rowId: string) => { const metaJson = yMeta.toJSON(); const icon = metaJson[iconKey]; - let cover = ''; + let cover = null; try { - cover = metaJson[coverKey] ? JSON.parse(metaJson[coverKey])?.url : ''; + cover = metaJson[coverKey] ? JSON.parse(metaJson[coverKey]) : null; } catch (e) { // do nothing } diff --git a/frontend/appflowy_web_app/src/application/types.ts b/frontend/appflowy_web_app/src/application/types.ts index 76ef8a84f2..e54483894e 100644 --- a/frontend/appflowy_web_app/src/application/types.ts +++ b/frontend/appflowy_web_app/src/application/types.ts @@ -830,6 +830,13 @@ export enum CoverType { None = 'none', } +export enum RowCoverType { + ColorCover = 0, + FileCover = 1, + AssetCover = 2, + GradientCover = 3, +} + export enum UIVariant { Publish = 'publish', App = 'app', diff --git a/frontend/appflowy_web_app/src/assets/date.svg b/frontend/appflowy_web_app/src/assets/date.svg index a814058d97..d868f54a4c 100644 --- a/frontend/appflowy_web_app/src/assets/date.svg +++ b/frontend/appflowy_web_app/src/assets/date.svg @@ -1,14 +1,9 @@ - - - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/frontend/appflowy_web_app/src/assets/reminder_clock.svg b/frontend/appflowy_web_app/src/assets/reminder_clock.svg new file mode 100644 index 0000000000..660d3863de --- /dev/null +++ b/frontend/appflowy_web_app/src/assets/reminder_clock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_web_app/src/components/_shared/image-render/ImageRender.tsx b/frontend/appflowy_web_app/src/components/_shared/image-render/ImageRender.tsx index 4cd2aafa6f..55321884df 100644 --- a/frontend/appflowy_web_app/src/components/_shared/image-render/ImageRender.tsx +++ b/frontend/appflowy_web_app/src/components/_shared/image-render/ImageRender.tsx @@ -13,6 +13,7 @@ export function ImageRender({ src, ...props }: ImageRenderProps) { const [loading, setLoading] = useState(true); const [hasError, setHasError] = useState(false); + console.log('ImageRender', src); return ( <> {hasError ? ( diff --git a/frontend/appflowy_web_app/src/components/database/components/board/card/Card.tsx b/frontend/appflowy_web_app/src/components/database/components/board/card/Card.tsx index 783912b3b9..3c2f662b34 100644 --- a/frontend/appflowy_web_app/src/components/database/components/board/card/Card.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/board/card/Card.tsx @@ -1,6 +1,9 @@ -import { DatabaseContext, useFieldsSelector, useRowMetaSelector } from '@/application/database-yjs'; +import { DatabaseContext, RowMeta, useFieldsSelector, useRowMetaSelector } from '@/application/database-yjs'; import CardField from '@/components/database/components/field/CardField'; -import React, { memo, useContext, useEffect, useMemo } from 'react'; +import React, { memo, useCallback, useContext, useEffect, useMemo } from 'react'; +import { RowCoverType } from '@/application/types'; +import { renderColor } from '@/utils/color'; +import ImageRender from '@/components/_shared/image-render/ImageRender'; export interface CardProps { groupFieldId: string; @@ -45,6 +48,41 @@ export const Card = memo(({ groupFieldId, rowId, onResize, isDragging }: CardPro return classList.join(' '); }, [navigateToRow]); + + const renderCoverImage = useCallback((cover: RowMeta["cover"]) => { + if (!cover) return null; + + if (cover.cover_type === RowCoverType.GradientCover || cover.cover_type === RowCoverType.ColorCover) { + return
; + } + + let url: string | undefined = cover.data; + + if (cover.cover_type === RowCoverType.AssetCover) { + url = { + 1: '/covers/m_cover_image_1.png', + 2: '/covers/m_cover_image_2.png', + 3: '/covers/m_cover_image_3.png', + 4: '/covers/m_cover_image_4.png', + 5: '/covers/m_cover_image_5.png', + 6: '/covers/m_cover_image_6.png', + }[Number(cover.data)] + } + + if (!url) return null; + + return ( + <> + + + ); + }, []); + return (
{ @@ -60,10 +98,7 @@ export const Card = memo(({ groupFieldId, rowId, onResize, isDragging }: CardPro
- + {renderCoverImage(cover)}
)}
diff --git a/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx b/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx index 853eacf435..4ff3163c44 100644 --- a/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx +++ b/frontend/appflowy_web_app/src/components/database/components/header/DatabaseRowHeader.tsx @@ -1,8 +1,10 @@ -import { useCellSelector, usePrimaryFieldId, useRowMetaSelector } from '@/application/database-yjs'; -import { AppendBreadcrumb, ViewIconType, ViewLayout } from '@/application/types'; +import { RowMeta, useCellSelector, usePrimaryFieldId, useRowMetaSelector } from '@/application/database-yjs'; +import { AppendBreadcrumb, RowCoverType, ViewIconType, ViewLayout } from '@/application/types'; import Title from '@/components/database/components/header/Title'; import { getScrollParent } from '@/components/global-comment/utils'; -import React, { useEffect } from 'react'; +import React, { useCallback, useEffect } from 'react'; +import { renderColor } from '@/utils/color'; +import ImageRender from '@/components/_shared/image-render/ImageRender'; function DatabaseRowHeader ({ rowId, appendBreadcrumb }: { rowId: string; appendBreadcrumb?: AppendBreadcrumb }) { const fieldId = usePrimaryFieldId() || ''; @@ -13,6 +15,40 @@ function DatabaseRowHeader ({ rowId, appendBreadcrumb }: { rowId: string; append const meta = useRowMetaSelector(rowId); const cover = meta?.cover; + const renderCoverImage = useCallback((cover: RowMeta["cover"]) => { + if (!cover) return null; + + if (cover.cover_type === RowCoverType.GradientCover || cover.cover_type === RowCoverType.ColorCover) { + return
; + } + + let url: string | undefined = cover.data; + + if (cover.cover_type === RowCoverType.AssetCover) { + url = { + 1: '/covers/m_cover_image_1.png', + 2: '/covers/m_cover_image_2.png', + 3: '/covers/m_cover_image_3.png', + 4: '/covers/m_cover_image_4.png', + 5: '/covers/m_cover_image_5.png', + 6: '/covers/m_cover_image_6.png', + }[Number(cover.data)] + } + + if (!url) return null; + + return ( + <> + + + ); + }, []); + const cell = useCellSelector({ rowId, fieldId, @@ -63,12 +99,16 @@ function DatabaseRowHeader ({ rowId, appendBreadcrumb }: { rowId: string; append return
- {cover && {cell?.data} + {cover &&
+ {renderCoverImage(cover)} +
}
- + <Title icon={meta?.icon} name={cell?.data as string}/> </div>; } diff --git a/frontend/appflowy_web_app/src/components/editor/components/blocks/callout/CalloutIcon.tsx b/frontend/appflowy_web_app/src/components/editor/components/blocks/callout/CalloutIcon.tsx index 11fef2d45a..ef66eba370 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/blocks/callout/CalloutIcon.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/blocks/callout/CalloutIcon.tsx @@ -6,8 +6,8 @@ function CalloutIcon({ node }: { node: CalloutNode }) { return ( <> - <span contentEditable={false} ref={ref} className={`icon flex h-8 w-8 items-center p-1`}> - {node.data.icon} + <span contentEditable={false} ref={ref} className={`icon flex h-10 w-8 items-center p-1`}> + {node.data.icon || `📌`} </span> </> ); diff --git a/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionDate.tsx b/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionDate.tsx index 2fdb25db9e..95b2adbe52 100644 --- a/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionDate.tsx +++ b/frontend/appflowy_web_app/src/components/editor/components/leaf/mention/MentionDate.tsx @@ -1,7 +1,7 @@ import { renderDate } from '@/utils/time'; import React, { useMemo } from 'react'; import { ReactComponent as DateSvg } from '@/assets/date.svg'; -import { ReactComponent as ReminderSvg } from '@/assets/clock_alarm.svg'; +import { ReactComponent as ReminderSvg } from '@/assets/reminder_clock.svg'; function MentionDate ({ date, reminder }: { date: string; reminder?: { id: string; option: string } }) { const dateFormat = useMemo(() => { @@ -9,10 +9,12 @@ function MentionDate ({ date, reminder }: { date: string; reminder?: { id: strin }, [date]); return ( - <span className={'mention-inline'}> - {reminder ? <ReminderSvg className={'mention-icon'} /> : <DateSvg className={'mention-icon'} />} + <span className={'mention-inline opacity-70'} style={{ + color: reminder ? 'var(--fill-default)' : 'var(--text-title)', + }}> + <span className={'mention-content mr-[1.5em] ml-0'}><span>@</span>{dateFormat}</span> + {reminder ? <ReminderSvg className={'mention-icon right-1'} /> : <DateSvg className={'mention-icon right-1'} />} - <span className={'mention-content'}>{dateFormat}</span> </span> ); }