mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 10:45:57 +08:00
Compare commits
94 Commits
v0.26.3
...
v0.12.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea17e86032 | ||
|
|
48cd8999bd | ||
|
|
cdf1d9002e | ||
|
|
79b39f14d2 | ||
|
|
619420cfd1 | ||
|
|
739e914b5f | ||
|
|
5e9739eb3a | ||
|
|
0a89b7f528 | ||
|
|
0a0ee37ac2 | ||
|
|
a143379161 | ||
|
|
8e7dedfe82 | ||
|
|
d25a8547d0 | ||
|
|
4d16229fea | ||
|
|
99371be7e8 | ||
|
|
34ed8dd7a5 | ||
|
|
39b7b671b1 | ||
|
|
207b56d5af | ||
|
|
9e94e7195b | ||
|
|
de951c8779 | ||
|
|
fd37026ca5 | ||
|
|
4fd5812a89 | ||
|
|
d01e987ecc | ||
|
|
d87c218c0b | ||
|
|
a5bf5cc244 | ||
|
|
16bcd6e76b | ||
|
|
2e2ace8472 | ||
|
|
37cff8fe8d | ||
|
|
70ab3b4916 | ||
|
|
f42ba54578 | ||
|
|
a67c8181fc | ||
|
|
613efbded9 | ||
|
|
549419d102 | ||
|
|
21c42f8771 | ||
|
|
9012adda7a | ||
|
|
fb442e9055 | ||
|
|
a231474dd2 | ||
|
|
833b42000b | ||
|
|
7690c48710 | ||
|
|
579828a700 | ||
|
|
746db2ccfc | ||
|
|
eff344a9c1 | ||
|
|
c89ebab596 | ||
|
|
62f4421b7c | ||
|
|
42383dbd29 | ||
|
|
120e7397ba | ||
|
|
24123ad01c | ||
|
|
ad50320391 | ||
|
|
eb21a60dda | ||
|
|
c0e3be2d40 | ||
|
|
09d3b72358 | ||
|
|
246e16c6c0 | ||
|
|
dc279d062b | ||
|
|
47d5f9e1c2 | ||
|
|
a226eb8d5f | ||
|
|
908c4e1a6f | ||
|
|
1d0bcc80a0 | ||
|
|
50010bd824 | ||
|
|
c0ede1326d | ||
|
|
89197bacef | ||
|
|
f97d323ab5 | ||
|
|
2acb219dcc | ||
|
|
992ed89a89 | ||
|
|
d272d7922d | ||
|
|
c1cd1713b9 | ||
|
|
b20e91bee0 | ||
|
|
9a4e5ec8c3 | ||
|
|
2019838ae7 | ||
|
|
30ff25f400 | ||
|
|
e766208c18 | ||
|
|
8742f28148 | ||
|
|
cd291bb60e | ||
|
|
62c0efcfd1 | ||
|
|
87248b3337 | ||
|
|
00c940f7df | ||
|
|
931b459fbd | ||
|
|
51e71f4a0a | ||
|
|
9b631f2328 | ||
|
|
01f481a9b6 | ||
|
|
0177ab5c87 | ||
|
|
4db35d341c | ||
|
|
3c4a803c97 | ||
|
|
05154dc7ca | ||
|
|
c90b477f60 | ||
|
|
6f18ddbe85 | ||
|
|
dde779a71d | ||
|
|
bd9f66fbc7 | ||
|
|
92f1f40bfa | ||
|
|
48dc1049b3 | ||
|
|
9add530370 | ||
|
|
b77460d871 | ||
|
|
42db41776b | ||
|
|
075439c74f | ||
|
|
fc6c553ece | ||
|
|
59cb3d5df1 |
2
.github/deployment/front/Dockerfile
vendored
2
.github/deployment/front/Dockerfile
vendored
@@ -1,6 +1,6 @@
|
|||||||
FROM openresty/openresty:1.21.4.3-0-buster
|
FROM openresty/openresty:1.21.4.3-0-buster
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ./packages/frontend/core/dist/index.html ./dist/index.html
|
COPY ./packages/frontend/core/dist ./dist
|
||||||
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
|
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
|
||||||
COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf
|
COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
|||||||
import { Schema, Workspace } from '@blocksuite/store';
|
import { Schema, Workspace } from '@blocksuite/store';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { initEmptyPage } from '@toeverything/infra/blocksuite';
|
import { initEmptyPage } from '@toeverything/infra/blocksuite';
|
||||||
import { beforeEach, describe, expect, test } from 'vitest';
|
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||||
|
|
||||||
import { useBlockSuitePageMeta } from '../use-block-suite-page-meta';
|
import { useBlockSuitePageMeta } from '../use-block-suite-page-meta';
|
||||||
import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper';
|
import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper';
|
||||||
@@ -17,18 +17,26 @@ let blockSuiteWorkspace: Workspace;
|
|||||||
const schema = new Schema();
|
const schema = new Schema();
|
||||||
schema.register(AffineSchemas).register(__unstableSchemas);
|
schema.register(AffineSchemas).register(__unstableSchemas);
|
||||||
|
|
||||||
|
// todo: this module has some side-effects that will break the tests
|
||||||
|
vi.mock('@affine/workspace-impl', () => ({
|
||||||
|
default: {},
|
||||||
|
}));
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
blockSuiteWorkspace = new Workspace({
|
blockSuiteWorkspace = new Workspace({
|
||||||
id: 'test',
|
id: 'test',
|
||||||
schema,
|
schema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
blockSuiteWorkspace.doc.emit('sync', []);
|
||||||
|
|
||||||
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page0' }));
|
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page0' }));
|
||||||
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' }));
|
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' }));
|
||||||
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' }));
|
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' }));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('useBlockSuiteWorkspaceHelper', () => {
|
describe('useBlockSuiteWorkspaceHelper', () => {
|
||||||
test('should create page', () => {
|
test('should create page', async () => {
|
||||||
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
|
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
|
||||||
const helperHook = renderHook(() =>
|
const helperHook = renderHook(() =>
|
||||||
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace)
|
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace)
|
||||||
@@ -36,6 +44,7 @@ describe('useBlockSuiteWorkspaceHelper', () => {
|
|||||||
const pageMetaHook = renderHook(() =>
|
const pageMetaHook = renderHook(() =>
|
||||||
useBlockSuitePageMeta(blockSuiteWorkspace)
|
useBlockSuitePageMeta(blockSuiteWorkspace)
|
||||||
);
|
);
|
||||||
|
await new Promise(resolve => setTimeout(resolve));
|
||||||
expect(pageMetaHook.result.current.length).toBe(3);
|
expect(pageMetaHook.result.current.length).toBe(3);
|
||||||
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
|
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
|
||||||
const page = helperHook.result.current.createPage('page4');
|
const page = helperHook.result.current.createPage('page4');
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import type { Atom } from 'jotai';
|
|||||||
import { atom, useAtomValue } from 'jotai';
|
import { atom, useAtomValue } from 'jotai';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { useJournalHelper } from './use-journal';
|
||||||
|
|
||||||
const weakMap = new WeakMap<Workspace, Atom<PageMeta[]>>();
|
const weakMap = new WeakMap<Workspace, Atom<PageMeta[]>>();
|
||||||
|
|
||||||
export function useBlockSuitePageMeta(
|
export function useAllBlockSuitePageMeta(
|
||||||
blockSuiteWorkspace: Workspace
|
blockSuiteWorkspace: Workspace
|
||||||
): PageMeta[] {
|
): PageMeta[] {
|
||||||
if (!weakMap.has(blockSuiteWorkspace)) {
|
if (!weakMap.has(blockSuiteWorkspace)) {
|
||||||
@@ -26,6 +28,18 @@ export function useBlockSuitePageMeta(
|
|||||||
return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<PageMeta[]>);
|
return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<PageMeta[]>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useBlockSuitePageMeta(blocksuiteWorkspace: Workspace) {
|
||||||
|
const pageMetas = useAllBlockSuitePageMeta(blocksuiteWorkspace);
|
||||||
|
const { isPageJournal } = useJournalHelper(blocksuiteWorkspace);
|
||||||
|
return useMemo(
|
||||||
|
() =>
|
||||||
|
pageMetas.filter(
|
||||||
|
pageMeta => !isPageJournal(pageMeta.id) || !!pageMeta.updatedDate
|
||||||
|
),
|
||||||
|
[isPageJournal, pageMetas]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function usePageMetaHelper(blockSuiteWorkspace: Workspace) {
|
export function usePageMetaHelper(blockSuiteWorkspace: Workspace) {
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { MoveToTrash } from '@affine/core/components/page-list';
|
import { MoveToTrash } from '@affine/core/components/page-list';
|
||||||
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
|
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
|
||||||
|
import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta';
|
||||||
import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
|
import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
|
||||||
import {
|
import {
|
||||||
useJournalHelper,
|
useJournalHelper,
|
||||||
@@ -13,6 +14,7 @@ import {
|
|||||||
useJournalRouteHelper,
|
useJournalRouteHelper,
|
||||||
} from '@affine/core/hooks/use-journal';
|
} from '@affine/core/hooks/use-journal';
|
||||||
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
|
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
|
||||||
|
import type { BlockSuiteWorkspace } from '@affine/core/shared';
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import {
|
import {
|
||||||
EdgelessIcon,
|
EdgelessIcon,
|
||||||
@@ -20,7 +22,7 @@ import {
|
|||||||
PageIcon,
|
PageIcon,
|
||||||
TodayIcon,
|
TodayIcon,
|
||||||
} from '@blocksuite/icons';
|
} from '@blocksuite/icons';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page, PageMeta } from '@blocksuite/store';
|
||||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@@ -41,21 +43,28 @@ const CountDisplay = ({
|
|||||||
return <span {...attrs}>{count > max ? `${max}+` : count}</span>;
|
return <span {...attrs}>{count > max ? `${max}+` : count}</span>;
|
||||||
};
|
};
|
||||||
interface PageItemProps extends HTMLAttributes<HTMLDivElement> {
|
interface PageItemProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
page: Page;
|
pageMeta: PageMeta;
|
||||||
|
workspace: BlockSuiteWorkspace;
|
||||||
right?: ReactNode;
|
right?: ReactNode;
|
||||||
}
|
}
|
||||||
const PageItem = ({ page, right, className, ...attrs }: PageItemProps) => {
|
const PageItem = ({
|
||||||
const { isJournal } = useJournalInfoHelper(page.workspace, page.id);
|
pageMeta,
|
||||||
const title = useBlockSuiteWorkspacePageTitle(page.workspace, page.id);
|
workspace,
|
||||||
|
right,
|
||||||
|
className,
|
||||||
|
...attrs
|
||||||
|
}: PageItemProps) => {
|
||||||
|
const { isJournal } = useJournalInfoHelper(workspace, pageMeta.id);
|
||||||
|
const title = useBlockSuiteWorkspacePageTitle(workspace, pageMeta.id);
|
||||||
|
|
||||||
const Icon = isJournal
|
const Icon = isJournal
|
||||||
? TodayIcon
|
? TodayIcon
|
||||||
: page.meta.mode === 'edgeless'
|
: pageMeta.mode === 'edgeless'
|
||||||
? EdgelessIcon
|
? EdgelessIcon
|
||||||
: PageIcon;
|
: PageIcon;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
aria-label={page.meta.title}
|
aria-label={pageMeta.title}
|
||||||
className={clsx(className, styles.pageItem)}
|
className={clsx(className, styles.pageItem)}
|
||||||
{...attrs}
|
{...attrs}
|
||||||
>
|
>
|
||||||
@@ -114,15 +123,12 @@ const EditorJournalPanel = (props: EditorExtensionProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const sortPagesByDate = (
|
const sortPagesByDate = (
|
||||||
pages: Page[],
|
pages: PageMeta[],
|
||||||
field: 'updatedDate' | 'createDate',
|
field: 'updatedDate' | 'createDate',
|
||||||
order: 'asc' | 'desc' = 'desc'
|
order: 'asc' | 'desc' = 'desc'
|
||||||
) => {
|
) => {
|
||||||
return [...pages].sort((a, b) => {
|
return [...pages].sort((a, b) => {
|
||||||
return (
|
return (order === 'asc' ? 1 : -1) * dayjs(b[field]).diff(dayjs(a[field]));
|
||||||
(order === 'asc' ? 1 : -1) *
|
|
||||||
dayjs(b.meta[field]).diff(dayjs(a.meta[field]))
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,21 +147,21 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
|
|||||||
const nodeRef = useRef<HTMLDivElement>(null);
|
const nodeRef = useRef<HTMLDivElement>(null);
|
||||||
const t = useAFFiNEI18N();
|
const t = useAFFiNEI18N();
|
||||||
const [activeItem, setActiveItem] = useState<NavItemName>('createdToday');
|
const [activeItem, setActiveItem] = useState<NavItemName>('createdToday');
|
||||||
|
const pageMetas = useBlockSuitePageMeta(workspace);
|
||||||
|
|
||||||
const navigateHelper = useNavigateHelper();
|
const navigateHelper = useNavigateHelper();
|
||||||
|
|
||||||
const getTodaysPages = useCallback(
|
const getTodaysPages = useCallback(
|
||||||
(field: 'createDate' | 'updatedDate') => {
|
(field: 'createDate' | 'updatedDate') => {
|
||||||
const pages: Page[] = [];
|
return sortPagesByDate(
|
||||||
Array.from(workspace.pages.values()).forEach(page => {
|
pageMetas.filter(pageMeta => {
|
||||||
if (page.meta.trash) return;
|
if (pageMeta.trash) return false;
|
||||||
if (page.meta[field] && dayjs(page.meta[field]).isSame(date, 'day')) {
|
return pageMeta[field] && dayjs(pageMeta[field]).isSame(date, 'day');
|
||||||
pages.push(page);
|
}),
|
||||||
}
|
field
|
||||||
});
|
);
|
||||||
return sortPagesByDate(pages, field);
|
|
||||||
},
|
},
|
||||||
[date, workspace.pages]
|
[date, pageMetas]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createdToday = useMemo(
|
const createdToday = useMemo(
|
||||||
@@ -224,14 +230,15 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
|
|||||||
<Scrollable.Scrollbar />
|
<Scrollable.Scrollbar />
|
||||||
<Scrollable.Viewport>
|
<Scrollable.Viewport>
|
||||||
<div className={styles.dailyCountContent} ref={nodeRef}>
|
<div className={styles.dailyCountContent} ref={nodeRef}>
|
||||||
{renderList.map((page, index) => (
|
{renderList.map((pageMeta, index) => (
|
||||||
<PageItem
|
<PageItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigateHelper.openPage(workspace.id, page.id)
|
navigateHelper.openPage(workspace.id, pageMeta.id)
|
||||||
}
|
}
|
||||||
tabIndex={name === activeItem ? 0 : -1}
|
tabIndex={name === activeItem ? 0 : -1}
|
||||||
key={index}
|
key={index}
|
||||||
page={page}
|
pageMeta={pageMeta}
|
||||||
|
workspace={workspace}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -282,7 +289,8 @@ const ConflictList = ({
|
|||||||
<PageItem
|
<PageItem
|
||||||
aria-label={page.meta.title}
|
aria-label={page.meta.title}
|
||||||
aria-selected={isCurrent}
|
aria-selected={isCurrent}
|
||||||
page={page}
|
pageMeta={page.meta}
|
||||||
|
workspace={workspace}
|
||||||
key={page.id}
|
key={page.id}
|
||||||
right={
|
right={
|
||||||
<Menu
|
<Menu
|
||||||
|
|||||||
Reference in New Issue
Block a user