stream-chat-angular 3.0.0-beta.8 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -12
- package/assets/version.d.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +89 -35
- package/bundles/stream-chat-angular.umd.js.map +1 -1
- package/esm2015/assets/version.js +2 -2
- package/esm2015/lib/attachment-list/attachment-list.component.js +9 -2
- package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +2 -2
- package/esm2015/lib/attachment.service.js +20 -5
- package/esm2015/lib/channel.service.js +42 -17
- package/esm2015/lib/message/message.component.js +7 -2
- package/esm2015/lib/message-input/message-input.component.js +8 -3
- package/esm2015/lib/types.js +1 -1
- package/fesm2015/stream-chat-angular.js +83 -26
- package/fesm2015/stream-chat-angular.js.map +1 -1
- package/lib/attachment-list/attachment-list.component.d.ts +1 -0
- package/lib/channel.service.d.ts +28 -2
- package/lib/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/assets/styles/css/index.css +1 -1
- package/src/assets/styles/css/index.css.map +1 -1
- package/src/assets/styles/scss/ActionsBox.scss +2 -2
- package/src/assets/styles/scss/Attachment.scss +1 -1
- package/src/assets/styles/scss/ChannelList.scss +6 -0
- package/src/assets/styles/scss/ChannelSearch.scss +12 -1
- package/src/assets/styles/scss/Message.scss +104 -93
- package/src/assets/styles/scss/MessageInput.scss +8 -2
- package/src/assets/styles/scss/MessageInputFlat.scss +6 -0
- package/src/assets/styles/scss/Thread.scss +15 -2
- package/src/assets/styles/scss/VirtualMessage.scss +1 -0
- package/src/assets/styles/scss/_base.scss +4 -0
- package/src/assets/version.ts +1 -1
package/README.md
CHANGED
|
@@ -30,15 +30,38 @@ The best way to get started is to follow the [Angular Chat Tutorial](https://get
|
|
|
30
30
|
Stream is free for most side and hobby projects. To qualify, your project/company must have no more than 5 team members and earn less than $10k in monthly revenue.
|
|
31
31
|
For complete pricing and details visit our [Chat Pricing Page](https://getstream.io/chat/pricing/).
|
|
32
32
|
|
|
33
|
+
## Docs
|
|
34
|
+
|
|
35
|
+
The [docs](https://getstream.io/chat/docs/sdk/angular/) provide a brief description about the components and services in the library.
|
|
36
|
+
|
|
37
|
+
The Angular library is created using the [stream-chat-js](https://github.com/getstream/stream-chat-js) library. For the most common use cases our services should give a nice abstraction over this library, however you might need it for more advanced customization, the [documentation](https://getstream.io/chat/docs/js/) is on our website.
|
|
38
|
+
|
|
39
|
+
## Contributing
|
|
40
|
+
|
|
41
|
+
We welcome code changes that improve this library or fix a problem. Please make sure to follow all best practices and add tests, if applicable, before submitting a pull request on GitHub. We are pleased to merge your code into the official repository if it meets a need. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. See our license file for more details.
|
|
42
|
+
|
|
43
|
+
## We are hiring!
|
|
44
|
+
|
|
45
|
+
We recently closed a [$38 million Series B funding round](https://techcrunch.com/2021/03/04/stream-raises-38m-as-its-chat-and-activity-feed-apis-power-communications-for-1b-users/) and are actively growing.
|
|
46
|
+
Our APIs are used by more than a billion end-users, and by working at Stream, you have the chance to make a huge impact on a team of very strong engineers.
|
|
47
|
+
|
|
48
|
+
Check out our current openings and apply via [Stream's website](https://getstream.io/team/#jobs).
|
|
49
|
+
|
|
33
50
|
## Installation
|
|
34
51
|
|
|
35
52
|
### Install with NPM
|
|
36
53
|
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
Run the following command if you are using **Angular 13**:
|
|
55
|
+
|
|
56
|
+
```shell
|
|
57
|
+
npm install stream-chat-angular stream-chat @ngx-translate/core
|
|
39
58
|
```
|
|
40
59
|
|
|
41
|
-
|
|
60
|
+
Run this command if you are using **Angular 12**:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
npm install stream-chat-angular stream-chat@5 @ngx-translate/core --legacy-peer-deps
|
|
64
|
+
```
|
|
42
65
|
|
|
43
66
|
## Sample App
|
|
44
67
|
|
|
@@ -56,19 +79,28 @@ STREAM_USER_TOKEN=<Your user token>
|
|
|
56
79
|
|
|
57
80
|
Run `npm start` and navigate to `http://localhost:4200/`.
|
|
58
81
|
|
|
59
|
-
##
|
|
82
|
+
## Customization examples
|
|
60
83
|
|
|
61
|
-
|
|
84
|
+
This repository includes a sample app that showcases how you can provide your own template for different components within the SDK:
|
|
62
85
|
|
|
63
|
-
|
|
86
|
+
To run the app:
|
|
64
87
|
|
|
65
|
-
|
|
88
|
+
Create a file named `.env` in the root directory with the following content:
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
```
|
|
91
|
+
STREAM_API_KEY=<Your API key>
|
|
92
|
+
STREAM_USER_ID=<Your user ID>
|
|
93
|
+
STREAM_USER_TOKEN=<Your user token>
|
|
94
|
+
```
|
|
68
95
|
|
|
69
|
-
|
|
96
|
+
Run `npm start:customizations-example` and navigate to `http://localhost:4200/`.
|
|
70
97
|
|
|
71
|
-
|
|
72
|
-
Our APIs are used by more than a billion end-users, and by working at Stream, you have the chance to make a huge impact on a team of very strong engineers.
|
|
98
|
+
## Local development
|
|
73
99
|
|
|
74
|
-
|
|
100
|
+
Run `npm install` in the root of the project. You can use the `npm run start:dev` command to start the SampleApp with automatic reloading.
|
|
101
|
+
|
|
102
|
+
A note about the documentation:
|
|
103
|
+
|
|
104
|
+
- Documentations for Angular services are generated from doc comments in the source files (not under source control)
|
|
105
|
+
- Documentations for inputs and outputs of Angular components are generated from doc comments in the source files (not under source control)
|
|
106
|
+
- Everything else in the documentation is written in `mdx` files located in the `docusaurus` folder
|
package/assets/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "3.0.
|
|
1
|
+
export declare const version = "3.0.1";
|
|
@@ -354,7 +354,7 @@
|
|
|
354
354
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
-
var version = '3.0.
|
|
357
|
+
var version = '3.0.1';
|
|
358
358
|
|
|
359
359
|
/**
|
|
360
360
|
* The `NotificationService` can be used to add or remove notifications. By default the [`NotificationList`](../components/NotificationListComponent.mdx) component displays the currently active notifications.
|
|
@@ -652,7 +652,7 @@
|
|
|
652
652
|
};
|
|
653
653
|
|
|
654
654
|
/**
|
|
655
|
-
* The `ChannelService` provides data and interaction for the channel list and message list.
|
|
655
|
+
* The `ChannelService` provides data and interaction for the channel list and message list.
|
|
656
656
|
*/
|
|
657
657
|
var ChannelService = /** @class */ (function () {
|
|
658
658
|
function ChannelService(chatClientService, ngZone) {
|
|
@@ -747,6 +747,21 @@
|
|
|
747
747
|
this.activeThreadMessagesSubject.next([]);
|
|
748
748
|
this.messageToQuoteSubject.next(undefined);
|
|
749
749
|
};
|
|
750
|
+
/**
|
|
751
|
+
* Deselects the currently active (if any) channel
|
|
752
|
+
*/
|
|
753
|
+
ChannelService.prototype.deselectActiveChannel = function () {
|
|
754
|
+
var activeChannel = this.activeChannelSubject.getValue();
|
|
755
|
+
if (!activeChannel) {
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
this.activeChannelMessagesSubject.next([]);
|
|
759
|
+
this.activeChannelSubject.next(undefined);
|
|
760
|
+
this.activeParentMessageIdSubject.next(undefined);
|
|
761
|
+
this.activeThreadMessagesSubject.next([]);
|
|
762
|
+
this.latestMessageDateByUserByChannelsSubject.next({});
|
|
763
|
+
this.selectMessageToQuote(undefined);
|
|
764
|
+
};
|
|
750
765
|
/**
|
|
751
766
|
* Sets the given `message` as an active parent message. If `undefined` is provided, it will deleselect the current parent message.
|
|
752
767
|
* @param message
|
|
@@ -842,9 +857,13 @@
|
|
|
842
857
|
* @param filters
|
|
843
858
|
* @param sort
|
|
844
859
|
* @param options
|
|
860
|
+
* @param shouldSetActiveChannel Decides if the first channel in the result should be made as an active channel, or no channel should be marked as active
|
|
861
|
+
* @returns the list of channels found by the query
|
|
845
862
|
*/
|
|
846
|
-
ChannelService.prototype.init = function (filters, sort, options) {
|
|
863
|
+
ChannelService.prototype.init = function (filters, sort, options, shouldSetActiveChannel) {
|
|
864
|
+
if (shouldSetActiveChannel === void 0) { shouldSetActiveChannel = true; }
|
|
847
865
|
return __awaiter(this, void 0, void 0, function () {
|
|
866
|
+
var result;
|
|
848
867
|
var _this = this;
|
|
849
868
|
return __generator(this, function (_h) {
|
|
850
869
|
switch (_h.label) {
|
|
@@ -859,11 +878,11 @@
|
|
|
859
878
|
message_limit: this.messagePageSize,
|
|
860
879
|
};
|
|
861
880
|
this.sort = sort || { last_message_at: -1, updated_at: -1 };
|
|
862
|
-
return [4 /*yield*/, this.queryChannels()];
|
|
881
|
+
return [4 /*yield*/, this.queryChannels(shouldSetActiveChannel)];
|
|
863
882
|
case 1:
|
|
864
|
-
_h.sent();
|
|
883
|
+
result = _h.sent();
|
|
865
884
|
this.chatClientService.events$.subscribe(function (notification) { return void _this.handleNotification(notification); });
|
|
866
|
-
return [2 /*return
|
|
885
|
+
return [2 /*return*/, result];
|
|
867
886
|
}
|
|
868
887
|
});
|
|
869
888
|
});
|
|
@@ -872,13 +891,8 @@
|
|
|
872
891
|
* Resets the `activeChannel$`, `channels$` and `activeChannelMessages$` Observables. Useful when disconnecting a chat user, use in combination with [`disconnectUser`](./ChatClientService.mdx/#disconnectuser).
|
|
873
892
|
*/
|
|
874
893
|
ChannelService.prototype.reset = function () {
|
|
875
|
-
this.
|
|
876
|
-
this.activeChannelSubject.next(undefined);
|
|
877
|
-
this.activeParentMessageIdSubject.next(undefined);
|
|
878
|
-
this.activeThreadMessagesSubject.next([]);
|
|
894
|
+
this.deselectActiveChannel();
|
|
879
895
|
this.channelsSubject.next(undefined);
|
|
880
|
-
this.latestMessageDateByUserByChannelsSubject.next({});
|
|
881
|
-
this.selectMessageToQuote(undefined);
|
|
882
896
|
};
|
|
883
897
|
/**
|
|
884
898
|
* Loads the next page of channels. The page size can be set in the [query option](https://getstream.io/chat/docs/javascript/query_channels/?language=javascript#query-options) object.
|
|
@@ -889,7 +903,7 @@
|
|
|
889
903
|
switch (_h.label) {
|
|
890
904
|
case 0:
|
|
891
905
|
this.options.offset = this.channels.length;
|
|
892
|
-
return [4 /*yield*/, this.queryChannels()];
|
|
906
|
+
return [4 /*yield*/, this.queryChannels(false)];
|
|
893
907
|
case 1:
|
|
894
908
|
_h.sent();
|
|
895
909
|
return [2 /*return*/];
|
|
@@ -1027,14 +1041,19 @@
|
|
|
1027
1041
|
ChannelService.prototype.uploadAttachments = function (uploads) {
|
|
1028
1042
|
return __awaiter(this, void 0, void 0, function () {
|
|
1029
1043
|
var result, channel, uploadResults;
|
|
1044
|
+
var _this = this;
|
|
1030
1045
|
return __generator(this, function (_h) {
|
|
1031
1046
|
switch (_h.label) {
|
|
1032
1047
|
case 0:
|
|
1033
1048
|
result = [];
|
|
1034
1049
|
channel = this.activeChannelSubject.getValue();
|
|
1035
1050
|
return [4 /*yield*/, Promise.allSettled(uploads.map(function (upload) { return upload.type === 'image'
|
|
1036
|
-
?
|
|
1037
|
-
|
|
1051
|
+
? _this.customImageUploadRequest
|
|
1052
|
+
? _this.customImageUploadRequest(upload.file, channel)
|
|
1053
|
+
: channel.sendImage(upload.file)
|
|
1054
|
+
: _this.customFileUploadRequest
|
|
1055
|
+
? _this.customFileUploadRequest(upload.file, channel)
|
|
1056
|
+
: channel.sendFile(upload.file); }))];
|
|
1038
1057
|
case 1:
|
|
1039
1058
|
uploadResults = _h.sent();
|
|
1040
1059
|
uploadResults.forEach(function (uploadResult, i) {
|
|
@@ -1069,8 +1088,12 @@
|
|
|
1069
1088
|
case 0:
|
|
1070
1089
|
channel = this.activeChannelSubject.getValue();
|
|
1071
1090
|
return [4 /*yield*/, (attachmentUpload.type === 'image'
|
|
1072
|
-
?
|
|
1073
|
-
|
|
1091
|
+
? this.customImageDeleteRequest
|
|
1092
|
+
? this.customImageDeleteRequest(attachmentUpload.url, channel)
|
|
1093
|
+
: channel.deleteImage(attachmentUpload.url)
|
|
1094
|
+
: this.customFileDeleteRequest
|
|
1095
|
+
? this.customFileDeleteRequest(attachmentUpload.url, channel)
|
|
1096
|
+
: channel.deleteFile(attachmentUpload.url))];
|
|
1074
1097
|
case 1:
|
|
1075
1098
|
_h.sent();
|
|
1076
1099
|
return [2 /*return*/];
|
|
@@ -1413,7 +1436,7 @@
|
|
|
1413
1436
|
this.activeChannelSubscriptions.forEach(function (s) { return s.unsubscribe(); });
|
|
1414
1437
|
this.activeChannelSubscriptions = [];
|
|
1415
1438
|
};
|
|
1416
|
-
ChannelService.prototype.queryChannels = function () {
|
|
1439
|
+
ChannelService.prototype.queryChannels = function (shouldSetActiveChannel) {
|
|
1417
1440
|
return __awaiter(this, void 0, void 0, function () {
|
|
1418
1441
|
var channels, prevChannels, error_2;
|
|
1419
1442
|
var _this = this;
|
|
@@ -1427,15 +1450,17 @@
|
|
|
1427
1450
|
channels.forEach(function (c) { return _this.watchForChannelEvents(c); });
|
|
1428
1451
|
prevChannels = this.channelsSubject.getValue() || [];
|
|
1429
1452
|
this.channelsSubject.next(__spreadArray(__spreadArray([], __read(prevChannels)), __read(channels)));
|
|
1430
|
-
if (channels.length > 0 &&
|
|
1453
|
+
if (channels.length > 0 &&
|
|
1454
|
+
!this.activeChannelSubject.getValue() &&
|
|
1455
|
+
shouldSetActiveChannel) {
|
|
1431
1456
|
this.setAsActiveChannel(channels[0]);
|
|
1432
1457
|
}
|
|
1433
1458
|
this.hasMoreChannelsSubject.next(channels.length >= this.options.limit);
|
|
1434
|
-
return [
|
|
1459
|
+
return [2 /*return*/, channels];
|
|
1435
1460
|
case 2:
|
|
1436
1461
|
error_2 = _h.sent();
|
|
1437
1462
|
this.channelsSubject.error(error_2);
|
|
1438
|
-
|
|
1463
|
+
throw error_2;
|
|
1439
1464
|
case 3: return [2 /*return*/];
|
|
1440
1465
|
}
|
|
1441
1466
|
});
|
|
@@ -1819,7 +1844,7 @@
|
|
|
1819
1844
|
*/
|
|
1820
1845
|
AttachmentService.prototype.filesSelected = function (fileList) {
|
|
1821
1846
|
return __awaiter(this, void 0, void 0, function () {
|
|
1822
|
-
var imageFiles, dataFiles, newUploads;
|
|
1847
|
+
var imageFiles, dataFiles, videoFiles, newUploads;
|
|
1823
1848
|
var _this = this;
|
|
1824
1849
|
return __generator(this, function (_d) {
|
|
1825
1850
|
switch (_d.label) {
|
|
@@ -1829,19 +1854,27 @@
|
|
|
1829
1854
|
}
|
|
1830
1855
|
imageFiles = [];
|
|
1831
1856
|
dataFiles = [];
|
|
1857
|
+
videoFiles = [];
|
|
1832
1858
|
Array.from(fileList).forEach(function (file) {
|
|
1833
1859
|
if (isImageFile(file)) {
|
|
1834
1860
|
imageFiles.push(file);
|
|
1835
1861
|
}
|
|
1862
|
+
else if (file.type.startsWith('video/')) {
|
|
1863
|
+
videoFiles.push(file);
|
|
1864
|
+
}
|
|
1836
1865
|
else {
|
|
1837
1866
|
dataFiles.push(file);
|
|
1838
1867
|
}
|
|
1839
1868
|
});
|
|
1840
1869
|
imageFiles.forEach(function (f) { return _this.createPreview(f); });
|
|
1841
|
-
newUploads = __spreadArray(__spreadArray([], __read(imageFiles.map(function (file) { return ({
|
|
1870
|
+
newUploads = __spreadArray(__spreadArray(__spreadArray([], __read(imageFiles.map(function (file) { return ({
|
|
1842
1871
|
file: file,
|
|
1843
1872
|
state: 'uploading',
|
|
1844
1873
|
type: 'image',
|
|
1874
|
+
}); }))), __read(videoFiles.map(function (file) { return ({
|
|
1875
|
+
file: file,
|
|
1876
|
+
state: 'uploading',
|
|
1877
|
+
type: 'video',
|
|
1845
1878
|
}); }))), __read(dataFiles.map(function (file) { return ({
|
|
1846
1879
|
file: file,
|
|
1847
1880
|
state: 'uploading',
|
|
@@ -1888,7 +1921,7 @@
|
|
|
1888
1921
|
*/
|
|
1889
1922
|
AttachmentService.prototype.deleteAttachment = function (upload) {
|
|
1890
1923
|
return __awaiter(this, void 0, void 0, function () {
|
|
1891
|
-
var attachmentUploads, error_1;
|
|
1924
|
+
var attachmentUploads, result, index, error_1, index;
|
|
1892
1925
|
return __generator(this, function (_d) {
|
|
1893
1926
|
switch (_d.label) {
|
|
1894
1927
|
case 0:
|
|
@@ -1900,18 +1933,23 @@
|
|
|
1900
1933
|
return [4 /*yield*/, this.channelService.deleteAttachment(upload)];
|
|
1901
1934
|
case 2:
|
|
1902
1935
|
_d.sent();
|
|
1903
|
-
|
|
1936
|
+
result = __spreadArray([], __read(attachmentUploads));
|
|
1937
|
+
index = attachmentUploads.indexOf(upload);
|
|
1938
|
+
result.splice(index, 1);
|
|
1904
1939
|
return [3 /*break*/, 4];
|
|
1905
1940
|
case 3:
|
|
1906
1941
|
error_1 = _d.sent();
|
|
1942
|
+
result = attachmentUploads;
|
|
1907
1943
|
this.notificationService.addTemporaryNotification('streamChat.Error deleting attachment');
|
|
1908
1944
|
return [3 /*break*/, 4];
|
|
1909
1945
|
case 4: return [3 /*break*/, 6];
|
|
1910
1946
|
case 5:
|
|
1911
|
-
|
|
1947
|
+
result = __spreadArray([], __read(attachmentUploads));
|
|
1948
|
+
index = attachmentUploads.indexOf(upload);
|
|
1949
|
+
result.splice(index, 1);
|
|
1912
1950
|
_d.label = 6;
|
|
1913
1951
|
case 6:
|
|
1914
|
-
this.attachmentUploadsSubject.next(__spreadArray([], __read(
|
|
1952
|
+
this.attachmentUploadsSubject.next(__spreadArray([], __read(result)));
|
|
1915
1953
|
return [2 /*return*/];
|
|
1916
1954
|
}
|
|
1917
1955
|
});
|
|
@@ -1994,16 +2032,16 @@
|
|
|
1994
2032
|
};
|
|
1995
2033
|
AttachmentService.prototype.uploadAttachments = function (uploads) {
|
|
1996
2034
|
return __awaiter(this, void 0, void 0, function () {
|
|
1997
|
-
var
|
|
2035
|
+
var result, attachmentUploads;
|
|
1998
2036
|
var _this = this;
|
|
1999
2037
|
return __generator(this, function (_d) {
|
|
2000
2038
|
switch (_d.label) {
|
|
2001
2039
|
case 0:
|
|
2002
|
-
attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
2003
2040
|
this.attachmentUploadInProgressCounterSubject.next(this.attachmentUploadInProgressCounterSubject.getValue() + 1);
|
|
2004
2041
|
return [4 /*yield*/, this.channelService.uploadAttachments(uploads)];
|
|
2005
2042
|
case 1:
|
|
2006
2043
|
result = _d.sent();
|
|
2044
|
+
attachmentUploads = this.attachmentUploadsSubject.getValue();
|
|
2007
2045
|
result.forEach(function (r) {
|
|
2008
2046
|
var upload = attachmentUploads.find(function (upload) { return upload.file === r.file; });
|
|
2009
2047
|
if (!upload) {
|
|
@@ -2730,7 +2768,7 @@
|
|
|
2730
2768
|
var _this = this;
|
|
2731
2769
|
var images = this.attachments.filter(this.isImage);
|
|
2732
2770
|
var containsGallery = images.length >= 2;
|
|
2733
|
-
this.orderedAttachments = __spreadArray(__spreadArray(__spreadArray([], __read((containsGallery ? this.createGallery(images) : images))), __read(this.attachments.filter(function (a) { return _this.isFile(a); }))), __read(this.attachments.filter(function (a) { return _this.isCard(a); })));
|
|
2771
|
+
this.orderedAttachments = __spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read((containsGallery ? this.createGallery(images) : images))), __read(this.attachments.filter(function (a) { return _this.isVideo(a); }))), __read(this.attachments.filter(function (a) { return _this.isFile(a); }))), __read(this.attachments.filter(function (a) { return _this.isCard(a); })));
|
|
2734
2772
|
};
|
|
2735
2773
|
AttachmentListComponent.prototype.trackById = function (index) {
|
|
2736
2774
|
return index;
|
|
@@ -2744,6 +2782,12 @@
|
|
|
2744
2782
|
AttachmentListComponent.prototype.isGallery = function (attachment) {
|
|
2745
2783
|
return attachment.type === 'gallery';
|
|
2746
2784
|
};
|
|
2785
|
+
AttachmentListComponent.prototype.isVideo = function (attachment) {
|
|
2786
|
+
return (attachment.type === 'video' &&
|
|
2787
|
+
attachment.asset_url &&
|
|
2788
|
+
!attachment.og_scrape_url // links from video share services (such as YouTube or Facebook) are can't be played
|
|
2789
|
+
);
|
|
2790
|
+
};
|
|
2747
2791
|
AttachmentListComponent.prototype.isCard = function (attachment) {
|
|
2748
2792
|
return (!attachment.type ||
|
|
2749
2793
|
(attachment.type === 'image' && !this.isImage(attachment)) ||
|
|
@@ -2823,7 +2867,7 @@
|
|
|
2823
2867
|
return AttachmentListComponent;
|
|
2824
2868
|
}());
|
|
2825
2869
|
AttachmentListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentListComponent, deps: [{ token: CustomTemplatesService }, { token: ImageLoadService }, { token: ChannelService }], target: i0__namespace.ɵɵFactoryTarget.Component });
|
|
2826
|
-
AttachmentListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal\">\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <img\n class=\"stream-chat-angular__image-modal-image\"\n data-testid=\"modal-image\"\n [src]=\"\n imagesToView[imagesToViewCurrentIndex].img_url ||\n imagesToView[imagesToViewCurrentIndex].thumb_url ||\n imagesToView[imagesToViewCurrentIndex].image_url\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n />\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-next\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }], directives: [{ type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe, "async": i3__namespace.AsyncPipe } });
|
|
2870
|
+
AttachmentListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", attachments: "attachments" }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0__namespace, template: "<ng-container *ngFor=\"let attachment of orderedAttachments; trackBy: trackById\">\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }}\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n >\n <img\n *ngIf=\"isImage(attachment)\"\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"attachment.img_url || attachment.thumb_url || attachment.image_url\"\n [alt]=\"attachment?.fallback\"\n (load)=\"imageLoaded()\"\n (click)=\"openImageModal([attachment])\"\n (keyup.enter)=\"openImageModal([attachment])\"\n />\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n *ngIf=\"isGallery(attachment)\"\n [class.str-chat__gallery--square]=\"(attachment?.images)!.length > 3\"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachment.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n >\n <img\n [src]=\"\n galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url\n \"\n [alt]=\"galleryImage.fallback\"\n (load)=\"imageLoaded()\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n (click)=\"openImageModal(attachment.images!, index)\"\n (keyup.enter)=\"openImageModal(attachment.images!, index)\"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n (galleryImage.img_url ||\n galleryImage.thumb_url ||\n galleryImage.image_url) +\n ')'\n }\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate: { imageCount: attachment!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n <video\n *ngIf=\"isVideo(attachment)\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"attachment.asset_url\"\n style=\"\n width: 100%;\n max-width: 400px;\n height: 300px;\n border-radius: inherit;\n \"\n ></video>\n <div\n *ngIf=\"isFile(attachment)\"\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n data-testclass=\"file-link\"\n download\n href=\"{{ attachment.asset_url }}\"\n target=\"_blank\"\n >\n {{ attachment.title }}\n </a>\n <span data-testclass=\"size\" *ngIf=\"hasFileSize(attachment)\">{{\n getFileSize(attachment)\n }}</span>\n </div>\n </div>\n <div\n *ngIf=\"isCard(attachment)\"\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachment.type\n }}\"\n >\n <div\n *ngIf=\"attachment.image_url || attachment.thumb_url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n data-testclass=\"card-img\"\n alt=\"{{ attachment.image_url || attachment.thumb_url }}\"\n src=\"{{ attachment.image_url || attachment.thumb_url }}\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachment.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachment.title }}\n </div>\n <div\n *ngIf=\"attachment.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachment.text }}\n </div>\n <a\n class=\"str-chat__message-attachment-card--url\"\n *ngIf=\"attachment.title_link || attachment.og_scrape_url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n href=\"{{ attachment.title_link || attachment.og_scrape_url }}\"\n target=\"_blank\"\n >\n {{ trimUrl(attachment.title_link || attachment.og_scrape_url) }}\n </a>\n </div>\n </div>\n </div>\n <div\n class=\"str-chat__message-attachment-actions\"\n *ngIf=\"attachment.actions && attachment.actions.length > 0\"\n >\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"let action of attachment.actions; trackBy: trackByActionValue\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n data-testclass=\"attachment-action\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n</ng-container>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n [isOpen]=\"isOpen\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n [content]=\"content\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal\">\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <img\n class=\"stream-chat-angular__image-modal-image\"\n data-testid=\"modal-image\"\n [src]=\"\n imagesToView[imagesToViewCurrentIndex].img_url ||\n imagesToView[imagesToViewCurrentIndex].thumb_url ||\n imagesToView[imagesToViewCurrentIndex].image_url\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n />\n <button\n class=\"stream-chat-angular__image-modal-stepper\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n data-testid=\"image-modal-next\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n</ng-template>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }], directives: [{ type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3__namespace.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "translate": i2__namespace.TranslatePipe, "async": i3__namespace.AsyncPipe } });
|
|
2827
2871
|
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentListComponent, decorators: [{
|
|
2828
2872
|
type: i0.Component,
|
|
2829
2873
|
args: [{
|
|
@@ -2866,7 +2910,7 @@
|
|
|
2866
2910
|
return AttachmentPreviewListComponent;
|
|
2867
2911
|
}());
|
|
2868
2912
|
AttachmentPreviewListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentPreviewListComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
|
|
2869
|
-
AttachmentPreviewListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0__namespace, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n <div class=\"rfu-thumbnail__wrapper\" style=\"width: 100; height: 100\">\n <div class=\"rfu-thumbnail__overlay\">\n <div\n class=\"rfu-icon-button\"\n data-testclass=\"delete-attachment\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n </div>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"attachmentUpload.file.name\"\n class=\"rfu-thumbnail__image\"\n data-testclass=\"attachment-image\"\n />\n </div>\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator-placeholder>\n </div>\n <div\n class=\"rfu-file-previewer\"\n *ngIf=\"attachmentUpload.type === 'file'\"\n data-testclass=\"attachment-file-preview\"\n >\n <ol>\n <li\n class=\"rfu-file-previewer__file\"\n [class.rfu-file-previewer__file--uploading]=\"\n attachmentUpload.state === 'uploading'\n \"\n [class.rfu-file-previewer__file--failed]=\"\n attachmentUpload.state === 'error'\n \"\n >\n <stream-icon-placeholder icon=\"file\"></stream-icon-placeholder>\n\n <a\n data-testclass=\"file-download-link\"\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n download\n >\n {{ attachmentUpload.file.name }}\n <ng-container *ngIf=\"attachmentUpload.state === 'error'\">\n <div\n data-testclass=\"file-upload-retry\"\n class=\"rfu-file-previewer__failed\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.retry\n </div>\n </ng-container>\n </a>\n\n <span\n data-testclass=\"file-delete\"\n class=\"rfu-file-previewer__close-button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n \u2718\n </span>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"rfu-file-previewer__loading-indicator\"\n >\n <stream-loading-indicator-placeholder></stream-loading-indicator-placeholder>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3__namespace.AsyncPipe } });
|
|
2913
|
+
AttachmentPreviewListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.5", type: AttachmentPreviewListComponent, selector: "stream-attachment-preview-list", inputs: { attachmentUploads$: "attachmentUploads$" }, outputs: { retryAttachmentUpload: "retryAttachmentUpload", deleteAttachment: "deleteAttachment" }, ngImport: i0__namespace, template: "<div class=\"rfu-image-previewer\" *ngIf=\"(attachmentUploads$ | async)?.length\">\n <ng-container\n *ngFor=\"\n let attachmentUpload of attachmentUploads$ | async;\n trackBy: trackByFile\n \"\n >\n <div\n *ngIf=\"attachmentUpload.type === 'image'\"\n class=\"rfu-image-previewer__image\"\n [class.rfu-image-previewer__image--loaded]=\"\n attachmentUpload.state === 'success'\n \"\n data-testclass=\"attachment-image-preview\"\n >\n <div\n *ngIf=\"attachmentUpload.state === 'error'\"\n class=\"rfu-image-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n data-testclass=\"upload-error\"\n >\n <stream-icon-placeholder icon=\"retry\"></stream-icon-placeholder>\n </div>\n <div class=\"rfu-thumbnail__wrapper\" style=\"width: 100; height: 100\">\n <div class=\"rfu-thumbnail__overlay\">\n <div\n class=\"rfu-icon-button\"\n data-testclass=\"delete-attachment\"\n role=\"button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n <stream-icon-placeholder icon=\"close\"></stream-icon-placeholder>\n </div>\n </div>\n <img\n *ngIf=\"attachmentUpload.url || attachmentUpload.previewUri\"\n src=\"{{\n attachmentUpload.url\n ? attachmentUpload.url\n : attachmentUpload.previewUri\n }}\"\n alt=\"attachmentUpload.file.name\"\n class=\"rfu-thumbnail__image\"\n data-testclass=\"attachment-image\"\n />\n </div>\n <stream-loading-indicator-placeholder\n data-testclass=\"loading-indicator\"\n color=\"rgba(255,255,255,0.7)\"\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n ></stream-loading-indicator-placeholder>\n </div>\n <div\n class=\"rfu-file-previewer\"\n *ngIf=\"\n attachmentUpload.type === 'file' || attachmentUpload.type === 'video'\n \"\n data-testclass=\"attachment-file-preview\"\n >\n <ol>\n <li\n class=\"rfu-file-previewer__file\"\n [class.rfu-file-previewer__file--uploading]=\"\n attachmentUpload.state === 'uploading'\n \"\n [class.rfu-file-previewer__file--failed]=\"\n attachmentUpload.state === 'error'\n \"\n >\n <stream-icon-placeholder icon=\"file\"></stream-icon-placeholder>\n\n <a\n data-testclass=\"file-download-link\"\n href=\"{{ attachmentUpload.url }}\"\n (click)=\"attachmentUpload.url ? null : $event.preventDefault()\"\n (keyup.enter)=\"\n attachmentUpload.url ? null : $event.preventDefault()\n \"\n download\n >\n {{ attachmentUpload.file.name }}\n <ng-container *ngIf=\"attachmentUpload.state === 'error'\">\n <div\n data-testclass=\"file-upload-retry\"\n class=\"rfu-file-previewer__failed\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.failed\n </div>\n <div\n class=\"rfu-file-previewer__retry\"\n (click)=\"attachmentUploadRetried(attachmentUpload.file)\"\n (keyup.enter)=\"attachmentUploadRetried(attachmentUpload.file)\"\n translate\n >\n streamChat.retry\n </div>\n </ng-container>\n </a>\n\n <span\n data-testclass=\"file-delete\"\n class=\"rfu-file-previewer__close-button\"\n (click)=\"attachmentDeleted(attachmentUpload)\"\n (keyup.enter)=\"attachmentDeleted(attachmentUpload)\"\n >\n \u2718\n </span>\n <div\n *ngIf=\"attachmentUpload.state === 'uploading'\"\n class=\"rfu-file-previewer__loading-indicator\"\n >\n <stream-loading-indicator-placeholder></stream-loading-indicator-placeholder>\n </div>\n </li>\n </ol>\n </div>\n </ng-container>\n</div>\n", components: [{ type: IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { type: LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }], directives: [{ type: i3__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], pipes: { "async": i3__namespace.AsyncPipe } });
|
|
2870
2914
|
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.5", ngImport: i0__namespace, type: AttachmentPreviewListComponent, decorators: [{
|
|
2871
2915
|
type: i0.Component,
|
|
2872
2916
|
args: [{
|
|
@@ -3030,7 +3074,7 @@
|
|
|
3030
3074
|
MessageInputComponent.prototype.messageSent = function () {
|
|
3031
3075
|
var _a;
|
|
3032
3076
|
return __awaiter(this, void 0, void 0, function () {
|
|
3033
|
-
var attachmentUploadInProgressCounter, attachments, text, error_1;
|
|
3077
|
+
var attachmentUploadInProgressCounter, attachments, text, textContainsOnlySpaceChars, error_1;
|
|
3034
3078
|
return __generator(this, function (_12) {
|
|
3035
3079
|
switch (_12.label) {
|
|
3036
3080
|
case 0:
|
|
@@ -3046,9 +3090,14 @@
|
|
|
3046
3090
|
}
|
|
3047
3091
|
attachments = this.attachmentService.mapToAttachments();
|
|
3048
3092
|
text = this.textareaValue;
|
|
3049
|
-
|
|
3093
|
+
textContainsOnlySpaceChars = !text.replace(/ /g, '');
|
|
3094
|
+
if ((!text || textContainsOnlySpaceChars) &&
|
|
3095
|
+
(!attachments || attachments.length === 0)) {
|
|
3050
3096
|
return [2 /*return*/];
|
|
3051
3097
|
}
|
|
3098
|
+
if (textContainsOnlySpaceChars) {
|
|
3099
|
+
text = '';
|
|
3100
|
+
}
|
|
3052
3101
|
if (this.containsLinks && !this.canSendLinks) {
|
|
3053
3102
|
this.notificationService.addTemporaryNotification('streamChat.Sending links is not allowed in this conversation');
|
|
3054
3103
|
return [2 /*return*/];
|
|
@@ -4364,7 +4413,12 @@
|
|
|
4364
4413
|
this.message.mentioned_users.length === 0) {
|
|
4365
4414
|
// Wrap emojis in span to display emojis correctly in Chrome https://bugs.chromium.org/p/chromium/issues/detail?id=596223
|
|
4366
4415
|
var regex = new RegExp(emojiRegex__default['default'](), 'g');
|
|
4367
|
-
|
|
4416
|
+
// Based on this: https://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome
|
|
4417
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4418
|
+
var isChrome_1 = !!window.chrome &&
|
|
4419
|
+
typeof window.opr === 'undefined';
|
|
4420
|
+
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
4421
|
+
content = content.replace(regex, function (match) { return "<span " + (isChrome_1 ? 'class="str-chat__emoji-display-fix"' : '') + ">" + match + "</span>"; });
|
|
4368
4422
|
this.messageTextParts = [{ content: content, type: 'text' }];
|
|
4369
4423
|
}
|
|
4370
4424
|
else {
|