Skip to content

Commit 043682f

Browse files
authored
Merge pull request #256 from GetStream/custom-cdn-link
feat: Add custom attachment requests #255
2 parents 5b08966 + 2e0be60 commit 043682f

File tree

2 files changed

+137
-2
lines changed

2 files changed

+137
-2
lines changed

projects/stream-chat-angular/src/lib/channel.service.spec.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,4 +1329,106 @@ describe('ChannelService', () => {
13291329

13301330
expect(spy).toHaveBeenCalledWith({ channel1: newMessage.created_at });
13311331
});
1332+
1333+
it('should call custom #customFileUploadRequest and #customImageUploadRequest if provided', async () => {
1334+
await init();
1335+
let channel!: Channel<DefaultStreamChatGenerics>;
1336+
service.activeChannel$.pipe(first()).subscribe((c) => (channel = c!));
1337+
const customImageUploadRequest = jasmine
1338+
.createSpy()
1339+
.and.callFake((file: File) => {
1340+
switch (file.name) {
1341+
case 'file_error.jpg':
1342+
return Promise.reject(new Error());
1343+
default:
1344+
return Promise.resolve({ file: 'url/to/image' });
1345+
}
1346+
});
1347+
const customFileUploadRequest = jasmine
1348+
.createSpy()
1349+
.and.callFake((file: File) => {
1350+
switch (file.name) {
1351+
case 'file_error.pdf':
1352+
return Promise.reject(new Error());
1353+
default:
1354+
return Promise.resolve({ file: 'url/to/pdf' });
1355+
}
1356+
});
1357+
service.customImageUploadRequest = customImageUploadRequest;
1358+
service.customFileUploadRequest = customFileUploadRequest;
1359+
spyOn(channel, 'sendImage');
1360+
spyOn(channel, 'sendFile');
1361+
const file1 = { name: 'food.png' } as File;
1362+
const file2 = { name: 'file_error.jpg' } as File;
1363+
const file3 = { name: 'menu.pdf' } as File;
1364+
const file4 = { name: 'file_error.pdf' } as File;
1365+
const attachments = [
1366+
{ file: file1, type: 'image', state: 'uploading' },
1367+
{ file: file2, type: 'image', state: 'uploading' },
1368+
{ file: file3, type: 'file', state: 'uploading' },
1369+
{ file: file4, type: 'file', state: 'uploading' },
1370+
] as AttachmentUpload[];
1371+
const result = await service.uploadAttachments(attachments);
1372+
const expectedResult = [
1373+
{
1374+
file: file1,
1375+
state: 'success',
1376+
url: 'url/to/image',
1377+
type: 'image',
1378+
},
1379+
{ file: file2, state: 'error', type: 'image' },
1380+
{
1381+
file: file3,
1382+
state: 'success',
1383+
url: 'url/to/pdf',
1384+
type: 'file',
1385+
},
1386+
{ file: file4, state: 'error', type: 'file' },
1387+
];
1388+
1389+
expect(channel.sendImage).not.toHaveBeenCalled();
1390+
expect(channel.sendFile).not.toHaveBeenCalled();
1391+
1392+
expectedResult.forEach((r, i) => {
1393+
expect(r).toEqual(result[i]);
1394+
});
1395+
});
1396+
1397+
it('should call custom #customImageDeleteRequest if provided', async () => {
1398+
await init();
1399+
let channel!: Channel<DefaultStreamChatGenerics>;
1400+
service.activeChannel$.pipe(first()).subscribe((c) => (channel = c!));
1401+
const customImageDeleteRequest = jasmine.createSpy();
1402+
service.customImageDeleteRequest = customImageDeleteRequest;
1403+
spyOn(channel, 'deleteImage');
1404+
const url = 'url/to/image';
1405+
await service.deleteAttachment({
1406+
url,
1407+
type: 'image',
1408+
state: 'success',
1409+
file: {} as any as File,
1410+
});
1411+
1412+
expect(customImageDeleteRequest).toHaveBeenCalledWith(url, channel);
1413+
expect(channel.deleteImage).not.toHaveBeenCalled();
1414+
});
1415+
1416+
it('should call custom #customFileDeleteRequest if provided', async () => {
1417+
await init();
1418+
let channel!: Channel<DefaultStreamChatGenerics>;
1419+
service.activeChannel$.pipe(first()).subscribe((c) => (channel = c!));
1420+
const customFileDeleteRequest = jasmine.createSpy();
1421+
service.customFileDeleteRequest = customFileDeleteRequest;
1422+
spyOn(channel, 'deleteFile');
1423+
const url = 'url/to/file';
1424+
await service.deleteAttachment({
1425+
url,
1426+
type: 'file',
1427+
state: 'success',
1428+
file: {} as any as File,
1429+
});
1430+
1431+
expect(customFileDeleteRequest).toHaveBeenCalledWith(url, channel);
1432+
expect(channel.deleteFile).not.toHaveBeenCalled();
1433+
});
13321434
});

projects/stream-chat-angular/src/lib/channel.service.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,31 @@ export class ChannelService<
197197
threadListSetter: (messages: StreamMessage<T>[]) => void,
198198
parentMessageSetter: (message: StreamMessage<T> | undefined) => void
199199
) => void;
200+
/**
201+
* You can override the default file upload request - you can use this to upload files to your own CDN
202+
*/
203+
customFileUploadRequest?: (
204+
file: File,
205+
channel: Channel<T>
206+
) => Promise<{ file: string }>;
207+
/**
208+
* You can override the default image upload request - you can use this to upload images to your own CDN
209+
*/
210+
customImageUploadRequest?: (
211+
file: File,
212+
channel: Channel<T>
213+
) => Promise<{ file: string }>;
214+
/**
215+
* You can override the default file delete request - override this if you use your own CDN
216+
*/
217+
customFileDeleteRequest?: (url: string, channel: Channel<T>) => Promise<void>;
218+
/**
219+
* You can override the default image delete request - override this if you use your own CDN
220+
*/
221+
customImageDeleteRequest?: (
222+
url: string,
223+
channel: Channel<T>
224+
) => Promise<void>;
200225
private channelsSubject = new BehaviorSubject<Channel<T>[] | undefined>(
201226
undefined
202227
);
@@ -557,7 +582,11 @@ export class ChannelService<
557582
const uploadResults = await Promise.allSettled(
558583
uploads.map((upload) =>
559584
upload.type === 'image'
560-
? channel.sendImage(upload.file)
585+
? this.customImageUploadRequest
586+
? this.customImageUploadRequest(upload.file, channel)
587+
: channel.sendImage(upload.file)
588+
: this.customFileUploadRequest
589+
? this.customFileUploadRequest(upload.file, channel)
561590
: channel.sendFile(upload.file)
562591
)
563592
);
@@ -586,7 +615,11 @@ export class ChannelService<
586615
async deleteAttachment(attachmentUpload: AttachmentUpload) {
587616
const channel = this.activeChannelSubject.getValue()!;
588617
await (attachmentUpload.type === 'image'
589-
? channel.deleteImage(attachmentUpload.url!)
618+
? this.customImageDeleteRequest
619+
? this.customImageDeleteRequest(attachmentUpload.url!, channel)
620+
: channel.deleteImage(attachmentUpload.url!)
621+
: this.customFileDeleteRequest
622+
? this.customFileDeleteRequest(attachmentUpload.url!, channel)
590623
: channel.deleteFile(attachmentUpload.url!));
591624
}
592625

0 commit comments

Comments
 (0)