@azure/communication-react
Version:
React library for building modern communication user experiences utilizing Azure Communication Services
183 lines • 7.79 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/**
* @private
*/
export class ResourceDownloadQueue {
constructor(context, authentication) {
this._messagesNeedingResourceRetrieval = [];
this.isActive = false;
this._requestsToCancel = {};
this._context = context;
this._credential = authentication.credential;
this._endpoint = authentication.endpoint;
}
containsMessageWithSameAttachments(message) {
var _a, _b, _c;
let contains = false;
const incomingAttachment = (_a = message.content) === null || _a === void 0 ? void 0 : _a.attachments;
if (incomingAttachment) {
for (const m of this._messagesNeedingResourceRetrieval) {
const existingAttachment = (_c = (_b = m.content) === null || _b === void 0 ? void 0 : _b.attachments) !== null && _c !== void 0 ? _c : [];
contains = incomingAttachment.every((element, index) => element === existingAttachment[index]);
if (contains) {
break;
}
}
}
return contains;
}
addMessage(message) {
// make a copy of message and add to queue
const copy = Object.assign({}, message);
this._messagesNeedingResourceRetrieval.push(copy);
}
startQueue(threadId, operation, options) {
return __awaiter(this, void 0, void 0, function* () {
if (this.isActive) {
return;
}
while (this._messagesNeedingResourceRetrieval.length > 0) {
this.isActive = true;
let message = this._messagesNeedingResourceRetrieval.shift();
if (!message) {
this.isActive = false;
continue;
}
if (options) {
const singleUrl = options.singleUrl;
message = yield this.downloadSingleUrl(message, singleUrl, operation);
}
else {
message = yield this.downloadAllPreviewUrls(message, operation);
}
this._context.setChatMessage(threadId, message);
this.isActive = false;
}
});
}
cancelAllRequests() {
for (const cancelation of Object.values(this._requestsToCancel)) {
cancelation.abortController.abort();
}
this._requestsToCancel = {};
}
cancelRequest(url) {
var _a;
if (this._requestsToCancel[url]) {
(_a = this._requestsToCancel[url]) === null || _a === void 0 ? void 0 : _a.abortController.abort();
delete this._requestsToCancel[url];
}
}
downloadSingleUrl(message, resourceUrl, operation) {
return __awaiter(this, void 0, void 0, function* () {
const response = {
sourceUrl: ''
};
try {
const abortController = new AbortController();
const blobUrl = yield this.downloadResource(operation, resourceUrl, abortController);
response.sourceUrl = blobUrl;
}
catch (error) {
response.error = error;
delete this._requestsToCancel[resourceUrl];
}
message = Object.assign(Object.assign({}, message), { resourceCache: Object.assign(Object.assign({}, message.resourceCache), { [resourceUrl]: response }) });
return message;
});
}
downloadAllPreviewUrls(message, operation) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const attachments = (_a = message.content) === null || _a === void 0 ? void 0 : _a.attachments;
if (message.type === 'html' && attachments) {
if (message.resourceCache === undefined) {
message.resourceCache = {};
}
for (const attachment of attachments) {
if (attachment.previewUrl && attachment.attachmentType === 'image') {
const response = {
sourceUrl: ''
};
try {
const abortController = new AbortController();
const blobUrl = yield this.downloadResource(operation, attachment.previewUrl, abortController);
response.sourceUrl = blobUrl;
}
catch (error) {
response.error = error;
delete this._requestsToCancel[attachment.previewUrl];
}
message.resourceCache[attachment.previewUrl] = response;
}
}
}
return message;
});
}
downloadResource(operation, url, abortController) {
return __awaiter(this, void 0, void 0, function* () {
this._requestsToCancel[url] = {
src: url,
abortController
};
const blobUrl = yield operation(url, {
credential: this._credential,
endpoint: this._endpoint
}, {
abortController
});
delete this._requestsToCancel[url];
return blobUrl;
});
}
}
/**
* @private
*/
export const fetchImageSource = (src, authentication, options) => __awaiter(void 0, void 0, void 0, function* () {
function fetchWithAuthentication(url, token, options) {
return __awaiter(this, void 0, void 0, function* () {
const headers = new Headers();
headers.append('Authorization', `Bearer ${token}`);
return yield fetchWithTimeout(url, {
timeout: options.timeout,
headers,
abortController: options.abortController
});
});
}
function fetchWithTimeout(resource, options) {
return __awaiter(this, void 0, void 0, function* () {
// default timeout is 30 seconds
const { timeout = 30000, abortController } = options;
const id = setTimeout(() => {
abortController.abort();
}, timeout);
const response = yield fetch(resource, Object.assign(Object.assign({}, options), { signal: abortController.signal }));
clearTimeout(id);
return response;
});
}
const fetchUrl = new URL(src);
const endpoint = new URL(authentication.endpoint);
let token = '';
if (fetchUrl.hostname === endpoint.hostname && fetchUrl.protocol === 'https:') {
token = (yield authentication.credential.getToken()).token;
}
const response = yield fetchWithAuthentication(src, token, options);
if (response.status >= 400) {
throw new Error(`Failed to fetch image source. Status code: ${response.status}`);
}
const blob = yield response.blob();
return URL.createObjectURL(blob);
});
//# sourceMappingURL=ResourceDownloadQueue.js.map