mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 06:16:59 +08:00
fix: patch service syntax (#7080)
Not sure if there is a better pattern like "macros" that can make this more generic. 🤡 also added notify impl to notification service for bs https://github.com/toeverything/blocksuite/pull/7160
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
createReactComponentFromLit,
|
createReactComponentFromLit,
|
||||||
type ElementOrFactory,
|
type ElementOrFactory,
|
||||||
|
notify,
|
||||||
toast,
|
toast,
|
||||||
type ToastOptions,
|
type ToastOptions,
|
||||||
type useConfirmModal,
|
type useConfirmModal,
|
||||||
@@ -12,7 +13,7 @@ import type {
|
|||||||
RootService,
|
RootService,
|
||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { LitElement, type TemplateResult } from 'lit';
|
import { LitElement, type TemplateResult } from 'lit';
|
||||||
import React from 'react';
|
import React, { createElement, type ReactNode } from 'react';
|
||||||
|
|
||||||
export type ReferenceReactRenderer = (
|
export type ReferenceReactRenderer = (
|
||||||
reference: AffineReference
|
reference: AffineReference
|
||||||
@@ -42,6 +43,36 @@ const TemplateWrapper = createReactComponentFromLit({
|
|||||||
react: React,
|
react: React,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const toReactNode = (template?: TemplateResult | string): ReactNode => {
|
||||||
|
if (!template) return null;
|
||||||
|
return typeof template === 'string'
|
||||||
|
? template
|
||||||
|
: createElement(TemplateWrapper, { template });
|
||||||
|
};
|
||||||
|
|
||||||
|
function patchSpecService<Spec extends BlockSpec>(
|
||||||
|
spec: Spec,
|
||||||
|
onMounted: (
|
||||||
|
service: Spec extends BlockSpec<any, infer BlockService>
|
||||||
|
? BlockService
|
||||||
|
: never
|
||||||
|
) => (() => void) | void
|
||||||
|
) {
|
||||||
|
const oldSetup = spec.setup;
|
||||||
|
spec.setup = (slots, disposableGroup) => {
|
||||||
|
oldSetup?.(slots, disposableGroup);
|
||||||
|
disposableGroup.add(
|
||||||
|
slots.mounted.on(({ service }) => {
|
||||||
|
const disposable = onMounted(service as any);
|
||||||
|
if (disposable) {
|
||||||
|
disposableGroup.add(disposable);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch the block specs with custom renderers.
|
* Patch the block specs with custom renderers.
|
||||||
*/
|
*/
|
||||||
@@ -61,15 +92,15 @@ export function patchReferenceRenderer(
|
|||||||
spec.schema.model.flavour
|
spec.schema.model.flavour
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// todo: remove these type assertions
|
spec = patchSpecService(
|
||||||
spec.service = class extends (
|
spec as BlockSpec<string, ParagraphBlockService>,
|
||||||
(spec.service as typeof ParagraphBlockService)
|
service => {
|
||||||
) {
|
service.referenceNodeConfig.setCustomContent(litRenderer);
|
||||||
override mounted() {
|
return () => {
|
||||||
super.mounted();
|
service.referenceNodeConfig.setCustomContent(null);
|
||||||
this.referenceNodeConfig.setCustomContent(litRenderer);
|
};
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec;
|
return spec;
|
||||||
@@ -82,14 +113,14 @@ export function patchNotificationService(
|
|||||||
) {
|
) {
|
||||||
const rootSpec = specs.find(
|
const rootSpec = specs.find(
|
||||||
spec => spec.schema.model.flavour === 'affine:page'
|
spec => spec.schema.model.flavour === 'affine:page'
|
||||||
);
|
) as BlockSpec<string, RootService>;
|
||||||
|
|
||||||
if (!rootSpec) {
|
if (!rootSpec) {
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
rootSpec.service = class extends (rootSpec.service as typeof RootService) {
|
patchSpecService(rootSpec, service => {
|
||||||
override notificationService = {
|
service.notificationService = {
|
||||||
confirm: async ({
|
confirm: async ({
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
@@ -106,12 +137,7 @@ export function patchNotificationService(
|
|||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
openConfirmModal({
|
openConfirmModal({
|
||||||
title,
|
title,
|
||||||
description:
|
description: toReactNode(message),
|
||||||
typeof message === 'string' ? (
|
|
||||||
message
|
|
||||||
) : (
|
|
||||||
<TemplateWrapper template={message} />
|
|
||||||
),
|
|
||||||
confirmButtonOptions: {
|
confirmButtonOptions: {
|
||||||
children: confirmText,
|
children: confirmText,
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
@@ -133,8 +159,34 @@ export function patchNotificationService(
|
|||||||
toast: (message: string, options: ToastOptions) => {
|
toast: (message: string, options: ToastOptions) => {
|
||||||
return toast(message, options);
|
return toast(message, options);
|
||||||
},
|
},
|
||||||
notify: async () => {},
|
notify: notification => {
|
||||||
|
const accentToNotify = {
|
||||||
|
error: notify.error,
|
||||||
|
success: notify.success,
|
||||||
|
warning: notify.warning,
|
||||||
|
info: notify,
|
||||||
|
};
|
||||||
|
|
||||||
|
const fn = accentToNotify[notification.accent || 'info'];
|
||||||
|
if (!fn) {
|
||||||
|
throw new Error('Invalid notification accent');
|
||||||
|
}
|
||||||
|
|
||||||
|
const toastId = fn(
|
||||||
|
{
|
||||||
|
title: toReactNode(notification.title),
|
||||||
|
message: toReactNode(notification.message),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
duration: notification.duration || 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
notification.abort?.addEventListener('abort', () => {
|
||||||
|
notify.dismiss(toastId);
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user