mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-25 18:26:05 +08:00
feat(core): add enable url preview to workspace settings (#8089)
This commit is contained in:
@@ -17,6 +17,7 @@ import { ExportPanel } from './export';
|
||||
import { LabelsPanel } from './labels';
|
||||
import { MembersPanel } from './members';
|
||||
import { ProfilePanel } from './profile';
|
||||
import { SharingPanel } from './sharing';
|
||||
import type { WorkspaceSettingDetailProps } from './types';
|
||||
|
||||
export const WorkspaceSettingDetail = ({
|
||||
@@ -67,6 +68,7 @@ export const WorkspaceSettingDetail = ({
|
||||
<EnableCloudPanel />
|
||||
<MembersPanel />
|
||||
</SettingWrapper>
|
||||
<SharingPanel />
|
||||
{environment.isElectron && (
|
||||
<SettingWrapper title={t['Storage and Export']()}>
|
||||
<ExportPanel
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Switch } from '@affine/component';
|
||||
import {
|
||||
SettingRow,
|
||||
SettingWrapper,
|
||||
} from '@affine/component/setting-components';
|
||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||
import { WorkspaceShareSettingService } from '@affine/core/modules/share-setting';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
|
||||
|
||||
export const SharingPanel = () => {
|
||||
const workspace = useService(WorkspaceService).workspace;
|
||||
if (workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||
return null;
|
||||
}
|
||||
return <Sharing />;
|
||||
};
|
||||
|
||||
export const Sharing = () => {
|
||||
const t = useI18n();
|
||||
const shareSetting = useService(WorkspaceShareSettingService).sharePreview;
|
||||
const enableUrlPreview = useLiveData(shareSetting.enableUrlPreview$);
|
||||
const loading = useLiveData(shareSetting.isLoading$);
|
||||
|
||||
const handleCheck = useAsyncCallback(
|
||||
async (checked: boolean) => {
|
||||
await shareSetting.setEnableUrlPreview(checked);
|
||||
},
|
||||
[shareSetting]
|
||||
);
|
||||
|
||||
return (
|
||||
<SettingWrapper title={t['com.affine.settings.workspace.sharing.title']()}>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.workspace.sharing.url-preview.title']()}
|
||||
desc={t[
|
||||
'com.affine.settings.workspace.sharing.url-preview.description'
|
||||
]()}
|
||||
>
|
||||
<Switch
|
||||
checked={enableUrlPreview || false}
|
||||
onChange={handleCheck}
|
||||
disabled={loading}
|
||||
/>
|
||||
</SettingRow>
|
||||
</SettingWrapper>
|
||||
);
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
23
packages/frontend/core/src/modules/share-setting/index.ts
Normal file
23
packages/frontend/core/src/modules/share-setting/index.ts
Normal file
@@ -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,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user