Skip to content

Commit

Permalink
feat(mobile): calc doc-card's height by id
Browse files Browse the repository at this point in the history
  • Loading branch information
CatsJuice committed Nov 7, 2024
1 parent 9a6d473 commit 585bafe
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 41 deletions.
26 changes: 17 additions & 9 deletions packages/frontend/core/src/mobile/components/doc-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ import {
import type { DocMeta } from '@blocksuite/affine/store';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import clsx from 'clsx';
import { forwardRef, type ReactNode } from 'react';
import { forwardRef, type ReactNode, useMemo } from 'react';

import * as styles from './styles.css';
import { DocCardTags } from './tag';

const calcRowsById = (id: string) => {
const [MIN, MAX] = [2, 8];

const code = id.charCodeAt(0);
return Math.floor((code % (MAX - MIN)) + MIN);
};

export interface DocCardProps extends Omit<WorkbenchLinkProps, 'to'> {
meta: {
id: DocMeta['id'];
Expand All @@ -23,14 +30,14 @@ export interface DocCardProps extends Omit<WorkbenchLinkProps, 'to'> {
showTags?: boolean;

/**
* If provided, content's height will be calculated: `previewRows * line-height`
* When enabled, preview's height will be calculated based on `meta.id`
*/
previewRows?: number;
autoHeightById?: boolean;
}

export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
function DocCard(
{ showTags = true, meta, className, previewRows, ...attrs },
{ showTags = true, meta, className, autoHeightById, ...attrs },
ref
) {
const favAdapter = useService(CompatibleFavoriteItemsAdapter);
Expand All @@ -46,7 +53,11 @@ export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
[favAdapter, meta.id]
);

const contentHeight = previewRows ? `${previewRows * 18}px` : 'unset';
const contentStyle = useMemo(() => {
if (!autoHeightById) return { flex: 1 };
const rows = calcRowsById(meta.id);
return { height: `${rows * 18}px` };
}, [autoHeightById, meta.id]);

return (
<WorkbenchLink
Expand All @@ -67,10 +78,7 @@ export const DocCard = forwardRef<HTMLAnchorElement, DocCardProps>(
}
/>
</header>
<main
className={styles.content}
style={{ height: contentHeight, flex: contentHeight ? 'unset' : 1 }}
>
<main className={styles.content} style={contentStyle}>
<PagePreview
docCollection={workspace.docCollection}
pageId={meta.id}
Expand Down
34 changes: 2 additions & 32 deletions packages/frontend/core/src/mobile/views/all-docs/doc/masonry.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useGlobalEvent } from '@affine/core/mobile/hooks/use-global-events';
import type { DocMeta } from '@blocksuite/affine/store';
import type { FrameworkProvider } from '@toeverything/infra';
import { GlobalCacheService, useFramework } from '@toeverything/infra';
import { useCallback, useMemo, useState } from 'react';
import { useCallback, useState } from 'react';

import { DocCard } from '../../../components';
import * as styles from './masonry.css';
Expand All @@ -16,28 +14,6 @@ const calcColumnCount = () => {
return Math.max(newColumnCount, 2);
};

/**
* Randomly assign preview rows to each item and cache it
*/
const getRowsCache = (framework: FrameworkProvider, items: DocMeta[]) => {
const ROWS = [3, 4, 5, 6, 7];
const CACHE_KEY = 'masonryPreviewRows';

const globalCache = framework.get(GlobalCacheService).globalCache;
const cache = globalCache.get<Record<string, number>>(CACHE_KEY) || {};
const newCache = items.reduce(
(acc, item) => {
if (cache[item.id]) return acc;
const row = ROWS[Math.floor(Math.random() * ROWS.length)];
acc[item.id] = row;
return acc;
},
{ ...cache }
);
globalCache.set(CACHE_KEY, newCache);
return newCache;
};

export const MasonryDocs = ({
items,
showTags,
Expand All @@ -46,27 +22,21 @@ export const MasonryDocs = ({
showTags?: boolean;
}) => {
const [columnCount, setColumnCount] = useState(calcColumnCount());
const framework = useFramework();

const updateColumnCount = useCallback(() => {
setColumnCount(calcColumnCount());
}, []);
useGlobalEvent('resize', updateColumnCount);

const previewRowsMap = useMemo(
() => getRowsCache(framework, items),
[framework, items]
);

return (
<div className={styles.masonry} style={{ columnCount }}>
{items.map(item => (
<DocCard
key={item.id}
className={styles.masonryItem}
previewRows={previewRowsMap[item.id]}
showTags={showTags}
meta={item}
autoHeightById
/>
))}
</div>
Expand Down

0 comments on commit 585bafe

Please sign in to comment.