feat(core): add enable url preview to workspace settings (#8089)

This commit is contained in:
JimmFly
2024-09-10 04:04:05 +00:00
parent fe1eefdbb2
commit 9d343bdaa6
12 changed files with 276 additions and 0 deletions
@@ -19,6 +19,7 @@ import { configurePermissionsModule } from './permissions';
import { configureWorkspacePropertiesModule } from './properties';
import { configureQuickSearchModule } from './quicksearch';
import { configureShareDocsModule } from './share-doc';
import { configureShareSettingModule } from './share-setting';
import { configureSystemFontFamilyModule } from './system-font-family';
import { configureTagModule } from './tag';
import { configureTelemetryModule } from './telemetry';
@@ -34,6 +35,7 @@ export function configureCommonModules(framework: Framework) {
configureQuotaModule(framework);
configurePermissionsModule(framework);
configureShareDocsModule(framework);
configureShareSettingModule(framework);
configureTelemetryModule(framework);
configureFindInPageModule(framework);
configurePeekViewModule(framework);
@@ -0,0 +1,80 @@
import { DebugLogger } from '@affine/debug';
import type { GetEnableUrlPreviewQuery } from '@affine/graphql';
import type { WorkspaceService } from '@toeverything/infra';
import {
backoffRetry,
catchErrorInto,
effect,
Entity,
fromPromise,
LiveData,
mapInto,
onComplete,
onStart,
} from '@toeverything/infra';
import { exhaustMap } from 'rxjs';
import { isBackendError, isNetworkError } from '../../cloud';
import type { WorkspaceShareSettingStore } from '../stores/share-setting';
type EnableUrlPreview =
GetEnableUrlPreviewQuery['workspace']['enableUrlPreview'];
const logger = new DebugLogger('affine:workspace-permission');
export class WorkspaceShareSetting extends Entity {
enableUrlPreview$ = new LiveData<EnableUrlPreview | null>(null);
isLoading$ = new LiveData(false);
error$ = new LiveData<any>(null);
constructor(
private readonly workspaceService: WorkspaceService,
private readonly store: WorkspaceShareSettingStore
) {
super();
this.revalidate();
}
revalidate = effect(
exhaustMap(() => {
return fromPromise(signal =>
this.store.fetchWorkspaceEnableUrlPreview(
this.workspaceService.workspace.id,
signal
)
).pipe(
backoffRetry({
when: isNetworkError,
count: Infinity,
}),
backoffRetry({
when: isBackendError,
count: 3,
}),
mapInto(this.enableUrlPreview$),
catchErrorInto(this.error$, error => {
logger.error('Failed to fetch enableUrlPreview', error);
}),
onStart(() => this.isLoading$.setValue(true)),
onComplete(() => this.isLoading$.setValue(false))
);
})
);
async waitForRevalidation(signal?: AbortSignal) {
this.revalidate();
await this.isLoading$.waitFor(isLoading => !isLoading, signal);
}
async setEnableUrlPreview(enableUrlPreview: EnableUrlPreview) {
await this.store.updateWorkspaceEnableUrlPreview(
this.workspaceService.workspace.id,
enableUrlPreview
);
await this.waitForRevalidation();
}
override dispose(): void {
this.revalidate.unsubscribe();
}
}
@@ -0,0 +1,23 @@
export { WorkspaceShareSettingService } from './services/share-setting';
import { GraphQLService } from '@affine/core/modules/cloud';
import {
type Framework,
WorkspaceScope,
WorkspaceService,
} from '@toeverything/infra';
import { WorkspaceShareSetting } from './entities/share-setting';
import { WorkspaceShareSettingService } from './services/share-setting';
import { WorkspaceShareSettingStore } from './stores/share-setting';
export function configureShareSettingModule(framework: Framework) {
framework
.scope(WorkspaceScope)
.service(WorkspaceShareSettingService)
.store(WorkspaceShareSettingStore, [GraphQLService])
.entity(WorkspaceShareSetting, [
WorkspaceService,
WorkspaceShareSettingStore,
]);
}
@@ -0,0 +1,7 @@
import { Service } from '@toeverything/infra';
import { WorkspaceShareSetting } from '../entities/share-setting';
export class WorkspaceShareSettingService extends Service {
sharePreview = this.framework.createEntity(WorkspaceShareSetting);
}
@@ -0,0 +1,45 @@
import type { GraphQLService } from '@affine/core/modules/cloud';
import {
getEnableUrlPreviewQuery,
setEnableUrlPreviewMutation,
} from '@affine/graphql';
import { Store } from '@toeverything/infra';
export class WorkspaceShareSettingStore extends Store {
constructor(private readonly graphqlService: GraphQLService) {
super();
}
async fetchWorkspaceEnableUrlPreview(
workspaceId: string,
signal?: AbortSignal
) {
const data = await this.graphqlService.gql({
query: getEnableUrlPreviewQuery,
variables: {
id: workspaceId,
},
context: {
signal,
},
});
return data.workspace.enableUrlPreview;
}
async updateWorkspaceEnableUrlPreview(
workspaceId: string,
enableUrlPreview: boolean,
signal?: AbortSignal
) {
await this.graphqlService.gql({
query: setEnableUrlPreviewMutation,
variables: {
id: workspaceId,
enableUrlPreview,
},
context: {
signal,
},
});
}
}