// Merge branch 'feat/support-get-encoded-collab-event' of https://github.com/AppFlowy-IO/AppFlowy into feat/support-get-encoded-collab-event

This commit is contained in:
Lucas.Xu 2024-06-28 13:17:16 +08:00
commit eab1519c3e
12 changed files with 89 additions and 74 deletions

View File

@ -0,0 +1,44 @@
import { ViewLayout } from '@/application/collab.type';
import React, { useMemo } from 'react';
import { ReactComponent as BoardSvg } from '@/assets/board.svg';
import { ReactComponent as CalendarSvg } from '@/assets/calendar.svg';
import { ReactComponent as DocumentSvg } from '@/assets/document.svg';
import { ReactComponent as GridSvg } from '@/assets/grid.svg';
export function ViewIcon({ layout, size }: { layout: ViewLayout; size: number | 'small' | 'medium' | 'large' }) {
const iconSize = useMemo(() => {
if (size === 'small') {
return 'h-4 w-4';
}
if (size === 'medium') {
return 'h-6 w-6';
}
if (size === 'large') {
return 'h-8 w-8';
}
return `h-${size} w-${size}`;
}, [size]);
if (layout === ViewLayout.Grid) {
return <GridSvg className={iconSize} />;
}
if (layout === ViewLayout.Board) {
return <BoardSvg className={iconSize} />;
}
if (layout === ViewLayout.Calendar) {
return <CalendarSvg className={iconSize} />;
}
if (layout === ViewLayout.Document) {
return <DocumentSvg className={iconSize} />;
}
return null;
}
export default ViewIcon;

View File

@ -0,0 +1 @@
export * from './ViewIcon';

View File

@ -1,9 +1,6 @@
import { ReactComponent as DocumentSvg } from '$icons/16x/document.svg';
import { ReactComponent as GridSvg } from '$icons/16x/grid.svg';
import { ReactComponent as BoardSvg } from '$icons/16x/board.svg';
import { ReactComponent as CalendarSvg } from '$icons/16x/date.svg';
import { ViewLayout } from '@/application/collab.type';
import { ViewMeta } from '@/application/db/tables/view_metas';
import { ViewIcon } from '@/components/_shared/view-icon';
import { useEditorContext } from '@/components/editor/EditorContext';
import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -33,21 +30,6 @@ function MentionPage({ pageId }: { pageId: string }) {
return meta?.icon;
}, [meta?.icon]);
const defaultIcon = useMemo(() => {
switch (meta?.layout) {
case ViewLayout.Document:
return <DocumentSvg />;
case ViewLayout.Grid:
return <GridSvg />;
case ViewLayout.Board:
return <BoardSvg />;
case ViewLayout.Calendar:
return <CalendarSvg />;
default:
return <DocumentSvg />;
}
}, [meta?.layout]);
const { t } = useTranslation();
return (
@ -62,7 +44,9 @@ function MentionPage({ pageId }: { pageId: string }) {
<span className={'mention-unpublished font-semibold text-text-caption'}>No Access</span>
) : (
<>
<span className={'mention-icon icon'}>{icon?.value || defaultIcon}</span>
<span className={'mention-icon icon'}>
{icon?.value || <ViewIcon layout={meta?.layout || ViewLayout.Document} size={'small'} />}
</span>
<span className={'mention-content'}>{meta?.name || t('menuAppHeader.defaultNewPageName')}</span>
</>

View File

@ -1,42 +1,20 @@
import { ReactComponent as BoardSvg } from '@/assets/board.svg';
import { ReactComponent as CalendarSvg } from '@/assets/calendar.svg';
import { ReactComponent as DocumentSvg } from '@/assets/document.svg';
import { ReactComponent as GridSvg } from '@/assets/grid.svg';
import { ViewLayout } from '@/application/collab.type';
import { usePublishContext } from '@/application/publish';
import { notify } from '@/components/_shared/notify';
import { ViewIcon } from '@/components/_shared/view-icon';
import React from 'react';
import { useTranslation } from 'react-i18next';
export const renderCrumbIcon = (icon: string) => {
if (Number(icon) === ViewLayout.Grid) {
return <GridSvg className={'h-4 w-4'} />;
}
if (Number(icon) === ViewLayout.Board) {
return <BoardSvg className={'h-4 w-4'} />;
}
if (Number(icon) === ViewLayout.Calendar) {
return <CalendarSvg className={'h-4 w-4'} />;
}
if (Number(icon) === ViewLayout.Document) {
return <DocumentSvg className={'h-4 w-4'} />;
}
return icon;
};
export interface Crumb {
viewId: string;
rowId?: string;
name: string;
icon: string;
layout: ViewLayout;
}
function BreadcrumbItem({ crumb, disableClick = false }: { crumb: Crumb; disableClick?: boolean }) {
const { viewId, icon, name } = crumb;
const { viewId, icon, name, layout } = crumb;
const { t } = useTranslation();
const onNavigateToView = usePublishContext()?.toView;
@ -53,7 +31,7 @@ function BreadcrumbItem({ crumb, disableClick = false }: { crumb: Crumb; disable
}
}}
>
<span className={'icon'}>{renderCrumbIcon(icon)}</span>
<span className={'icon'}>{icon || <ViewIcon layout={layout} size={'small'} />}</span>
<span
className={!disableClick ? 'max-w-[250px] truncate hover:text-text-title hover:underline' : 'flex-1 truncate'}
>

View File

@ -36,7 +36,8 @@ export function PublishViewHeader({
return {
viewId: ancestor.view_id,
name: ancestor.name,
icon: icon || String(viewMeta?.layout),
icon: icon,
layout: ancestor.layout,
};
});
}, [viewMeta]);
@ -64,7 +65,7 @@ export function PublishViewHeader({
width: openDrawer ? `calc(100% - ${drawerWidth}px)` : '100%',
transition: 'width 0.2s ease-in-out 0s',
}}
className={'appflowy-top-bar flex h-[64px] px-5'}
className={'appflowy-top-bar flex h-[48px] px-5'}
>
<div className={'flex w-full items-center justify-between gap-2 overflow-hidden'}>
{!openDrawer && (

View File

@ -31,9 +31,9 @@ function OutlineDrawer({ open, width, onClose }: { open: boolean; width: number;
autoFocus
>
<div className={'flex h-full flex-col'}>
<div className={'flex h-[64px] items-center justify-between p-4'}>
<div className={'flex h-[48px] items-center justify-between p-4'}>
<div
className={'flex cursor-pointer items-center text-text-title'}
className={'flex cursor-pointer items-center gap-1 text-text-title'}
onClick={() => {
window.open('https://appflowy.io', '_blank');
}}

View File

@ -1,7 +1,7 @@
import { PublishViewInfo, ViewLayout } from '@/application/collab.type';
import { PublishContext } from '@/application/publish';
import { notify } from '@/components/_shared/notify';
import { renderCrumbIcon } from '@/components/publish/header/BreadcrumbItem';
import { ViewIcon } from '@/components/_shared/view-icon';
import React, { useCallback, useContext } from 'react';
import { ReactComponent as ChevronDownIcon } from '@/assets/chevron_down.svg';
import { useTranslation } from 'react-i18next';
@ -35,40 +35,51 @@ function OutlineItem({ view }: { view: PublishViewInfo }) {
const navigateToView = useContext(PublishContext)?.toView;
const renderItem = (item: PublishViewInfo) => {
const { icon, layout, name, view_id } = item;
const hasChildren = Boolean(item.child_views?.length);
return (
<div className={'flex h-fit w-full flex-col gap-2'}>
<div
style={{
marginLeft: hasChildren ? '0' : '1.125rem',
}}
className={'flex h-fit flex-col gap-2'}
>
<div
className={
'flex w-full items-center rounded-[8px] p-1.5 text-sm hover:bg-content-blue-50 focus:bg-content-blue-50 focus:outline-none'
'flex w-full items-center gap-0.5 rounded-[8px] p-1.5 text-sm hover:bg-content-blue-50 focus:bg-content-blue-50 focus:outline-none'
}
>
{item.child_views?.length ? getIcon() : null}
<div
onClick={async () => {
try {
await navigateToView?.(item.view_id);
await navigateToView?.(view_id);
} catch (e) {
notify.error(t('publish.hasNotBeenPublished'));
}
}}
className={'flex flex-1 cursor-pointer items-center gap-1 overflow-hidden'}
>
<div className={'icon'}>{renderCrumbIcon(item.icon?.value || String(item.layout))}</div>
<div className={'flex-1 truncate'}>{item.name}</div>
<div className={'icon'}>{icon?.value || <ViewIcon layout={layout} size={'small'} />}</div>
<div className={'flex-1 truncate'}>{name}</div>
</div>
</div>
</div>
);
};
const hasChildren = Boolean(view.child_views?.length);
return (
<div className={'flex h-fit w-full flex-col'}>
{renderItem(view)}
<div
className={'ml-9 flex transform flex-col gap-2 transition-all'}
className={'flex transform flex-col gap-2 transition-all'}
style={{
height: isExpanded && view.child_views?.length ? 'auto' : 0,
opacity: isExpanded && view.child_views?.length ? 1 : 0,
marginLeft: hasChildren ? '1.125rem' : '2.25rem',
}}
>
{view.child_views

View File

@ -30,7 +30,7 @@ export function OutlinePopover({
<div
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={'flex h-fit max-h-[500px] w-[268px] flex-col overflow-y-auto p-2'}
className={'flex h-fit max-h-[500px] w-[268px] flex-col overflow-y-auto overflow-x-hidden p-2'}
>
<Outline viewMeta={viewMeta} />
<div
@ -44,22 +44,19 @@ export function OutlinePopover({
>
{Boolean(viewMeta?.child_views?.length) && <Divider className={'w-full'} />}
<div className={'flex w-full items-center justify-center gap-4 text-sm'}>
<div className={'text-text-caption'}>{t('publish.createdWith')}</div>
<div
className={'flex cursor-pointer items-center justify-center text-text-title'}
onClick={() => {
window.open('https://appflowy.io', '_blank');
}}
>
<Logo className={'h-4 w-4'} />
<AppflowyLogo className={'w-20'} />
</div>
<div
onClick={() => {
window.open('https://appflowy.io', '_blank');
}}
className={'flex w-full cursor-pointer items-center justify-center text-sm text-text-title opacity-50'}
>
<Logo className={'h-4 w-4'} />
<AppflowyLogo className={'w-20'} />
</div>
</div>
</div>
);
}, [onMouseEnter, onMouseLeave, t, viewMeta]);
}, [onMouseEnter, onMouseLeave, viewMeta]);
return (
<RichTooltip open={open} onClose={onClose} content={content} placement={placement}>

View File

@ -21,7 +21,6 @@ function SearchInput({ onSearch }: { onSearch: (value: string) => void }) {
return (
<OutlinedInput
autoFocus
spellCheck={false}
startAdornment={
<InputAdornment className={'text-text-caption'} position='start'>

View File

@ -22,7 +22,7 @@ function ViewCover({ coverValue, coverType }: { coverValue?: string; coverType?:
}
return (
<div className={'relative flex h-[198px] w-full max-sm:h-[180px]'}>
<div className={'relative flex h-[208px] w-full max-sm:h-[180px]'}>
{coverType === 'color' && renderCoverColor(coverValue)}
{(coverType === 'custom' || coverType === 'built_in') && renderCoverImage(coverValue)}
</div>

View File

@ -19,7 +19,7 @@
--fill-toolbar: #0F111C;
--fill-selector: #232b38;
--fill-list-active: #3c4557;
--fill-list-hover: #005174;
--fill-list-hover: rgba(255, 255, 255, 0.1);
--content-blue-400: #00bcf0;
--content-blue-300: #52d1f4;
--content-blue-600: #009fd1;

View File

@ -20,7 +20,7 @@
--fill-hover: #52d1f4;
--fill-pressed: #009fd1;
--fill-active: #e0f8ff;
--fill-list-hover: #e0f8ff;
--fill-list-hover: rgba(31, 35, 41, 6%);
--fill-list-active: #f9fafd;
--content-blue-400: #00bcf0;
--content-blue-300: #52d1f4;