mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-01 09:30:01 +08:00
feat(core): support better battery save mode (#13383)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a Document Summary module, enabling live and cached document summaries with cloud revalidation. * Added a feature flag for enabling battery save mode. * Added explicit pause and resume controls for sync operations, accessible via UI events and programmatically. * **Improvements** * Enhanced sync and indexing logic to support pausing, resuming, and battery save mode, with improved job prioritization. * Updated navigation and preview components to use the new document summary service and improved priority handling. * Improved logging and state reporting for sync and indexing processes. * Refined backlink handling with reactive loading states and cloud revalidation. * Replaced backlink and link management to use a new dedicated document links service. * Enhanced workspace engine to conditionally enable battery save mode based on feature flags and workspace flavor. * **Bug Fixes** * Removed unnecessary debug console logs from various components for cleaner output. * **Refactor** * Replaced battery save mode methods with explicit pause/resume methods throughout the app and services. * Modularized and streamlined document summary and sync-related code for better maintainability. * Restructured backlink components to improve visibility handling and data fetching. * Simplified and improved document backlink data fetching with retry and loading state management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -16,6 +16,7 @@ import { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import { GlobalContextService } from '@affine/core/modules/global-context';
|
||||
import { NavigationPanelService } from '@affine/core/modules/navigation-panel';
|
||||
import { GuardService } from '@affine/core/modules/permissions';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
@@ -56,12 +57,14 @@ export const NavigationPanelDocNode = ({
|
||||
const t = useI18n();
|
||||
const {
|
||||
docsSearchService,
|
||||
workspaceService,
|
||||
docsService,
|
||||
globalContextService,
|
||||
docDisplayMetaService,
|
||||
featureFlagService,
|
||||
guardService,
|
||||
} = useServices({
|
||||
WorkspaceService,
|
||||
DocsSearchService,
|
||||
DocsService,
|
||||
GlobalContextService,
|
||||
@@ -120,9 +123,17 @@ export const NavigationPanelDocNode = ({
|
||||
|
||||
const [referencesLoading, setReferencesLoading] = useState(true);
|
||||
useLayoutEffect(() => {
|
||||
if (collapsed) {
|
||||
return;
|
||||
}
|
||||
const abortController = new AbortController();
|
||||
const undoSync = workspaceService.workspace.engine.doc.addPriority(
|
||||
docId,
|
||||
10
|
||||
);
|
||||
const undoIndexer = docsSearchService.indexer.addPriority(docId, 10);
|
||||
docsSearchService.indexer
|
||||
.waitForDocCompletedWithPriority(docId, 100, abortController.signal)
|
||||
.waitForDocCompleted(docId, abortController.signal)
|
||||
.then(() => {
|
||||
setReferencesLoading(false);
|
||||
})
|
||||
@@ -132,9 +143,11 @@ export const NavigationPanelDocNode = ({
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
undoSync();
|
||||
undoIndexer();
|
||||
abortController.abort(MANUALLY_STOP);
|
||||
};
|
||||
}, [docId, docsSearchService]);
|
||||
}, [docId, docsSearchService, workspaceService, collapsed]);
|
||||
|
||||
const dndData = useMemo(() => {
|
||||
return {
|
||||
|
||||
@@ -14,14 +14,14 @@ import type {
|
||||
DatabaseRow,
|
||||
DatabaseValueCell,
|
||||
} from '@affine/core/modules/doc-info/types';
|
||||
import { DocsSearchService } from '@affine/core/modules/docs-search';
|
||||
import { DocLinksService } from '@affine/core/modules/doc-link';
|
||||
import { GuardService } from '@affine/core/modules/permissions';
|
||||
import { WorkspacePropertyService } from '@affine/core/modules/workspace-property';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import track from '@affine/track';
|
||||
import { PlusIcon } from '@blocksuite/icons/rc';
|
||||
import { LiveData, useLiveData, useServices } from '@toeverything/infra';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useLiveData, useServices } from '@toeverything/infra';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import * as styles from './info-modal.css';
|
||||
import { LinksRow } from './links-row';
|
||||
@@ -34,11 +34,11 @@ export const InfoTable = ({
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const { docsSearchService, workspacePropertyService, guardService } =
|
||||
const { workspacePropertyService, guardService, docLinksService } =
|
||||
useServices({
|
||||
DocsSearchService,
|
||||
WorkspacePropertyService,
|
||||
GuardService,
|
||||
DocLinksService,
|
||||
});
|
||||
const canEditPropertyInfo = useLiveData(
|
||||
guardService.can$('Workspace_Properties_Update')
|
||||
@@ -46,30 +46,9 @@ export const InfoTable = ({
|
||||
const canEditProperty = useLiveData(guardService.can$('Doc_Update', docId));
|
||||
const [newPropertyId, setNewPropertyId] = useState<string | null>(null);
|
||||
const properties = useLiveData(workspacePropertyService.sortedProperties$);
|
||||
const links = useLiveData(
|
||||
useMemo(
|
||||
() => LiveData.from(docsSearchService.watchRefsFrom(docId), null),
|
||||
[docId, docsSearchService]
|
||||
)
|
||||
);
|
||||
const links = useLiveData(docLinksService.links.links$);
|
||||
|
||||
const backlinks = useLiveData(
|
||||
useMemo(() => {
|
||||
return LiveData.from(docsSearchService.watchRefsTo(docId), []).map(
|
||||
links => {
|
||||
const visitedDoc = new Set<string>();
|
||||
// for each doc, we only show the first block
|
||||
return links.filter(link => {
|
||||
if (visitedDoc.has(link.docId)) {
|
||||
return false;
|
||||
}
|
||||
visitedDoc.add(link.docId);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
);
|
||||
}, [docId, docsSearchService])
|
||||
);
|
||||
const backlinks = useLiveData(docLinksService.backlinks.backlinks$);
|
||||
|
||||
const onBacklinkPropertyChange = useCallback(
|
||||
(_row: DatabaseRow, cell: DatabaseValueCell, _value: unknown) => {
|
||||
@@ -111,6 +90,10 @@ export const InfoTable = ({
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
docLinksService.backlinks.revalidateFromCloud();
|
||||
}, [docLinksService.backlinks]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PropertyCollapsibleSection
|
||||
|
||||
Reference in New Issue
Block a user