Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "minor",
"area": "feature",
"workstream": "InlineImages",
"comment": "Chat Stateful Client now returns and empty string in cases of errors",
"packageName": "@azure/communication-react",
"email": "9044372+JoshuaLai@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "minor",
"area": "feature",
"workstream": "InlineImages",
"comment": "Chat Stateful Client now returns and empty string in cases of errors",
"packageName": "@azure/communication-react",
"email": "9044372+JoshuaLai@users.noreply.github.com",
"dependentChangeType": "patch"
}
14 changes: 12 additions & 2 deletions packages/chat-component-bindings/src/messageThreadSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ const processChatMessageContent = (message: ChatMessageWithStatus): string | und
document.querySelectorAll('img').forEach((img) => {
const attachmentPreviewUrl = attachments.find((attachment) => attachment.id === img.id)?.previewUrl;
if (attachmentPreviewUrl) {
const src = message.resourceCache?.[attachmentPreviewUrl].sourceUrl ?? '';
const resourceCache = message.resourceCache?.[attachmentPreviewUrl];
let src = 'blob://';
if (resourceCache && resourceCache.error === undefined) {
src = resourceCache.sourceUrl;
}

img.src = src;
}
});
Expand All @@ -185,7 +190,12 @@ const processChatMessageContent = (message: ChatMessageWithStatus): string | und
const generateImageAttachmentImgHtml = (message: ChatMessageWithStatus, attachment: ChatAttachment): string => {
if (attachment.previewUrl !== undefined) {
const contentType = extractAttachmentContentTypeFromName(attachment.name);
const src = message.resourceCache?.[attachment.previewUrl].sourceUrl ?? '';
const resourceCache = message.resourceCache?.[attachment.previewUrl];
let src = 'blob://';
if (resourceCache && resourceCache.error === undefined) {
src = resourceCache.sourceUrl;
}
Comment thread
JoshuaLai marked this conversation as resolved.
Outdated

return `\r\n<p><img alt="image" src="${src}" itemscope="${contentType}" id="${attachment.id}"></p>`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CommunicationTokenCredential } from '@azure/communication-common';
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
import { ChatContext } from './ChatContext';
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
import { ResourceDownloadError, ResourceDownloadQueue } from './ResourceDownloadQueue';
import { ResourceDownloadQueue } from './ResourceDownloadQueue';
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
import { messageTemplate } from './mocks/createMockChatThreadClient';
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
Expand Down Expand Up @@ -224,8 +224,7 @@ describe('ResourceDownloadQueue api functions', () => {

const queue = new ResourceDownloadQueue(context, tokenCredential);
const operation = jest.fn();
const e = new ResourceDownloadError(first);
operation.mockRejectedValueOnce(e);
operation.mockRejectedValueOnce(new Error('mock error'));
queue.addMessage(first);
queue.addMessage(second);
queue.addMessage(third);
Expand Down Expand Up @@ -282,6 +281,7 @@ describe('ResourceDownloadQueue api functions', () => {
const resourceCache = context.getState().threads[threadId].chatMessages[messageId].resourceCache;
expect(resourceCache).toBeDefined();
expect(resourceCache?.['previewUrl1'].error).toBeDefined();
expect(resourceCache?.['previewUrl1'].sourceUrl).toEqual('');
});
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
test('if operation fails for first item, error should be in the cache only for first item', async () => {
Expand Down Expand Up @@ -322,6 +322,7 @@ describe('ResourceDownloadQueue api functions', () => {
const resourceCache = context.getState().threads[threadId].chatMessages[messageId].resourceCache;
expect(resourceCache).toBeDefined();
expect(resourceCache?.['previewUrl1'].error).toBeDefined();
expect(resourceCache?.['previewUrl1'].sourceUrl).toEqual('');
expect(resourceCache?.['previewUrl2'].error).toBeUndefined();
expect(resourceCache?.['previewUrl3'].error).toBeUndefined();
});
Expand Down
25 changes: 3 additions & 22 deletions packages/chat-stateful-client/src/ResourceDownloadQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class ResourceDownloadQueue {
private _context: ChatContext;
private isActive = false;
private _credential: CommunicationTokenCredential;
private _errors: ResourceDownloadError[] = [];

constructor(context: ChatContext, credential: CommunicationTokenCredential) {
this._context = context;
Expand All @@ -41,10 +40,6 @@ export class ResourceDownloadQueue {
return contains;
}

public get errors(): ResourceDownloadError[] {
return this._errors;
}

public addMessage(message: ChatMessageWithStatus): void {
// make a copy of message and add to queue
const copy = { ...message };
Expand Down Expand Up @@ -79,7 +74,7 @@ export class ResourceDownloadQueue {
resourceUrl: string,
operation: ImageRequest
): Promise<ChatMessageWithStatus> {
const response: ResourceFetchResult = { sourceUrl: URL.createObjectURL(new Blob()) };
const response: ResourceFetchResult = { sourceUrl: '' };
try {
const blobUrl = await this.downloadResource(operation, resourceUrl);
response.sourceUrl = blobUrl;
Expand All @@ -102,7 +97,7 @@ export class ResourceDownloadQueue {
}
for (const attachment of attachments) {
if (attachment.previewUrl && attachment.attachmentType === 'image') {
const response: ResourceFetchResult = { sourceUrl: URL.createObjectURL(new Blob()) };
const response: ResourceFetchResult = { sourceUrl: '' };
try {
const blobUrl = await this.downloadResource(operation, attachment.previewUrl);
response.sourceUrl = blobUrl;
Expand All @@ -118,8 +113,7 @@ export class ResourceDownloadQueue {
}

private async downloadResource(operation: ImageRequest, url: string): Promise<string> {
let blobUrl = URL.createObjectURL(new Blob());
blobUrl = await operation(url, this._credential);
const blobUrl = await operation(url, this._credential);
return blobUrl;
}
}
Expand Down Expand Up @@ -164,16 +158,3 @@ export const fetchImageSource = async (src: string, credential: CommunicationTok
interface ImageRequest {
(request: string, credential: CommunicationTokenCredential): Promise<string>;
}

/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
/**
* @private
*/
export class ResourceDownloadError extends Error {
public chatMessageWithStatus: ChatMessageWithStatus;

constructor(chatMessageWithStatus: ChatMessageWithStatus) {
super();
this.chatMessageWithStatus = chatMessageWithStatus;
}
}