mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
feat(mobile): show doc title on title bar when scroll down (#8976)
This commit is contained in:
@@ -31,6 +31,7 @@ export interface PageHeaderProps
|
||||
* @default true
|
||||
*/
|
||||
centerContent?: boolean;
|
||||
contentClassName?: string;
|
||||
|
||||
prefixClassName?: string;
|
||||
prefixStyle?: React.CSSProperties;
|
||||
@@ -56,6 +57,7 @@ export const PageHeader = forwardRef<HTMLDivElement, PageHeaderProps>(
|
||||
children,
|
||||
className,
|
||||
centerContent = true,
|
||||
contentClassName,
|
||||
prefixClassName,
|
||||
prefixStyle,
|
||||
suffixClassName,
|
||||
@@ -85,7 +87,9 @@ export const PageHeader = forwardRef<HTMLDivElement, PageHeaderProps>(
|
||||
</section>
|
||||
|
||||
<section
|
||||
className={clsx(styles.content, { center: centerContent })}
|
||||
className={clsx(styles.content, contentClassName, {
|
||||
center: centerContent,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</section>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
import { createVar, style } from '@vanilla-extract/css';
|
||||
|
||||
export const root = style({
|
||||
width: '100%',
|
||||
@@ -18,14 +18,22 @@ export const inner = style({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
});
|
||||
const contentMaxWidth = createVar('contentMaxWidth');
|
||||
export const content = style({
|
||||
vars: {
|
||||
[contentMaxWidth]: 'unset',
|
||||
},
|
||||
maxWidth: contentMaxWidth,
|
||||
selectors: {
|
||||
'&.center': {
|
||||
vars: {
|
||||
// gap(6 * 2) + button(44 * 2) + padding(8 * 2)
|
||||
[contentMaxWidth]: 'calc(100% - 12px - 88px - 16px)',
|
||||
},
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: 'fit-content',
|
||||
maxWidth: 'calc(100% - 12px - 88px - 16px)',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
pointerEvents: 'none',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { bodyEmphasized } from '@toeverything/theme/typography';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { globalStyle, style } from '@vanilla-extract/css';
|
||||
|
||||
@@ -16,6 +17,26 @@ export const header = style({
|
||||
zIndex: 1,
|
||||
});
|
||||
|
||||
export const headerContent = style({
|
||||
maxWidth: `calc(100% - 200px)`,
|
||||
});
|
||||
export const headerTitle = style([
|
||||
bodyEmphasized,
|
||||
{
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
opacity: 0,
|
||||
transition: 'opacity 0.23s ease',
|
||||
selectors: {
|
||||
'&[data-show="true"]': {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
export const mainContainer = style({
|
||||
containerType: 'inline-size',
|
||||
display: 'flex',
|
||||
|
||||
@@ -10,11 +10,13 @@ import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-he
|
||||
import { PageDetailEditor } from '@affine/core/components/page-detail-editor';
|
||||
import { DetailPageWrapper } from '@affine/core/desktop/pages/workspace/detail-page/detail-page-wrapper';
|
||||
import { PageHeader } from '@affine/core/mobile/components';
|
||||
import { useGlobalEvent } from '@affine/core/mobile/hooks/use-global-events';
|
||||
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
||||
import { EditorService } from '@affine/core/modules/editor';
|
||||
import { JournalService } from '@affine/core/modules/journal';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import { ViewService } from '@affine/core/modules/workbench/services/view';
|
||||
import { i18nTime } from '@affine/i18n';
|
||||
import { i18nTime, useI18n } from '@affine/i18n';
|
||||
import {
|
||||
BookmarkBlockService,
|
||||
customImageProxyMiddleware,
|
||||
@@ -36,11 +38,10 @@ import {
|
||||
useServices,
|
||||
WorkspaceService,
|
||||
} from '@toeverything/infra';
|
||||
import { bodyEmphasized } from '@toeverything/theme/typography';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { AppTabs } from '../../../components';
|
||||
@@ -219,6 +220,8 @@ const skeletonWithBack = getSkeleton(true);
|
||||
const notFound = getNotFound(false);
|
||||
const notFoundWithBack = getNotFound(true);
|
||||
|
||||
const checkShowTitle = () => window.scrollY >= 158;
|
||||
|
||||
const MobileDetailPage = ({
|
||||
pageId,
|
||||
date,
|
||||
@@ -226,8 +229,15 @@ const MobileDetailPage = ({
|
||||
pageId: string;
|
||||
date?: string;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const docDisplayMetaService = useService(DocDisplayMetaService);
|
||||
const journalService = useService(JournalService);
|
||||
|
||||
const [showTitle, setShowTitle] = useState(checkShowTitle);
|
||||
const { openJournal } = useJournalRouteHelper();
|
||||
const titleInfo = useLiveData(docDisplayMetaService.title$(pageId));
|
||||
const title =
|
||||
typeof titleInfo === 'string' ? titleInfo : t[titleInfo.i18nKey]();
|
||||
|
||||
const allJournalDates = useLiveData(journalService.allJournalDates$);
|
||||
|
||||
@@ -237,6 +247,12 @@ const MobileDetailPage = ({
|
||||
},
|
||||
[openJournal]
|
||||
);
|
||||
|
||||
useGlobalEvent(
|
||||
'scroll',
|
||||
useCallback(() => setShowTitle(checkShowTitle()), [])
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<DetailPageWrapper
|
||||
@@ -247,6 +263,7 @@ const MobileDetailPage = ({
|
||||
<PageHeader
|
||||
back={!date}
|
||||
className={styles.header}
|
||||
contentClassName={styles.headerContent}
|
||||
suffix={
|
||||
<>
|
||||
<PageHeaderShareButton />
|
||||
@@ -265,11 +282,11 @@ const MobileDetailPage = ({
|
||||
}
|
||||
bottomSpacer={94}
|
||||
>
|
||||
{date ? (
|
||||
<span className={bodyEmphasized}>
|
||||
{i18nTime(dayjs(date), { absolute: { accuracy: 'month' } })}
|
||||
</span>
|
||||
) : null}
|
||||
<span data-show={!!date || showTitle} className={styles.headerTitle}>
|
||||
{date
|
||||
? i18nTime(dayjs(date), { absolute: { accuracy: 'month' } })
|
||||
: title}
|
||||
</span>
|
||||
</PageHeader>
|
||||
<DetailPageImpl />
|
||||
<AppTabs background={cssVarV2('layer/background/primary')} />
|
||||
|
||||
Reference in New Issue
Block a user