feat(ios): add intelligents button (#9281)

Co-authored-by: 砍砍 <git@qaq.wiki>
This commit is contained in:
EYHN
2024-12-24 15:51:11 +08:00
committed by GitHub
parent fbe3e08769
commit 3cf4bcf651
78 changed files with 3283 additions and 114 deletions

View File

@@ -10,6 +10,7 @@ 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 { AIButtonService } from '@affine/core/modules/ai-button';
import { DocService } from '@affine/core/modules/doc';
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
import { EditorService } from '@affine/core/modules/editor';
@@ -57,6 +58,7 @@ const DetailPageImpl = () => {
workspaceService,
globalContextService,
featureFlagService,
aIButtonService,
} = useServices({
WorkbenchService,
ViewService,
@@ -65,6 +67,7 @@ const DetailPageImpl = () => {
WorkspaceService,
GlobalContextService,
FeatureFlagService,
AIButtonService,
});
const editor = editorService.editor;
const workspace = workspaceService.workspace;
@@ -124,6 +127,14 @@ const DetailPageImpl = () => {
enableEdgelessEditing,
]);
useEffect(() => {
aIButtonService.presentAIButton(true);
return () => {
aIButtonService.presentAIButton(false);
};
}, [aIButtonService]);
useEffect(() => {
globalContext.isTrashDoc.set(!!isInTrash);

View File

@@ -0,0 +1,13 @@
export { AIButtonProvider } from './provider/ai-button';
export { AIButtonService } from './services/ai-button';
import type { Framework } from '@toeverything/infra';
import { AIButtonProvider } from './provider/ai-button';
import { AIButtonService } from './services/ai-button';
export const configureAIButtonModule = (framework: Framework) => {
framework.service(AIButtonService, container => {
return new AIButtonService(container.getOptional(AIButtonProvider));
});
};

View File

@@ -0,0 +1,9 @@
import { createIdentifier } from '@toeverything/infra';
export interface AIButtonProvider {
presentAIButton: () => Promise<void>;
dismissAIButton: () => Promise<void>;
}
export const AIButtonProvider =
createIdentifier<AIButtonProvider>('AIButtonProvider');

View File

@@ -0,0 +1,48 @@
import { DebugLogger } from '@affine/debug';
import {
effect,
exhaustMapWithTrailing,
fromPromise,
Service,
} from '@toeverything/infra';
import {
catchError,
distinctUntilChanged,
EMPTY,
mergeMap,
throttleTime,
} from 'rxjs';
import type { AIButtonProvider } from '../provider/ai-button';
const logger = new DebugLogger('AIButtonService');
export class AIButtonService extends Service {
constructor(private readonly aiButtonProvider?: AIButtonProvider) {
super();
}
presentAIButton = effect(
distinctUntilChanged(),
throttleTime<boolean>(1000), // throttle time to avoid frequent calls
exhaustMapWithTrailing((present: boolean) => {
return fromPromise(async () => {
if (!this.aiButtonProvider) {
return;
}
if (present) {
await this.aiButtonProvider.presentAIButton();
} else {
await this.aiButtonProvider.dismissAIButton();
}
return;
}).pipe(
mergeMap(() => EMPTY),
catchError(err => {
logger.error('presentAIButton error', err);
return EMPTY;
})
);
})
);
}

View File

@@ -1,6 +1,7 @@
import { configureQuotaModule } from '@affine/core/modules/quota';
import { type Framework } from '@toeverything/infra';
import { configureAIButtonModule } from './ai-button';
import { configureAppSidebarModule } from './app-sidebar';
import { configAtMenuConfigModule } from './at-menu-config';
import { configureCloudModule } from './cloud';
@@ -88,4 +89,5 @@ export function configureCommonModules(framework: Framework) {
configAtMenuConfigModule(framework);
configureDndModule(framework);
configureCommonGlobalStorageImpls(framework);
configureAIButtonModule(framework);
}

View File

@@ -67,6 +67,7 @@ export function configureWorkspaceModule(framework: Framework) {
.service(WorkspaceRepositoryService, [
WorkspaceFlavoursService,
WorkspaceProfileService,
WorkspaceListService,
])
.scope(WorkspaceScope)
.service(WorkspaceService)

View File

@@ -7,6 +7,7 @@ import type { WorkspaceOpenOptions } from '../open-options';
import type { WorkspaceEngineProvider } from '../providers/flavour';
import { WorkspaceScope } from '../scopes/workspace';
import type { WorkspaceFlavoursService } from './flavours';
import type { WorkspaceListService } from './list';
import type { WorkspaceProfileService } from './profile';
import { WorkspaceService } from './workspace';
@@ -15,7 +16,8 @@ const logger = new DebugLogger('affine:workspace-repository');
export class WorkspaceRepositoryService extends Service {
constructor(
private readonly flavoursService: WorkspaceFlavoursService,
private readonly profileRepo: WorkspaceProfileService
private readonly profileRepo: WorkspaceProfileService,
private readonly workspacesListService: WorkspaceListService
) {
super();
}
@@ -73,6 +75,12 @@ export class WorkspaceRepositoryService extends Service {
};
};
openByWorkspaceId = (workspaceId: string) => {
const workspaceMetadata =
this.workspacesListService.list.workspace$(workspaceId).value;
return workspaceMetadata && this.open({ metadata: workspaceMetadata });
};
instantiate(
openOptions: WorkspaceOpenOptions,
customProvider?: WorkspaceEngineProvider

View File

@@ -42,6 +42,10 @@ export class WorkspacesService extends Service {
return this.workspaceRepo.open;
}
get openByWorkspaceId() {
return this.workspaceRepo.openByWorkspaceId;
}
get create() {
return this.workspaceFactory.create;
}