mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-12 23:56:36 +08:00
refactor(core): implement doc created/updated by service (#12150)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Documents now automatically track and display "created by" and "updated by" user information. - Document creation and update timestamps are now managed and shown more accurately. - Workspace and document metadata (name, avatar) updates are more responsive and reliable. - Document creation supports middleware for customizing properties and behavior. - **Improvements** - Simplified and unified event handling for document list updates, reducing redundant event subscriptions. - Enhanced integration of editor and theme settings into the document creation process. - Explicit Yjs document initialization for improved workspace stability and reliability. - Consolidated journal-related metadata display in document icons and titles for clarity. - **Bug Fixes** - Fixed inconsistencies in how workspace and document names are set and updated. - Improved accuracy of "last updated" indicators by handling timestamps automatically. - **Refactor** - Removed deprecated event subjects and direct metadata manipulation in favor of more robust, reactive patterns. - Streamlined document creation logic across various features (quick search, journal, recording, etc.). - Simplified user avatar display components and removed cloud metadata dependencies. - Removed legacy editor setting and theme service dependencies from multiple modules. - **Chores** - Updated internal APIs and interfaces to support new metadata and event handling mechanisms. - Cleaned up unused code and dependencies related to editor settings and theme services. - Skipped flaky end-to-end test to improve test suite stability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -113,6 +113,7 @@ const getOrCreateShellWorkspace = (
|
||||
if (!docCollection) {
|
||||
docCollection = new WorkspaceImpl({
|
||||
id: workspaceId,
|
||||
rootDoc: new YDoc({ guid: workspaceId }),
|
||||
blobSource: {
|
||||
name: 'cloud',
|
||||
readonly: true,
|
||||
|
||||
@@ -1,56 +1,26 @@
|
||||
import { Avatar, PropertyValue } from '@affine/component';
|
||||
import { CloudDocMetaService } from '@affine/core/modules/cloud/services/cloud-doc-meta';
|
||||
import { PropertyValue } from '@affine/component';
|
||||
import { PublicUserLabel } from '@affine/core/modules/cloud/views/public-user';
|
||||
import { DocService } from '@affine/core/modules/doc';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { userWrapper } from './created-updated-by.css';
|
||||
|
||||
const CloudUserAvatar = (props: { type: 'CreatedBy' | 'UpdatedBy' }) => {
|
||||
const cloudDocMetaService = useService(CloudDocMetaService);
|
||||
const cloudDocMeta = useLiveData(cloudDocMetaService.cloudDocMeta.meta$);
|
||||
const isRevalidating = useLiveData(
|
||||
cloudDocMetaService.cloudDocMeta.isRevalidating$
|
||||
const CreatedByUpdatedByAvatar = (props: {
|
||||
type: 'CreatedBy' | 'UpdatedBy';
|
||||
}) => {
|
||||
const docService = useService(DocService);
|
||||
const userId = useLiveData(
|
||||
props.type === 'CreatedBy'
|
||||
? docService.doc.createdBy$
|
||||
: docService.doc.updatedBy$
|
||||
);
|
||||
const error = useLiveData(cloudDocMetaService.cloudDocMeta.error$);
|
||||
|
||||
useEffect(() => {
|
||||
cloudDocMetaService.cloudDocMeta.revalidate();
|
||||
}, [cloudDocMetaService]);
|
||||
|
||||
const user = useMemo(() => {
|
||||
if (!cloudDocMeta) return null;
|
||||
if (props.type === 'CreatedBy' && cloudDocMeta.createdBy) {
|
||||
return {
|
||||
name: cloudDocMeta.createdBy.name,
|
||||
avatarUrl: cloudDocMeta.createdBy.avatarUrl,
|
||||
};
|
||||
} else if (props.type === 'UpdatedBy' && cloudDocMeta.updatedBy) {
|
||||
return {
|
||||
name: cloudDocMeta.updatedBy.name,
|
||||
avatarUrl: cloudDocMeta.updatedBy.avatarUrl,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}, [cloudDocMeta, props.type]);
|
||||
|
||||
if (!cloudDocMeta) {
|
||||
if (isRevalidating) {
|
||||
// TODO: loading ui
|
||||
return null;
|
||||
}
|
||||
if (error) {
|
||||
// error ui
|
||||
return;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (user) {
|
||||
if (userId) {
|
||||
return (
|
||||
<div className={userWrapper}>
|
||||
<Avatar url={user.avatarUrl || ''} name={user.name} size={22} />
|
||||
<span>{user.name}</span>
|
||||
<PublicUserLabel id={userId} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -85,7 +55,7 @@ export const CreatedByValue = () => {
|
||||
|
||||
return (
|
||||
<PropertyValue readonly>
|
||||
<CloudUserAvatar type="CreatedBy" />
|
||||
<CreatedByUpdatedByAvatar type="CreatedBy" />
|
||||
</PropertyValue>
|
||||
);
|
||||
};
|
||||
@@ -104,7 +74,7 @@ export const UpdatedByValue = () => {
|
||||
|
||||
return (
|
||||
<PropertyValue readonly>
|
||||
<CloudUserAvatar type="UpdatedBy" />
|
||||
<CreatedByUpdatedByAvatar type="UpdatedBy" />
|
||||
</PropertyValue>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,16 +16,11 @@ export function useDocCollectionPage(
|
||||
useEffect(() => {
|
||||
const group = new DisposableGroup();
|
||||
group.add(
|
||||
docCollection.slots.docCreated.subscribe(id => {
|
||||
if (pageId === id) {
|
||||
setPage(docCollection.getDoc(id)?.getStore() ?? null);
|
||||
}
|
||||
})
|
||||
);
|
||||
group.add(
|
||||
docCollection.slots.docRemoved.subscribe(id => {
|
||||
if (pageId === id) {
|
||||
docCollection.slots.docListUpdated.subscribe(() => {
|
||||
if (!pageId) {
|
||||
setPage(null);
|
||||
} else {
|
||||
setPage(docCollection.getDoc(pageId)?.getStore() ?? null);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -16,16 +16,11 @@ export function useDocCollectionPage(
|
||||
useEffect(() => {
|
||||
const group = new DisposableGroup();
|
||||
group.add(
|
||||
docCollection.slots.docCreated.subscribe(id => {
|
||||
if (pageId === id) {
|
||||
setPage(docCollection.getDoc(id)?.getStore() ?? null);
|
||||
}
|
||||
})
|
||||
);
|
||||
group.add(
|
||||
docCollection.slots.docRemoved.subscribe(id => {
|
||||
if (pageId === id) {
|
||||
docCollection.slots.docListUpdated.subscribe(() => {
|
||||
if (!pageId) {
|
||||
setPage(null);
|
||||
} else {
|
||||
setPage(docCollection.getDoc(pageId)?.getStore() ?? null);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user