botbuilder-core
Advanced tools
Comparing version 4.11.0-dev.20200921.00cab05 to 4.11.0-dev.20200924.ca751f7
@@ -16,4 +16,2 @@ import { Middleware } from './middlewareSet'; | ||
private readonly period; | ||
private interval; | ||
private finished; | ||
/** | ||
@@ -20,0 +18,0 @@ * Create the SendTypingIndicator middleware |
@@ -37,2 +37,4 @@ "use strict"; | ||
constructor(delay = 500, period = 2000) { | ||
this.delay = delay; | ||
this.period = period; | ||
if (delay < 0) { | ||
@@ -44,4 +46,2 @@ throw new Error('Delay must be greater than or equal to zero'); | ||
} | ||
this.delay = delay; | ||
this.period = period; | ||
} | ||
@@ -55,45 +55,30 @@ /** Implement middleware signature | ||
let finished = false; | ||
let hTimeout = undefined; | ||
/** | ||
* @param context TurnContext object representing incoming message. | ||
* @param delay The initial delay before sending the first indicator. | ||
* @param period How often to send the indicator after the first. | ||
*/ | ||
function startInterval(context, delay, period) { | ||
hTimeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () { | ||
let timeout; | ||
const scheduleIndicator = (delay = this.delay) => { | ||
timeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () { | ||
if (!finished) { | ||
let typingActivity = { | ||
type: botframework_schema_1.ActivityTypes.Typing, | ||
relatesTo: context.activity.relatesTo | ||
}; | ||
// Sending the Activity directly via the Adapter avoids other middleware and avoids setting the | ||
// responded flag. However this also requires that the conversation reference details are explicitly added. | ||
const conversationReference = turnContext_1.TurnContext.getConversationReference(context.activity); | ||
typingActivity = turnContext_1.TurnContext.applyConversationReference(typingActivity, conversationReference); | ||
yield context.adapter.sendActivities(context, [typingActivity]); | ||
// Pass in period as the delay to repeat at an interval. | ||
startInterval(context, period, period); | ||
try { | ||
yield this.sendTypingActivity(context); | ||
} | ||
catch (err) { | ||
if (context.adapter && context.adapter.onTurnError) { | ||
yield context.adapter.onTurnError(context, err); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
scheduleIndicator(this.period); | ||
} | ||
else { | ||
// Do nothing! This turn is done and we don't want to continue sending typing indicators. | ||
} | ||
}), delay); | ||
} | ||
}; | ||
if (context.activity.type === botframework_schema_1.ActivityTypes.Message) { | ||
// Set a property to track whether or not the turn is finished. | ||
// When it flips to true, we won't send anymore typing indicators. | ||
finished = false; | ||
startInterval(context, this.delay, this.period); | ||
scheduleIndicator(); | ||
} | ||
// Let the rest of the process run. | ||
// After everything has run, stop the indicator! | ||
try { | ||
return yield next(); | ||
} | ||
finally { | ||
finished = true; | ||
if (hTimeout) { | ||
clearTimeout(hTimeout); | ||
} | ||
} | ||
// Execute remaining middleware, then clear scheduled indicators | ||
yield next(); | ||
finished = true; | ||
if (timeout) | ||
clearTimeout(timeout); | ||
}); | ||
@@ -103,10 +88,9 @@ } | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let typingActivity = { | ||
type: botframework_schema_1.ActivityTypes.Typing, | ||
relatesTo: context.activity.relatesTo | ||
}; | ||
// Sending the Activity directly via the Adapter avoids other middleware and avoids setting the | ||
// responded flag. However this also requires that the conversation reference details are explicitly added. | ||
const conversationReference = turnContext_1.TurnContext.getConversationReference(context.activity); | ||
typingActivity = turnContext_1.TurnContext.applyConversationReference(typingActivity, conversationReference); | ||
const typingActivity = turnContext_1.TurnContext.applyConversationReference({ | ||
type: botframework_schema_1.ActivityTypes.Typing, | ||
relatesTo: context.activity.relatesTo | ||
}, conversationReference); | ||
yield context.adapter.sendActivities(context, [typingActivity]); | ||
@@ -113,0 +97,0 @@ }); |
@@ -5,3 +5,3 @@ { | ||
"description": "Core components for Microsoft Bot Builder. Components in this library can run either in a browser or on the server.", | ||
"version": "4.11.0-dev.20200921.00cab05", | ||
"version": "4.11.0-dev.20200924.ca751f7", | ||
"license": "MIT", | ||
@@ -25,3 +25,3 @@ "keywords": [ | ||
"assert": "^1.4.1", | ||
"botframework-schema": "4.11.0-dev.20200921.00cab05" | ||
"botframework-schema": "4.11.0-dev.20200924.ca751f7" | ||
}, | ||
@@ -44,3 +44,3 @@ "devDependencies": { | ||
"clean": "erase /q /s .\\lib", | ||
"set-version": "npm version --allow-same-version 4.11.0-dev.20200921.00cab05", | ||
"set-version": "npm version --allow-same-version 4.11.0-dev.20200924.ca751f7", | ||
"test": "tsc && nyc mocha tests/", | ||
@@ -47,0 +47,0 @@ "test:compat": "api-extractor run --verbose" |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
import { Activity, ActivityTypes, ConversationReference } from 'botframework-schema'; | ||
import { ActivityTypes } from 'botframework-schema'; | ||
import { Middleware } from './middlewareSet'; | ||
@@ -24,7 +24,2 @@ import { TurnContext } from './turnContext'; | ||
export class ShowTypingMiddleware implements Middleware { | ||
private readonly delay: number; | ||
private readonly period: number; | ||
private interval: any; | ||
private finished: boolean; | ||
/** | ||
@@ -35,3 +30,3 @@ * Create the SendTypingIndicator middleware | ||
*/ | ||
constructor(delay: number = 500, period: number = 2000) { | ||
constructor(private readonly delay: number = 500, private readonly period: number = 2000) { | ||
if (delay < 0) { | ||
@@ -44,5 +39,2 @@ throw new Error('Delay must be greater than or equal to zero'); | ||
} | ||
this.delay = delay; | ||
this.period = period; | ||
} | ||
@@ -54,75 +46,48 @@ | ||
*/ | ||
public async onTurn(context: TurnContext, next: () => Promise<void>): Promise<void> { | ||
public async onTurn(context: TurnContext, next: () => Promise<void>) { | ||
let finished = false; | ||
let hTimeout: any = undefined; | ||
let timeout: ReturnType<typeof setTimeout>; | ||
/** | ||
* @param context TurnContext object representing incoming message. | ||
* @param delay The initial delay before sending the first indicator. | ||
* @param period How often to send the indicator after the first. | ||
*/ | ||
function startInterval(context: TurnContext, delay: number, period: number): void { | ||
hTimeout = setTimeout( | ||
async () => { | ||
if (!finished) { | ||
let typingActivity: Partial<Activity> = { | ||
type: ActivityTypes.Typing, | ||
relatesTo: context.activity.relatesTo | ||
}; | ||
const scheduleIndicator = (delay = this.delay) => { | ||
timeout = setTimeout(async () => { | ||
if (!finished) { | ||
try { | ||
await this.sendTypingActivity(context); | ||
} catch (err) { | ||
if (context.adapter && context.adapter.onTurnError) { | ||
await context.adapter.onTurnError(context, err); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
// Sending the Activity directly via the Adapter avoids other middleware and avoids setting the | ||
// responded flag. However this also requires that the conversation reference details are explicitly added. | ||
const conversationReference: Partial<ConversationReference> = | ||
TurnContext.getConversationReference(context.activity); | ||
typingActivity = TurnContext.applyConversationReference(typingActivity, conversationReference); | ||
await context.adapter.sendActivities(context, [typingActivity]); | ||
// Pass in period as the delay to repeat at an interval. | ||
startInterval(context, period, period); | ||
} else { | ||
// Do nothing! This turn is done and we don't want to continue sending typing indicators. | ||
} | ||
}, | ||
delay | ||
); | ||
scheduleIndicator(this.period); | ||
} | ||
}, delay); | ||
} | ||
if (context.activity.type === ActivityTypes.Message) { | ||
// Set a property to track whether or not the turn is finished. | ||
// When it flips to true, we won't send anymore typing indicators. | ||
finished = false; | ||
startInterval(context, this.delay, this.period); | ||
scheduleIndicator(); | ||
} | ||
// Let the rest of the process run. | ||
// After everything has run, stop the indicator! | ||
try { | ||
return await next(); | ||
} | ||
finally | ||
{ | ||
finished = true; | ||
if (hTimeout) { | ||
clearTimeout(hTimeout); | ||
} | ||
} | ||
// Execute remaining middleware, then clear scheduled indicators | ||
await next(); | ||
finished = true; | ||
if (timeout) clearTimeout(timeout); | ||
} | ||
private async sendTypingActivity(context: TurnContext): Promise<void> { | ||
let typingActivity: Partial<Activity> = { | ||
private async sendTypingActivity(context: TurnContext) { | ||
// Sending the Activity directly via the Adapter avoids other middleware and avoids setting the | ||
// responded flag. However this also requires that the conversation reference details are explicitly added. | ||
const conversationReference = TurnContext.getConversationReference(context.activity); | ||
const typingActivity = TurnContext.applyConversationReference({ | ||
type: ActivityTypes.Typing, | ||
relatesTo: context.activity.relatesTo | ||
}; | ||
}, conversationReference); | ||
// Sending the Activity directly via the Adapter avoids other middleware and avoids setting the | ||
// responded flag. However this also requires that the conversation reference details are explicitly added. | ||
const conversationReference: Partial<ConversationReference> = TurnContext.getConversationReference(context.activity); | ||
typingActivity = TurnContext.applyConversationReference(typingActivity, conversationReference); | ||
await context.adapter.sendActivities(context, [typingActivity]); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
807284
15819
+ Addedbotframework-schema@4.11.0-dev.20200924.ca751f7(transitive)
- Removedbotframework-schema@4.11.0-dev.20200921.00cab05(transitive)