Skip to content

Commit 84969c2

Browse files
compulimOEvgeny
andauthored
Livestreaming informative message (#5265)
* Add getLivestreamingActivityType * Decorate as completion * Rename requests * Fix typing * Get stream session ID * Use getLivestreamingActivityMetadata * Add comment * Fix tests * Rename to decorateForLivestreaming and fix tests * Fix typing indicator test * Should not render typing indicator activity * Clean up if-statement * Fix test * Fix snapshot * Fix test * Fix tests * Add rule for streamSequence * Clean up comment * Update comment * Clean up tests * Clean up * Update comment * Add "preparing" decoration * Add entry * Typo * Add LIVESTREAMING.md * Clean up * Sort * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Verbiage * Update packages/component/src/Activity/StackedLayout.tsx Co-authored-by: Eugene <[email protected]> * Rename to livestreamingState --------- Co-authored-by: Eugene <[email protected]>
1 parent 2dbeed3 commit 84969c2

33 files changed

+775
-214
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
3939
- Updated Fluent theme styling to improve accessibility and visual consistency, in PR [#5258](https://github.com/microsoft/BotFramework-WebChat/pull/5258), by [@OEvgeny](https://github.com/OEvgeny)
4040
- Fixed header font in copilot variant, in PR [#5261](https://github.com/microsoft/BotFramework-WebChat/pull/5261), by [@OEvgeny](https://github.com/OEvgeny)
4141
- Added "Copy" button to bot messages in Fluent UI if it contains keyword `AllowCopy`, in PR [#5259](https://github.com/microsoft/BotFramework-WebChat/pull/5259) and [#5262](https://github.com/microsoft/BotFramework-WebChat/pull/5262), by [@compulim](https://github.com/compulim)
42+
- Resolves [#4876](https://github.com/microsoft/BotFramework-WebChat/issues/4876) and [#4939](https://github.com/microsoft/BotFramework-WebChat/issues/4939). Added support of informative message in livestreaming, by [@compulim](https://github.com/compulim), in PR [#5265](https://github.com/microsoft/BotFramework-WebChat/pull/5265)
4243

4344
### Changed
4445

Loading
Loading

__tests__/html/fluentTheme/withDecorator.html

+22-33
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
const {
2828
React,
2929
ReactDOM: { render },
30-
WebChat: {
30+
WebChat: {
3131
decorator: { DecoratorComposer },
3232
FluentThemeProvider,
3333
ReactWebChat
@@ -43,20 +43,26 @@
4343
}
4444

4545
const decoratorMiddleware = [
46-
init => init === 'activity border' && (next => request => (request.state === 'completion' ? Flair : next(request))),
47-
init => init === 'activity border' && (next => request => (request.state === 'informative' ? Loader : next(request)))
46+
init =>
47+
init === 'activity border' &&
48+
(next => request => (request.livestreamingState === 'completing' ? Flair : next(request))),
49+
init =>
50+
init === 'activity border' &&
51+
(next => request => (request.livestreamingState === 'preparing' ? Loader : next(request)))
4852
];
4953

5054
const { directLine, store } = testHelpers.createDirectLineEmulator();
5155

52-
const App = () => <ReactWebChat
53-
directLine={directLine}
54-
store={store}
55-
styleOptions={{
56-
bubbleBorderRadius: 10,
57-
typingAnimationBackgroundImage: `url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUACgDASIAAhEBAxEB/8QAGgABAQACAwAAAAAAAAAAAAAAAAYCBwMFCP/EACsQAAECBQIEBQUAAAAAAAAAAAECAwAEBQYRBxITIjFBMlFhccFScoGh8f/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwD0lctx023JVD9UeKOIcNoSNylkdcCMbauSmXHLOPUx8r4ZAcQtO1SM9Mj5iO1gtWo1syc7S2zMKYSptbIPNgnII8/5HBpRZ9RpaKjNVVCpUzLPAQ1nmA7qPl6fmAondRrcaqhkVTiiQrYXgglsH7vnpHc3DcNNoEimaqT4Q2s4bCRuUs+gEaLd05uNFVMmiS3o3YEwFDhlP1Z7e3WLzUuzahUKHRk0zM07TmeApvOFLGEjcM9+Xp6wFnbN0Uu5GnF0x4qW1je2tO1Sc9Djy9oRD6QWlU6PPzVSqjRlgtksttKPMcqBKiO3h/cIDacIQgEIQgEIQgP/2Q==')`
58-
}}
59-
/>;
56+
const App = () => (
57+
<ReactWebChat
58+
directLine={directLine}
59+
store={store}
60+
styleOptions={{
61+
bubbleBorderRadius: 10,
62+
typingAnimationBackgroundImage: `url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUACgDASIAAhEBAxEB/8QAGgABAQACAwAAAAAAAAAAAAAAAAYCBwMFCP/EACsQAAECBQIEBQUAAAAAAAAAAAECAwAEBQYRBxITIjFBMlFhccFScoGh8f/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwD0lctx023JVD9UeKOIcNoSNylkdcCMbauSmXHLOPUx8r4ZAcQtO1SM9Mj5iO1gtWo1syc7S2zMKYSptbIPNgnII8/5HBpRZ9RpaKjNVVCpUzLPAQ1nmA7qPl6fmAondRrcaqhkVTiiQrYXgglsH7vnpHc3DcNNoEimaqT4Q2s4bCRuUs+gEaLd05uNFVMmiS3o3YEwFDhlP1Z7e3WLzUuzahUKHRk0zM07TmeApvOFLGEjcM9+Xp6wFnbN0Uu5GnF0x4qW1je2tO1Sc9Djy9oRD6QWlU6PPzVSqjRlgtksttKPMcqBKiO3h/cIDacIQgEIQgEIQgP/2Q==')`
63+
}}
64+
/>
65+
);
6066

6167
render(
6268
<FluentThemeProvider>
@@ -70,23 +76,7 @@
7076
await pageConditions.uiConnected();
7177

7278
await directLine.emulateIncomingActivity({
73-
channelData: {
74-
streamType: 'informative'
75-
},
76-
from: {
77-
id: 'u-00001',
78-
name: 'Bot',
79-
role: 'bot'
80-
},
81-
id: 'm-00001',
82-
text: 'Working on it...',
83-
type: 'message'
84-
});
85-
86-
await directLine.emulateIncomingActivity({
87-
channelData: {
88-
streamType: 'informative'
89-
},
79+
channelData: { streamSequence: 1, streamType: 'informative' },
9080
from: {
9181
id: 'u-00001',
9282
name: 'Bot',
@@ -97,7 +87,6 @@
9787
type: 'typing'
9888
});
9989

100-
await pageConditions.typingIndicatorShown();
10190
await pageConditions.numActivitiesShown(1);
10291
await host.snapshot();
10392

@@ -128,15 +117,15 @@
128117
}
129118
];
130119
await directLine.emulateIncomingActivity({
131-
id: 'm-00001',
120+
attachments,
121+
channelData: { streamId: 't-00001', streamSequence: 2, streamType: 'final' },
132122
from: {
133123
id: 'u-00001',
134124
name: 'Bot',
135125
role: 'bot'
136126
},
137-
text: 'Work completed!',
138-
channelData: { streamType: 'completion' },
139-
attachments
127+
id: 'm-00001',
128+
text: 'Work completed!'
140129
});
141130

142131
await pageConditions.numActivitiesShown(1);

__tests__/html/hooks.useActiveTyping.livestream.html

+25
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,16 @@
5555

5656
// WHEN: Bot livestream.
5757
await directLine.emulateIncomingActivity({
58+
channelData: {
59+
streamSequence: 1,
60+
streamType: 'streaming'
61+
},
5862
from: {
5963
id: 'bot',
6064
name: 'Bot',
6165
role: 'bot'
6266
},
67+
id: 'a-00001',
6368
text: 'Et est esse aliqua culpa quis laboris exercitation voluptate dolor.',
6469
type: 'typing'
6570
});
@@ -76,6 +81,26 @@
7681
}
7782
}
7883
]);
84+
85+
// WHEN: Bot livestream ended.
86+
await directLine.emulateIncomingActivity({
87+
channelData: {
88+
streamId: 'a-00001',
89+
streamSequence: 2,
90+
streamType: 'final'
91+
},
92+
from: {
93+
id: 'bot',
94+
name: 'Bot',
95+
role: 'bot'
96+
},
97+
id: 'a-00002',
98+
text: 'Et est esse aliqua culpa quis laboris exercitation voluptate dolor.',
99+
type: 'message'
100+
});
101+
102+
// THEN: `useActiveTyping` should return empty.
103+
await expect(renderWithFunction(() => useActiveTyping())).resolves.toEqual([{}]);
79104
});
80105
</script>
81106
</body>

__tests__/html/scrollToEndButton.typingChunk.html __tests__/html/scrollToEndButton.livestreaming.html

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
// WHEN: Receive a bot typing message.
6060
await directLine.emulateIncomingActivity({
61+
channelData: { streamSequence: 1, streamType: 'streaming' },
6162
from: { role: 'bot' },
6263
text: 'Amet consequat ex duis',
6364
type: 'typing'
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */
22

33
describe('scroll to end button', () => {
4-
test('should show for typing chunks.', () => runHTML('scrollToEndButton.typingChunk.html'));
4+
test('should show for livestreaming session', () => runHTML('scrollToEndButton.livestreaming.html'));
55
});

__tests__/html/typing/activityOrder.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
const firstTypingActivityId = 't-00001';
6262

6363
await directLine.emulateIncomingActivity({
64-
channelData: { streamType: 'streaming' },
64+
channelData: { streamSequence: 1, streamType: 'streaming' },
6565
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
6666
id: firstTypingActivityId,
6767
text: 'A quick',
@@ -122,7 +122,7 @@
122122

123123
// WHEN: Bot continue typing the message.
124124
await directLine.emulateIncomingActivity({
125-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
125+
channelData: { streamId: firstTypingActivityId, streamSequence: 2, streamType: 'streaming' },
126126
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
127127
id: 't-00002',
128128
text: 'A quick brown fox',
@@ -154,7 +154,7 @@
154154

155155
// WHEN: Bot continue typing the message.
156156
await directLine.emulateIncomingActivity({
157-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
157+
channelData: { streamId: firstTypingActivityId, streamSequence: 3, streamType: 'streaming' },
158158
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
159159
id: 't-00003',
160160
text: 'A quick brown fox jumped over',
@@ -186,7 +186,7 @@
186186

187187
// WHEN: Bot finished typing the message.
188188
await directLine.emulateIncomingActivity({
189-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
189+
channelData: { streamId: firstTypingActivityId, streamSequence: 4, streamType: 'streaming' },
190190
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
191191
id: 'a-00002',
192192
text: 'A quick brown fox jumped over the lazy dogs.',

__tests__/html/typing/chunk.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
const firstTypingActivityId = 't-00001';
6262

6363
await directLine.emulateIncomingActivity({
64-
channelData: { streamType: 'streaming' },
64+
channelData: { streamSequence: 1, streamType: 'streaming' },
6565
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
6666
id: firstTypingActivityId,
6767
text: 'A quick',
@@ -90,7 +90,7 @@
9090

9191
// WHEN: Bot continue typing the message.
9292
await directLine.emulateIncomingActivity({
93-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
93+
channelData: { streamId: firstTypingActivityId, streamSequence: 2, streamType: 'streaming' },
9494
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
9595
id: 't-00002',
9696
text: 'A quick brown fox',
@@ -117,7 +117,7 @@
117117

118118
// WHEN: Bot continue typing the message.
119119
await directLine.emulateIncomingActivity({
120-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
120+
channelData: { streamId: firstTypingActivityId, streamSequence: 3, streamType: 'streaming' },
121121
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
122122
id: 't-00003',
123123
text: 'A quick brown fox jumped over',
@@ -142,7 +142,7 @@
142142

143143
// WHEN: Bot finished typing the message.
144144
await directLine.emulateIncomingActivity({
145-
channelData: { streamId: firstTypingActivityId, streamType: 'streaming' },
145+
channelData: { streamId: firstTypingActivityId, streamSequence: 4, streamType: 'streaming' },
146146
from: { id: 'u-00001', name: 'Bot', role: 'bot' },
147147
id: 'a-00002',
148148
text: 'A quick brown fox jumped over the lazy dogs.',

__tests__/html/typing/informative.html

+9-3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
// WHEN: An informative message is received.
4343
await directLine.emulateIncomingActivity({
4444
channelData: {
45+
streamSequence: 1,
4546
streamType: 'informative'
4647
},
4748
from: {
@@ -54,9 +55,14 @@
5455
type: 'typing'
5556
});
5657

57-
// THEN: Should render the typing indicator for informative typing message.
58-
await pageConditions.numActivitiesShown(1);
59-
await pageConditions.typingIndicatorShown();
58+
// THEN: Should render the informative message.
59+
expect(pageElements.activityContents()[0]).toHaveProperty(
60+
'textContent',
61+
'Adipisicing cupidatat eu Lorem anim ut aute magna occaecat id cillum.\n'
62+
);
63+
expect(pageElements.activityContents()[1]).toHaveProperty('textContent', 'Nisi elit quis nisi consectetur.\n');
64+
65+
await pageConditions.numActivitiesShown(2);
6066
await host.snapshot();
6167
});
6268
</script>

0 commit comments

Comments
 (0)