forked from microsoft/BotFramework-WebChat
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcreateActivityPolymiddlewareFromLegacy.tsx
More file actions
118 lines (102 loc) · 3.83 KB
/
createActivityPolymiddlewareFromLegacy.tsx
File metadata and controls
118 lines (102 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { type WebChatActivity } from 'botframework-webchat-core';
import { composeEnhancer } from 'handler-chain';
import { type ComponentType, type ReactNode } from 'react';
import {
boolean,
custom,
function_,
literal,
never,
object,
optional,
pipe,
readonly,
safeParse,
union,
type InferInput
} from 'valibot';
import {
activityComponent,
createActivityPolymiddleware,
type ActivityPolymiddleware
} from '../activityPolymiddleware';
import { type LegacyActivityMiddleware } from '../legacy/activityMiddleware';
import { type LegacyRenderAttachment } from '../legacy/attachmentMiddleware';
const webChatActivitySchema = custom<WebChatActivity>(value => safeParse(object({}), value).success);
type LegacyRenderFunction = (
renderAttachment: LegacyRenderAttachment,
options: {
readonly hideTimestamp: boolean;
readonly renderActivityStatus: (options: { hideTimestamp: boolean }) => ReactNode;
readonly renderAvatar: false | (() => Exclude<ReactNode, boolean | null | undefined>);
readonly showCallout: boolean;
}
) => Exclude<ReactNode, boolean>;
const legacyActivityBridgeComponentPropsSchema = pipe(
object({
activity: webChatActivitySchema,
children: optional(never()),
render: custom<LegacyRenderFunction>(value => safeParse(function_(), value).success),
// The following extraneous props should be removed once `useCreateActivityRenderer()` is removed.
hideTimestamp: optional(boolean()),
renderActivityStatus: optional(
custom<(options: { hideTimestamp: boolean }) => ReactNode>(value => safeParse(function_(), value).success)
),
renderAvatar: optional(
union([
literal(false),
custom<() => Exclude<ReactNode, boolean | null | undefined>>(value => safeParse(function_(), value).success)
])
),
showCallout: optional(boolean())
}),
readonly()
);
type LegacyActivityBridgeComponentProps = Readonly<
InferInput<typeof legacyActivityBridgeComponentPropsSchema> & { children?: never }
>;
const fallbackComponentPropsSchema = pipe(
object({
activity: webChatActivitySchema,
children: optional(never())
}),
readonly()
);
type FallbackComponentProps = Readonly<InferInput<typeof fallbackComponentPropsSchema> & { children?: never }>;
interface RenderFallbackComponentCallback {
// Returns { render(): ReactNode } so we don't confuse with function component.
(request: { activity: WebChatActivity }): { readonly render: () => ReactNode };
}
function createActivityPolymiddlewareFromLegacy(
bridgeComponent: ComponentType<LegacyActivityBridgeComponentProps>,
// Use lowercase for argument name, but we need uppercase for JSX.
renderFallbackComponent: RenderFallbackComponentCallback,
...middleware: readonly LegacyActivityMiddleware[]
): ActivityPolymiddleware;
function createActivityPolymiddlewareFromLegacy(
bridgeComponent: ComponentType<LegacyActivityBridgeComponentProps>,
renderFallbackComponent: RenderFallbackComponentCallback,
...middleware: readonly LegacyActivityMiddleware[]
): ActivityPolymiddleware {
const legacyEnhancer = composeEnhancer(...middleware.map(middleware => middleware()));
return createActivityPolymiddleware(() => {
const legacyHandler = legacyEnhancer(
request => () => renderFallbackComponent({ activity: request.activity })?.render()
);
return ({ activity }) => {
const legacyResult = legacyHandler({ activity });
if (!legacyResult) {
// Legacy cannot fallback to poly middleware due to signature incompatibility.
return undefined;
}
return activityComponent(bridgeComponent, { activity, render: legacyResult });
};
});
}
export default createActivityPolymiddlewareFromLegacy;
export {
fallbackComponentPropsSchema,
legacyActivityBridgeComponentPropsSchema,
type FallbackComponentProps,
type LegacyActivityBridgeComponentProps
};