Skip to content

Commit db76780

Browse files
committed
feat(mobile): mobile index page UI (#7959)
1 parent f37051d commit db76780

File tree

47 files changed

+1403
-83
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1403
-83
lines changed
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
11
import type { DocCollection } from '@blocksuite/store';
22
import { useAtomValue } from 'jotai';
3-
import { Suspense } from 'react';
3+
import { type ReactNode, Suspense } from 'react';
44

55
import { useBlockSuitePagePreview } from './use-block-suite-page-preview';
66
import { useDocCollectionPage } from './use-block-suite-workspace-page';
77

8-
interface PagePreviewInnerProps {
8+
interface PagePreviewProps {
99
docCollection: DocCollection;
1010
pageId: string;
11+
emptyFallback?: ReactNode;
1112
}
1213

1314
const PagePreviewInner = ({
1415
docCollection: workspace,
1516
pageId,
16-
}: PagePreviewInnerProps) => {
17+
emptyFallback,
18+
}: PagePreviewProps) => {
1719
const page = useDocCollectionPage(workspace, pageId);
1820
const previewAtom = useBlockSuitePagePreview(page);
1921
const preview = useAtomValue(previewAtom);
20-
return preview ? preview : null;
22+
const res = preview ? preview : null;
23+
return res || emptyFallback;
2124
};
2225

23-
interface PagePreviewProps {
24-
docCollection: DocCollection;
25-
pageId: string;
26-
}
27-
28-
export const PagePreview = ({ docCollection, pageId }: PagePreviewProps) => {
26+
export const PagePreview = (props: PagePreviewProps) => {
2927
return (
3028
<Suspense>
31-
<PagePreviewInner docCollection={docCollection} pageId={pageId} />
29+
<PagePreviewInner {...props} />
3230
</Suspense>
3331
);
3432
};

packages/frontend/core/src/modules/explorer/entities/explore-section.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { map } from 'rxjs';
55
import type { CollapsibleSectionName } from '../types';
66

77
const DEFAULT_COLLAPSABLE_STATE: Record<CollapsibleSectionName, boolean> = {
8+
recent: true,
89
favorites: false,
910
organize: false,
1011
collections: true,

packages/frontend/core/src/modules/explorer/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ExplorerSection } from './entities/explore-section';
88
import { ExplorerService } from './services/explorer';
99
export { ExplorerService } from './services/explorer';
1010
export type { CollapsibleSectionName } from './types';
11+
export { CollapsibleSection } from './views/layouts/collapsible-section';
1112
export { ExplorerMobileContext } from './views/mobile.context';
1213
export { ExplorerCollections } from './views/sections/collections';
1314
export { ExplorerFavorites } from './views/sections/favorites';

packages/frontend/core/src/modules/explorer/services/explorer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ExplorerSection } from '../entities/explore-section';
44
import type { CollapsibleSectionName } from '../types';
55

66
const allSectionName: Array<CollapsibleSectionName> = [
7+
'recent', // mobile only
78
'favorites',
89
'organize',
910
'collections',

packages/frontend/core/src/modules/explorer/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export type CollapsibleSectionName =
2+
| 'recent'
23
| 'collections'
34
| 'favorites'
45
| 'tags'

packages/frontend/core/src/modules/explorer/views/tree/node.css.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const postfix = style({
7777
});
7878
export const iconContainer = style({
7979
display: 'flex',
80-
alignContent: 'center',
80+
justifyContent: 'center',
8181
alignItems: 'center',
8282
width: 20,
8383
height: 20,

packages/frontend/core/src/modules/workbench/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
export { Workbench } from './entities/workbench';
22
export { ViewScope } from './scopes/view';
33
export { WorkbenchService } from './services/workbench';
4+
export { useBindWorkbenchToBrowserRouter } from './view/browser-adapter';
45
export { useIsActiveView } from './view/use-is-active-view';
56
export { ViewBody, ViewHeader, ViewSidebarTab } from './view/view-islands';
67
export { ViewIcon, ViewTitle } from './view/view-meta';
8+
export type { WorkbenchLinkProps } from './view/workbench-link';
79
export { WorkbenchLink } from './view/workbench-link';
810
export { WorkbenchRoot } from './view/workbench-root';
911

packages/frontend/core/src/modules/workbench/view/workbench-link.tsx

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,57 @@ import { forwardRef, type MouseEvent } from 'react';
1010

1111
import { WorkbenchService } from '../services/workbench';
1212

13-
export const WorkbenchLink = forwardRef<
14-
HTMLAnchorElement,
15-
React.PropsWithChildren<
16-
{
17-
to: To;
18-
onClick?: (e: MouseEvent) => void;
19-
} & React.HTMLProps<HTMLAnchorElement>
20-
>
21-
>(function WorkbenchLink({ to, onClick, ...other }, ref) {
22-
const { featureFlagService, workbenchService } = useServices({
23-
FeatureFlagService,
24-
WorkbenchService,
25-
});
26-
const enableMultiView = useLiveData(
27-
featureFlagService.flags.enable_multi_view.$
28-
);
29-
const workbench = workbenchService.workbench;
30-
const basename = useLiveData(workbench.basename$);
31-
const link =
32-
basename +
33-
(typeof to === 'string' ? to : `${to.pathname}${to.search}${to.hash}`);
34-
const handleClick = useCatchEventCallback(
35-
async (event: React.MouseEvent<HTMLAnchorElement>) => {
36-
onClick?.(event);
37-
if (event.defaultPrevented) {
38-
return;
39-
}
40-
const at = (() => {
41-
if (isNewTabTrigger(event)) {
42-
return event.altKey && enableMultiView && environment.isDesktop
43-
? 'tail'
44-
: 'new-tab';
13+
export type WorkbenchLinkProps = React.PropsWithChildren<
14+
{
15+
to: To;
16+
onClick?: (e: MouseEvent) => void;
17+
} & React.HTMLProps<HTMLAnchorElement>
18+
>;
19+
20+
export const WorkbenchLink = forwardRef<HTMLAnchorElement, WorkbenchLinkProps>(
21+
function WorkbenchLink({ to, onClick, ...other }, ref) {
22+
const { featureFlagService, workbenchService } = useServices({
23+
FeatureFlagService,
24+
WorkbenchService,
25+
});
26+
const enableMultiView = useLiveData(
27+
featureFlagService.flags.enable_multi_view.$
28+
);
29+
const workbench = workbenchService.workbench;
30+
const basename = useLiveData(workbench.basename$);
31+
const link =
32+
basename +
33+
(typeof to === 'string' ? to : `${to.pathname}${to.search}${to.hash}`);
34+
const handleClick = useCatchEventCallback(
35+
async (event: React.MouseEvent<HTMLAnchorElement>) => {
36+
onClick?.(event);
37+
if (event.defaultPrevented) {
38+
return;
4539
}
46-
return 'active';
47-
})();
48-
workbench.open(to, { at });
49-
event.preventDefault();
50-
},
51-
[enableMultiView, onClick, to, workbench]
52-
);
40+
const at = (() => {
41+
if (isNewTabTrigger(event)) {
42+
return event.altKey && enableMultiView && environment.isDesktop
43+
? 'tail'
44+
: 'new-tab';
45+
}
46+
return 'active';
47+
})();
48+
workbench.open(to, { at });
49+
event.preventDefault();
50+
},
51+
[enableMultiView, onClick, to, workbench]
52+
);
5353

54-
// eslint suspicious runtime error
55-
// eslint-disable-next-line react/no-danger-with-children
56-
return (
57-
<a
58-
{...other}
59-
ref={ref}
60-
href={link}
61-
onClick={handleClick}
62-
onAuxClick={handleClick}
63-
/>
64-
);
65-
});
54+
// eslint suspicious runtime error
55+
// eslint-disable-next-line react/no-danger-with-children
56+
return (
57+
<a
58+
{...other}
59+
ref={ref}
60+
href={link}
61+
onClick={handleClick}
62+
onAuxClick={handleClick}
63+
/>
64+
);
65+
}
66+
);

packages/frontend/core/src/pages/index.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ export const loader: LoaderFunction = async () => {
2828
return null;
2929
};
3030

31-
export const Component = () => {
31+
export const Component = ({
32+
defaultIndexRoute = WorkspaceSubPath.ALL,
33+
}: {
34+
defaultIndexRoute?: WorkspaceSubPath;
35+
}) => {
3236
// navigating and creating may be slow, to avoid flickering, we show workspace fallback
3337
const [navigating, setNavigating] = useState(true);
3438
const [creating, setCreating] = useState(false);
@@ -59,11 +63,11 @@ export const Component = () => {
5963
if (defaultDocId) {
6064
jumpToPage(meta.id, defaultDocId);
6165
} else {
62-
openPage(meta.id, WorkspaceSubPath.ALL);
66+
openPage(meta.id, defaultIndexRoute);
6367
}
6468
})
6569
.catch(err => console.error('Failed to create cloud workspace', err));
66-
}, [jumpToPage, openPage, workspacesService]);
70+
}, [defaultIndexRoute, jumpToPage, openPage, workspacesService]);
6771

6872
useLayoutEffect(() => {
6973
if (!navigating) {
@@ -86,7 +90,7 @@ export const Component = () => {
8690
const openWorkspace =
8791
list.find(w => w.flavour === WorkspaceFlavour.AFFINE_CLOUD) ??
8892
list[0];
89-
openPage(openWorkspace.id, WorkspaceSubPath.ALL);
93+
openPage(openWorkspace.id, defaultIndexRoute);
9094
} else {
9195
return;
9296
}
@@ -99,7 +103,7 @@ export const Component = () => {
99103
const lastId = localStorage.getItem('last_workspace_id');
100104

101105
const openWorkspace = list.find(w => w.id === lastId) ?? list[0];
102-
openPage(openWorkspace.id, WorkspaceSubPath.ALL);
106+
openPage(openWorkspace.id, defaultIndexRoute);
103107
}
104108
}, [
105109
createCloudWorkspace,
@@ -109,6 +113,7 @@ export const Component = () => {
109113
listIsLoading,
110114
loggedIn,
111115
navigating,
116+
defaultIndexRoute,
112117
]);
113118

114119
useEffect(() => {

packages/frontend/core/src/pages/workspace/workbench-root.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { WorkbenchService } from '@affine/core/modules/workbench';
2-
import { useBindWorkbenchToBrowserRouter } from '@affine/core/modules/workbench/view/browser-adapter';
1+
import {
2+
useBindWorkbenchToBrowserRouter,
3+
WorkbenchService,
4+
} from '@affine/core/modules/workbench';
35
import { ViewRoot } from '@affine/core/modules/workbench/view/view-root';
46
import { useLiveData, useService } from '@toeverything/infra';
57
import { useEffect } from 'react';

0 commit comments

Comments
 (0)