@chat21/chat21-web-widget 5.1.32-rc9 → 5.1.33-rc11
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/.angular-mcp-cache/package.json +1 -0
- package/.cursor/angular18-accessibility-auditor-skill.md +442 -0
- package/.cursor/mcp.json +15 -0
- package/.github/workflows/playwright.yml +27 -0
- package/.playwright-mcp/console-2026-05-08T15-31-09-000Z.log +17 -0
- package/.playwright-mcp/console-2026-05-08T15-32-19-412Z.log +89 -0
- package/.playwright-mcp/console-2026-05-08T16-18-48-424Z.log +133 -0
- package/.playwright-mcp/console-2026-05-11T12-54-06-869Z.log +13 -0
- package/.playwright-mcp/console-2026-05-11T12-54-56-229Z.log +147 -0
- package/.playwright-mcp/console-2026-05-11T12-55-47-174Z.log +183 -0
- package/.playwright-mcp/console-2026-05-11T15-34-03-590Z.log +210 -0
- package/.playwright-mcp/console-2026-05-12T15-07-31-880Z.log +118 -0
- package/.playwright-mcp/page-2026-05-08T15-32-19-900Z.yml +851 -0
- package/.playwright-mcp/page-2026-05-08T15-32-47-264Z.yml +857 -0
- package/.playwright-mcp/page-2026-05-08T15-33-17-089Z.yml +1110 -0
- package/.playwright-mcp/page-2026-05-08T15-33-23-486Z.yml +1069 -0
- package/.playwright-mcp/page-2026-05-08T15-33-45-390Z.yml +1076 -0
- package/.playwright-mcp/page-2026-05-08T15-33-52-666Z.yml +1072 -0
- package/.playwright-mcp/page-2026-05-08T15-34-01-338Z.yml +1085 -0
- package/.playwright-mcp/page-2026-05-08T15-34-07-227Z.yml +1072 -0
- package/.playwright-mcp/page-2026-05-08T15-34-13-875Z.yml +1072 -0
- package/.playwright-mcp/page-2026-05-08T15-34-21-885Z.yml +1109 -0
- package/.playwright-mcp/page-2026-05-08T15-34-32-755Z.yml +1109 -0
- package/.playwright-mcp/page-2026-05-08T15-35-09-607Z.yml +1119 -0
- package/.playwright-mcp/page-2026-05-08T15-35-14-242Z.yml +1109 -0
- package/.playwright-mcp/page-2026-05-08T16-18-48-671Z.yml +44 -0
- package/.playwright-mcp/page-2026-05-08T16-18-52-753Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-19-13-919Z.yml +68 -0
- package/.playwright-mcp/page-2026-05-08T16-19-17-977Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-19-25-733Z.yml +120 -0
- package/.playwright-mcp/page-2026-05-08T16-19-29-252Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-19-39-269Z.yml +80 -0
- package/.playwright-mcp/page-2026-05-08T16-19-43-915Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-20-04-407Z.yml +81 -0
- package/.playwright-mcp/page-2026-05-08T16-20-08-984Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-20-32-397Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-20-58-658Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-21-12-320Z.yml +86 -0
- package/.playwright-mcp/page-2026-05-08T16-21-39-154Z.yml +91 -0
- package/.playwright-mcp/page-2026-05-08T16-21-45-420Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-22-21-062Z.yml +0 -0
- package/.playwright-mcp/page-2026-05-08T16-22-58-232Z.yml +91 -0
- package/.playwright-mcp/page-2026-05-08T16-23-36-520Z.yml +0 -0
- package/.playwright-mcp/page-2026-05-08T16-23-46-805Z.yml +100 -0
- package/.playwright-mcp/page-2026-05-08T16-23-55-169Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-24-26-574Z.yml +91 -0
- package/.playwright-mcp/page-2026-05-08T16-25-34-414Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-25-59-831Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-26-21-809Z.yml +91 -0
- package/.playwright-mcp/page-2026-05-08T16-26-47-443Z.yml +105 -0
- package/.playwright-mcp/page-2026-05-08T16-26-56-136Z.png +0 -0
- package/.playwright-mcp/page-2026-05-08T16-27-59-610Z.yml +48 -0
- package/.playwright-mcp/page-2026-05-11T12-54-07-180Z.yml +44 -0
- package/.playwright-mcp/page-2026-05-11T12-54-56-946Z.yml +4 -0
- package/.playwright-mcp/page-2026-05-11T12-55-47-503Z.yml +24 -0
- package/.playwright-mcp/page-2026-05-11T12-56-00-766Z.yml +28 -0
- package/.playwright-mcp/page-2026-05-11T12-56-06-438Z.yml +90 -0
- package/.playwright-mcp/page-2026-05-11T12-57-56-838Z.yml +106 -0
- package/.playwright-mcp/page-2026-05-11T12-58-00-124Z.yml +106 -0
- package/.playwright-mcp/page-2026-05-11T12-59-08-836Z.yml +61 -0
- package/.playwright-mcp/page-2026-05-11T12-59-12-088Z.yml +61 -0
- package/.playwright-mcp/page-2026-05-11T12-59-26-215Z.yml +69 -0
- package/.playwright-mcp/page-2026-05-11T12-59-29-519Z.yml +69 -0
- package/.playwright-mcp/page-2026-05-11T12-59-37-309Z.yml +0 -0
- package/.playwright-mcp/page-2026-05-11T12-59-39-968Z.yml +79 -0
- package/.playwright-mcp/page-2026-05-11T12-59-45-983Z.yml +78 -0
- package/.playwright-mcp/page-2026-05-11T12-59-49-951Z.yml +78 -0
- package/.playwright-mcp/page-2026-05-11T15-34-04-515Z.yml +0 -0
- package/.playwright-mcp/page-2026-05-12T15-07-32-171Z.yml +44 -0
- package/.playwright-mcp/page-2026-05-12T15-08-09-820Z.yml +119 -0
- package/CHANGELOG.md +61 -4
- package/angular.json +20 -3
- package/deploy_amazon_beta.sh +7 -17
- package/deploy_amazon_prod.sh +41 -0
- package/docs/TILEDESK_WIDGET_ACCESSIBILITY_STATEMENT_COMPLETE.md +379 -0
- package/env.sample +3 -2
- package/mocks/voice-websocket-mock/server.cjs +245 -0
- package/package.json +7 -3
- package/playwright.config.ts +41 -0
- package/src/app/app.component.html +2 -2
- package/src/app/app.component.scss +25 -14
- package/src/app/app.component.spec.ts +21 -6
- package/src/app/app.module.ts +4 -0
- package/src/app/component/conversation-detail/conversation/conversation.component.html +19 -11
- package/src/app/component/conversation-detail/conversation/conversation.component.scss +28 -0
- package/src/app/component/conversation-detail/conversation/conversation.component.spec.ts +644 -75
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +63 -17
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html +25 -13
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.spec.ts +123 -5
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.ts +1 -0
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +17 -7
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +15 -3
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.spec.ts +242 -149
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +7 -6
- package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.spec.ts +53 -3
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component copy.html +172 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +112 -61
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +133 -16
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.spec.ts +452 -78
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +198 -84
- package/src/app/component/conversation-detail/conversation-header/conversation-header.component.html +113 -53
- package/src/app/component/conversation-detail/conversation-header/conversation-header.component.scss +12 -4
- package/src/app/component/conversation-detail/conversation-header/conversation-header.component.spec.ts +274 -29
- package/src/app/component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component.html +23 -9
- package/src/app/component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component.spec.ts +80 -8
- package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.html +29 -23
- package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.spec.ts +185 -16
- package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.ts +34 -14
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.html +46 -18
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.scss +60 -2
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.ts +135 -5
- package/src/app/component/error-alert/error-alert.component.spec.ts +65 -5
- package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.html +16 -7
- package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.scss +21 -0
- package/src/app/component/eyeeye-catcher-card/eyeeye-catcher-card.component.spec.ts +89 -7
- package/src/app/component/form/form-builder/form-builder.component.html +1 -1
- package/src/app/component/form/form-builder/form-builder.component.spec.ts +163 -21
- package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.html +8 -4
- package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.scss +10 -5
- package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.spec.ts +90 -16
- package/src/app/component/form/inputs/form-checkbox/form-checkbox.component.ts +26 -0
- package/src/app/component/form/inputs/form-label/form-label.component.spec.ts +45 -11
- package/src/app/component/form/inputs/form-radio-button/form-radio-button.component.spec.ts +24 -6
- package/src/app/component/form/inputs/form-select/form-select.component.spec.ts +14 -5
- package/src/app/component/form/inputs/form-text/form-text.component.html +14 -12
- package/src/app/component/form/inputs/form-text/form-text.component.scss +11 -1
- package/src/app/component/form/inputs/form-text/form-text.component.spec.ts +113 -17
- package/src/app/component/form/inputs/form-text/form-text.component.ts +35 -3
- package/src/app/component/form/inputs/form-textarea/form-textarea.component.html +13 -11
- package/src/app/component/form/inputs/form-textarea/form-textarea.component.scss +6 -5
- package/src/app/component/form/inputs/form-textarea/form-textarea.component.spec.ts +149 -13
- package/src/app/component/form/inputs/form-textarea/form-textarea.component.ts +26 -0
- package/src/app/component/form/prechat-form/prechat-form.component.html +14 -11
- package/src/app/component/form/prechat-form/prechat-form.component.spec.ts +102 -10
- package/src/app/component/form/prechat-form/prechat-form.component.ts +8 -1
- package/src/app/component/form/prechat-form-test-mock.ts +35 -0
- package/src/app/component/home/home.component.html +38 -31
- package/src/app/component/home/home.component.scss +4 -2
- package/src/app/component/home/home.component.spec.ts +226 -11
- package/src/app/component/home-conversations/home-conversations.component.html +30 -26
- package/src/app/component/home-conversations/home-conversations.component.scss +3 -0
- package/src/app/component/home-conversations/home-conversations.component.spec.ts +212 -36
- package/src/app/component/last-message/last-message.component.html +15 -9
- package/src/app/component/last-message/last-message.component.scss +16 -2
- package/src/app/component/last-message/last-message.component.spec.ts +204 -23
- package/src/app/component/launcher-button/launcher-button.component.html +8 -13
- package/src/app/component/launcher-button/launcher-button.component.spec.ts +104 -8
- package/src/app/component/list-all-conversations/list-all-conversations.component.html +12 -17
- package/src/app/component/list-all-conversations/list-all-conversations.component.scss +2 -0
- package/src/app/component/list-conversations/list-conversations.component.html +22 -22
- package/src/app/component/menu-options/menu-options.component.html +30 -20
- package/src/app/component/menu-options/menu-options.component.spec.ts +125 -9
- package/src/app/component/message/audio/audio.component.html +13 -15
- package/src/app/component/message/audio/audio.component.spec.ts +140 -5
- package/src/app/component/message/audio/audio.component.ts +1 -0
- package/src/app/component/message/audio-sync/audio-sync.component.scss +1 -0
- package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +81 -1
- package/src/app/component/message/audio-sync/audio-sync.component.ts +133 -86
- package/src/app/component/message/avatar/avatar.component.html +2 -2
- package/src/app/component/message/avatar/avatar.component.spec.ts +99 -7
- package/src/app/component/message/bubble-message/bubble-message.component.html +39 -52
- package/src/app/component/message/bubble-message/bubble-message.component.scss +59 -1
- package/src/app/component/message/bubble-message/bubble-message.component.spec.ts +154 -57
- package/src/app/component/message/bubble-message/bubble-message.component.ts +152 -110
- package/src/app/component/message/buttons/action-button/action-button.component.html +3 -4
- package/src/app/component/message/buttons/action-button/action-button.component.spec.ts +49 -5
- package/src/app/component/message/buttons/link-button/link-button.component.scss +5 -8
- package/src/app/component/message/buttons/link-button/link-button.component.spec.ts +50 -5
- package/src/app/component/message/buttons/text-button/text-button.component.spec.ts +44 -5
- package/src/app/component/message/carousel/carousel.component.html +29 -16
- package/src/app/component/message/carousel/carousel.component.scss +20 -8
- package/src/app/component/message/carousel/carousel.component.spec.ts +80 -3
- package/src/app/component/message/carousel/carousel.component.ts +16 -0
- package/src/app/component/message/frame/frame.component.html +9 -4
- package/src/app/component/message/frame/frame.component.spec.ts +34 -15
- package/src/app/component/message/frame/frame.component.ts +7 -2
- package/src/app/component/message/html/html.component.html +1 -1
- package/src/app/component/message/html/html.component.scss +1 -1
- package/src/app/component/message/html/html.component.spec.ts +24 -7
- package/src/app/component/message/image/image.component.html +12 -10
- package/src/app/component/message/image/image.component.scss +16 -0
- package/src/app/component/message/image/image.component.spec.ts +101 -15
- package/src/app/component/message/image/image.component.ts +90 -51
- package/src/app/component/message/info-message/info-message.component.spec.ts +26 -14
- package/src/app/component/message/json-sources/json-sources.component.html +38 -0
- package/src/app/component/message/json-sources/json-sources.component.scss +201 -0
- package/src/app/component/message/json-sources/json-sources.component.ts +89 -0
- package/src/app/component/message/like-unlike/like-unlike.component.html +7 -9
- package/src/app/component/message/like-unlike/like-unlike.component.spec.ts +31 -3
- package/src/app/component/message/return-receipt/return-receipt.component.spec.ts +38 -17
- package/src/app/component/message/text/text.component.html +3 -3
- package/src/app/component/message/text/text.component.scss +80 -86
- package/src/app/component/message/text/text.component.spec.ts +106 -13
- package/src/app/component/message-attachment/message-attachment.component.spec.ts +134 -13
- package/src/app/component/selection-department/selection-department.component.html +21 -23
- package/src/app/component/selection-department/selection-department.component.spec.ts +159 -14
- package/src/app/component/selection-department/selection-department.component.ts +8 -1
- package/src/app/component/send-button/send-button.component.html +5 -13
- package/src/app/component/send-button/send-button.component.spec.ts +2 -2
- package/src/app/component/star-rating-widget/star-rating-widget.component.html +51 -81
- package/src/app/directives/tooltip.directive.spec.ts +8 -4
- package/src/app/modals/confirm-close/confirm-close.component.html +20 -8
- package/src/app/modals/confirm-close/confirm-close.component.scss +3 -0
- package/src/app/modals/confirm-close/confirm-close.component.spec.ts +13 -4
- package/src/app/modals/confirm-close/confirm-close.component.ts +8 -1
- package/src/app/pipe/html-entites-encode.pipe.spec.ts +35 -2
- package/src/app/pipe/marked.pipe.spec.ts +38 -2
- package/src/app/pipe/marked.pipe.ts +51 -41
- package/src/app/providers/app-config.service.ts +4 -2
- package/src/app/providers/brand.service.spec.ts +23 -2
- package/src/app/providers/brand.service.ts +1 -1
- package/src/app/providers/global-settings.service.spec.ts +1009 -14
- package/src/app/providers/global-settings.service.ts +59 -2
- package/src/app/providers/json-sources-parser.service.ts +175 -0
- package/src/app/providers/translator.service.ts +24 -6
- package/src/app/providers/tts-audio-playback-coordinator.service.spec.ts +117 -0
- package/src/app/providers/tts-audio-playback-coordinator.service.ts +39 -16
- package/src/app/providers/url-preview.service.ts +82 -0
- package/src/app/providers/voice/audio.types.ts +6 -0
- package/src/app/providers/voice/voice-streaming.service.spec.ts +23 -0
- package/src/app/providers/voice/voice-streaming.service.ts +702 -0
- package/src/app/providers/voice/voice-streaming.types.ts +112 -0
- package/src/app/providers/voice/voice.service.spec.ts +170 -3
- package/src/app/providers/voice/voice.service.ts +691 -17
- package/src/app/sass/_variables.scss +1 -1
- package/src/app/sass/animations.scss +19 -1
- package/src/app/utils/globals.ts +14 -0
- package/src/app/utils/json-sources-utils.ts +27 -0
- package/src/app/utils/url-utils.ts +98 -0
- package/src/app/utils/utils-resources.ts +1 -1
- package/src/assets/i18n/en.json +106 -100
- package/src/assets/i18n/es.json +107 -101
- package/src/assets/i18n/fr.json +107 -101
- package/src/assets/i18n/it.json +107 -99
- package/src/assets/sounds/keyboard.mp3 +0 -0
- package/src/assets/twp/index-dev.html +18 -0
- package/src/assets/twp/tiledesk_widget_files/widget-css-override-example.css +14 -0
- package/src/chat21-core/providers/chat-manager.spec.ts +72 -0
- package/src/chat21-core/providers/scripts/script.service.spec.ts +12 -2
- package/src/chat21-core/utils/constants.ts +4 -0
- package/src/chat21-core/utils/utils-message.ts +23 -1
- package/src/widget-config-template.json +3 -1
- package/src/widget-config.json +28 -27
- package/tests/widget-form-rich.spec.ts +67 -0
- package/tests/widget-index-dev-settings.spec.ts +52 -0
- package/tests/widget-twp-iframe.spec.ts +39 -0
|
@@ -163,6 +163,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
163
163
|
|
|
164
164
|
// ========== begin:: stream audio ======= //
|
|
165
165
|
public isStreamAudioActive = false;
|
|
166
|
+
public isStreamAudioConnecting = false;
|
|
166
167
|
// ========== end:: stream audio ======= //
|
|
167
168
|
|
|
168
169
|
@ViewChild(ConversationFooterComponent) conversationFooter: ConversationFooterComponent
|
|
@@ -251,7 +252,21 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
251
252
|
'EMOJI_NOT_ELLOWED',
|
|
252
253
|
'ATTACHMENT',
|
|
253
254
|
'EMOJI',
|
|
254
|
-
'
|
|
255
|
+
'BUTTON_ATTACH_FILE',
|
|
256
|
+
'BUTTON_SEND_MESSAGE',
|
|
257
|
+
'BUTTON_RECORD_AUDIO',
|
|
258
|
+
'BUTTON_DELETE_AUDIO',
|
|
259
|
+
'BUTTON_SEND_AUDIO',
|
|
260
|
+
'BUTTON_PLAY_AUDIO',
|
|
261
|
+
'BUTTON_PAUSE_AUDIO',
|
|
262
|
+
'SKIP_TO_COMPOSER',
|
|
263
|
+
'CLOSE_CHAT',
|
|
264
|
+
'CLOSE',
|
|
265
|
+
'VOICE_CONNECTING',
|
|
266
|
+
'VOICE_LISTENING',
|
|
267
|
+
'VOICE_PROCESSING',
|
|
268
|
+
'STREAM_AUDIO',
|
|
269
|
+
'MAX_ATTACHMENT'
|
|
255
270
|
];
|
|
256
271
|
|
|
257
272
|
const keysContent = [
|
|
@@ -271,13 +286,21 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
271
286
|
'LABEL_THINKING',
|
|
272
287
|
'LABEL_TO',
|
|
273
288
|
'ARRAY_DAYS',
|
|
289
|
+
'CONVERSATION_LOG_LABEL',
|
|
290
|
+
'BUTTON_SCROLL_TO_BOTTOM',
|
|
291
|
+
'CAROUSEL_PREVIOUS',
|
|
292
|
+
'CAROUSEL_NEXT',
|
|
293
|
+
'CAROUSEL_LABEL',
|
|
294
|
+
'CAROUSEL_SLIDE_LABEL'
|
|
274
295
|
];
|
|
275
296
|
|
|
276
297
|
const keysPreview= [
|
|
277
298
|
'BACK',
|
|
278
299
|
'CLOSE',
|
|
279
300
|
'LABEL_PLACEHOLDER',
|
|
280
|
-
'LABEL_PREVIEW'
|
|
301
|
+
'LABEL_PREVIEW',
|
|
302
|
+
'BUTTON_CLOSE_PREVIEW',
|
|
303
|
+
'BUTTON_SEND_MESSAGE'
|
|
281
304
|
];
|
|
282
305
|
|
|
283
306
|
const keysCloseChatDialog= [
|
|
@@ -506,27 +529,31 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
506
529
|
return this.isConversationArchived;
|
|
507
530
|
}
|
|
508
531
|
|
|
509
|
-
//
|
|
510
|
-
|
|
532
|
+
// FALLBACK TO TILEDESK
|
|
533
|
+
let requests_list: { requests: any[] };
|
|
534
|
+
try {
|
|
535
|
+
requests_list = await this.tiledeskRequestService.getMyRequests();
|
|
536
|
+
} catch (err) {
|
|
511
537
|
this.logger.error('[CONV-COMP] getConversationDetail: error getting request from Tiledesk', err);
|
|
512
|
-
this.isConversationArchived=true
|
|
513
|
-
return
|
|
514
|
-
}
|
|
538
|
+
this.isConversationArchived = true;
|
|
539
|
+
return this.isConversationArchived;
|
|
540
|
+
}
|
|
541
|
+
|
|
515
542
|
if (requests_list && requests_list.requests.length > 0) {
|
|
516
543
|
this.logger.debug('[CONV-COMP] getConversationDetail: request exist on Tiledesk', requests_list);
|
|
517
|
-
|
|
518
|
-
if(conversation){
|
|
519
|
-
this.isConversationArchived = false
|
|
520
|
-
return this.isConversationArchived
|
|
544
|
+
const conversation = requests_list.requests.find((request) => request.request_id === this.conversationId);
|
|
545
|
+
if (conversation) {
|
|
546
|
+
this.isConversationArchived = false;
|
|
547
|
+
return this.isConversationArchived;
|
|
521
548
|
}
|
|
522
549
|
this.logger.debug('[CONV-COMP] getConversationDetail: request NOT EXIST on Tiledesk', requests_list);
|
|
523
|
-
this.isConversationArchived = true
|
|
524
|
-
return this.isConversationArchived
|
|
550
|
+
this.isConversationArchived = true;
|
|
551
|
+
return this.isConversationArchived;
|
|
525
552
|
}
|
|
526
553
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
554
|
+
this.isConversationArchived = false;
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
530
557
|
|
|
531
558
|
/**
|
|
532
559
|
* this.g.recipientId:
|
|
@@ -1055,6 +1082,21 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
1055
1082
|
|
|
1056
1083
|
|
|
1057
1084
|
|
|
1085
|
+
/**
|
|
1086
|
+
* Programmatically moves keyboard focus to the message composer textarea.
|
|
1087
|
+
* Wired to the visible-on-focus skip link in conversation.component.html (WCAG 2.4.1 Bypass Blocks).
|
|
1088
|
+
*/
|
|
1089
|
+
skipToCompose() {
|
|
1090
|
+
try {
|
|
1091
|
+
const textarea = document.getElementById('chat21-main-message-context') as HTMLTextAreaElement | null;
|
|
1092
|
+
if (textarea) {
|
|
1093
|
+
textarea.focus();
|
|
1094
|
+
}
|
|
1095
|
+
} catch(e) {
|
|
1096
|
+
this.logger.warn('[CONV-COMP] skipToCompose error', e);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1058
1100
|
scrollToBottom() {
|
|
1059
1101
|
this.conversationContent.scrollToBottom();
|
|
1060
1102
|
// const that = this;
|
|
@@ -1411,6 +1453,10 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
1411
1453
|
onStreamAudioActiveChange(event: boolean){
|
|
1412
1454
|
this.isStreamAudioActive = event
|
|
1413
1455
|
}
|
|
1456
|
+
/** CALLED BY: conv-footer when connecting state changes */
|
|
1457
|
+
onStreamAudioConnectingChange(event: boolean){
|
|
1458
|
+
this.isStreamAudioConnecting = event
|
|
1459
|
+
}
|
|
1414
1460
|
/** CALLED BY: conv-footer component */
|
|
1415
1461
|
onCloseChatButtonClickedFN(event){
|
|
1416
1462
|
this.logger.debug('[CONV-COMP] onCloseChatButtonClicked::::', event)
|
|
@@ -1423,7 +1469,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
1423
1469
|
* Solo in quel caso il bottom del foglio include `--chat-footer-stream-button-height`.
|
|
1424
1470
|
*/
|
|
1425
1471
|
closeStreamButtonActiveForSheetBottom(): boolean {
|
|
1426
|
-
return !!(this.g?.showAudioStreamFooterButton && this.isStreamAudioActive);
|
|
1472
|
+
return !!(this.g?.showAudioStreamFooterButton && (this.isStreamAudioActive || this.isStreamAudioConnecting));
|
|
1427
1473
|
}
|
|
1428
1474
|
|
|
1429
1475
|
openInputFiles() {
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
<div class="audio-recorder">
|
|
2
|
-
<button *ngIf="audioUrl" (click)="deleteRecording()">
|
|
2
|
+
<button *ngIf="audioUrl" type="button" [attr.aria-label]="translationMap?.get('BUTTON_DELETE_AUDIO') || 'Delete recording'" (click)="deleteRecording()">
|
|
3
3
|
<span class="v-align-center">
|
|
4
|
-
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
4
|
+
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
5
5
|
<path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm80-160h80v-360h-80v360Zm160 0h80v-360h-80v360Z"/>
|
|
6
6
|
</svg>
|
|
7
|
-
<!-- <i class="material-icons">delete_outline</i> -->
|
|
8
7
|
</span>
|
|
9
8
|
</button>
|
|
10
9
|
|
|
11
|
-
<chat-audio
|
|
12
|
-
[audioBlob]
|
|
10
|
+
<chat-audio class="test" *ngIf="audioBlob && audioUrl"
|
|
11
|
+
[audioBlob]="audioBlob"
|
|
13
12
|
[color]="'var(--chat-footer-color)'"
|
|
13
|
+
[translationMap]="translationMap"
|
|
14
14
|
[stylesMap]="stylesMap">
|
|
15
15
|
</chat-audio>
|
|
16
|
-
|
|
17
|
-
<button *ngIf="!audioUrl"
|
|
18
|
-
|
|
16
|
+
|
|
17
|
+
<button *ngIf="!audioUrl"
|
|
18
|
+
type="button"
|
|
19
|
+
class="mic-button"
|
|
20
|
+
[attr.aria-label]="translationMap?.get('BUTTON_RECORD_AUDIO') || 'Hold to record an audio message'"
|
|
21
|
+
[attr.aria-pressed]="isRecording ? 'true' : 'false'"
|
|
22
|
+
(mousedown)="startRecording($event)"
|
|
23
|
+
(mouseup)="stopRecording($event)"
|
|
24
|
+
(touchstart)="startRecording($event)"
|
|
25
|
+
(touchend)="stopRecording($event)"
|
|
26
|
+
(keydown.space)="$event.preventDefault(); !isRecording && startRecording($event)"
|
|
27
|
+
(keyup.space)="$event.preventDefault(); isRecording && stopRecording($event)">
|
|
28
|
+
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
19
29
|
<path d="M480-400q-50 0-85-35t-35-85v-240q0-50 35-85t85-35q50 0 85 35t35 85v240q0 50-35 85t-85 35Zm0-240Zm-40 520v-123q-104-14-172-93t-68-184h80q0 83 58.5 141.5T480-320q83 0 141.5-58.5T680-520h80q0 105-68 184t-172 93v123h-80Zm40-360q17 0 28.5-11.5T520-520v-240q0-17-11.5-28.5T480-800q-17 0-28.5 11.5T440-760v240q0 17 11.5 28.5T480-480Z"/>
|
|
20
30
|
</svg>
|
|
21
31
|
</button>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
|
|
33
|
+
<button *ngIf="audioUrl"
|
|
34
|
+
type="button"
|
|
35
|
+
[attr.aria-label]="translationMap?.get('BUTTON_SEND_AUDIO') || 'Send audio message'"
|
|
36
|
+
(click)="sendMessage()">
|
|
25
37
|
<span class="v-align-center">
|
|
26
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
38
|
+
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="20" width="24" viewBox="0 0 24 20" xml:space="preserve">
|
|
27
39
|
<path d="M1.8,18.9V1.7L22,10.3L1.8,18.9z M3.9,15.6l12.6-5.4L3.9,4.9v3.7l6.4,1.6l-6.4,1.6V15.6z M3.9,15.6V4.9v7V15.6z"/>
|
|
28
40
|
</svg>
|
|
29
41
|
</span>
|
|
30
42
|
</button>
|
|
31
43
|
|
|
32
|
-
</div>
|
|
44
|
+
</div>
|
|
@@ -1,23 +1,141 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
1
|
+
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
2
2
|
|
|
3
3
|
import { ConversationAudioRecorderComponent } from './conversation-audio-recorder.component';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
5
|
+
describe('ConversationAudioRecorderComponent', () => {
|
|
6
6
|
let component: ConversationAudioRecorderComponent;
|
|
7
7
|
let fixture: ComponentFixture<ConversationAudioRecorderComponent>;
|
|
8
|
+
let stopListeners: { stop?: () => void; data?: (e: { data: Blob }) => void };
|
|
9
|
+
let mediaRecorderInstance: {
|
|
10
|
+
start: jasmine.Spy;
|
|
11
|
+
stop: jasmine.Spy;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
addEventListener: jasmine.Spy;
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
beforeEach(async () => {
|
|
17
|
+
stopListeners = {};
|
|
18
|
+
mediaRecorderInstance = {
|
|
19
|
+
start: jasmine.createSpy('start'),
|
|
20
|
+
stop: jasmine.createSpy('stop').and.callFake(() => {
|
|
21
|
+
const fn = stopListeners.stop;
|
|
22
|
+
if (fn) {
|
|
23
|
+
fn();
|
|
24
|
+
}
|
|
25
|
+
}),
|
|
26
|
+
mimeType: 'audio/webm',
|
|
27
|
+
addEventListener: jasmine.createSpy('addEventListener').and.callFake((ev: string, fn: any) => {
|
|
28
|
+
if (ev === 'stop') {
|
|
29
|
+
stopListeners.stop = fn;
|
|
30
|
+
}
|
|
31
|
+
if (ev === 'dataavailable') {
|
|
32
|
+
stopListeners.data = fn;
|
|
33
|
+
}
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const stream = {
|
|
38
|
+
getTracks: () => [{ stop: jasmine.createSpy('trackStop') }],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
spyOn(window.navigator.mediaDevices, 'getUserMedia').and.returnValue(Promise.resolve(stream as any));
|
|
42
|
+
(window as any).MediaRecorder = jasmine.createSpy('MediaRecorder').and.returnValue(mediaRecorderInstance);
|
|
43
|
+
|
|
10
44
|
await TestBed.configureTestingModule({
|
|
11
|
-
declarations: [
|
|
12
|
-
})
|
|
13
|
-
.compileComponents();
|
|
45
|
+
declarations: [ConversationAudioRecorderComponent],
|
|
46
|
+
}).compileComponents();
|
|
14
47
|
|
|
15
48
|
fixture = TestBed.createComponent(ConversationAudioRecorderComponent);
|
|
16
49
|
component = fixture.componentInstance;
|
|
50
|
+
component.translationMap = new Map();
|
|
51
|
+
component.stylesMap = new Map();
|
|
52
|
+
spyOn(component.startRecordingEvent, 'emit');
|
|
53
|
+
spyOn(component.endRecordingEvent, 'emit');
|
|
17
54
|
fixture.detectChanges();
|
|
18
55
|
});
|
|
19
56
|
|
|
20
57
|
it('should create', () => {
|
|
21
58
|
expect(component).toBeTruthy();
|
|
22
59
|
});
|
|
60
|
+
|
|
61
|
+
describe('startRecording', () => {
|
|
62
|
+
it('should preventDefault on touchstart', fakeAsync(() => {
|
|
63
|
+
const ev = { type: 'touchstart', preventDefault: jasmine.createSpy('pd') } as any;
|
|
64
|
+
component.startRecording(ev);
|
|
65
|
+
tick();
|
|
66
|
+
expect(ev.preventDefault).toHaveBeenCalled();
|
|
67
|
+
expect(component.startRecordingEvent.emit).toHaveBeenCalled();
|
|
68
|
+
}));
|
|
69
|
+
|
|
70
|
+
it('should request microphone and start MediaRecorder on mousedown', fakeAsync(() => {
|
|
71
|
+
const ev = new MouseEvent('mousedown');
|
|
72
|
+
component.startRecording(ev);
|
|
73
|
+
tick();
|
|
74
|
+
expect(navigator.mediaDevices.getUserMedia).toHaveBeenCalledWith({ audio: true });
|
|
75
|
+
expect(mediaRecorderInstance.start).toHaveBeenCalled();
|
|
76
|
+
expect(component.isRecording).toBe(true);
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
it('should log when getUserMedia fails', fakeAsync(() => {
|
|
80
|
+
(navigator.mediaDevices.getUserMedia as jasmine.Spy).and.returnValue(Promise.reject(new Error('denied')));
|
|
81
|
+
spyOn(console, 'error');
|
|
82
|
+
component.startRecording(new MouseEvent('mousedown'));
|
|
83
|
+
tick();
|
|
84
|
+
expect(console.error).toHaveBeenCalled();
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('stopRecording', () => {
|
|
89
|
+
it('should discard very short press without stopping recorder', fakeAsync(() => {
|
|
90
|
+
component.startTime = Date.now();
|
|
91
|
+
component.stopRecording(new MouseEvent('mouseup'));
|
|
92
|
+
tick(400);
|
|
93
|
+
expect(mediaRecorderInstance.stop).not.toHaveBeenCalled();
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
it('should stop recorder after long press', fakeAsync(() => {
|
|
97
|
+
component.mediaRecorder = mediaRecorderInstance as any;
|
|
98
|
+
component.startTime = Date.now() - 600;
|
|
99
|
+
component.stopRecording(new MouseEvent('mouseup'));
|
|
100
|
+
tick(400);
|
|
101
|
+
expect(mediaRecorderInstance.stop).toHaveBeenCalled();
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
it('should preventDefault on touchend', () => {
|
|
105
|
+
const ev = { type: 'touchend', preventDefault: jasmine.createSpy('pd') } as any;
|
|
106
|
+
component.stopRecording(ev);
|
|
107
|
+
expect(ev.preventDefault).toHaveBeenCalled();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('deleteRecording', () => {
|
|
112
|
+
it('should reset state and emit', () => {
|
|
113
|
+
spyOn(component.deleteRecordingEvent, 'emit');
|
|
114
|
+
component.audioUrl = {} as any;
|
|
115
|
+
component.audioBlob = new Blob();
|
|
116
|
+
component.deleteRecording();
|
|
117
|
+
expect(component.audioUrl).toBeNull();
|
|
118
|
+
expect(component.audioBlob).toBeNull();
|
|
119
|
+
expect(component.deleteRecordingEvent.emit).toHaveBeenCalledWith(null);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('sendMessage', () => {
|
|
124
|
+
it('should emit blob and clear url when recording exists', () => {
|
|
125
|
+
spyOn(component.sendRecordingEvent, 'emit');
|
|
126
|
+
const b = new Blob(['a'], { type: 'audio/webm' });
|
|
127
|
+
component.audioBlob = b;
|
|
128
|
+
component.audioUrl = {} as any;
|
|
129
|
+
component.sendMessage();
|
|
130
|
+
expect(component.sendRecordingEvent.emit).toHaveBeenCalledWith(b);
|
|
131
|
+
expect(component.audioUrl).toBeNull();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should no-op when there is no audioUrl', () => {
|
|
135
|
+
spyOn(component.sendRecordingEvent, 'emit');
|
|
136
|
+
component.audioUrl = null;
|
|
137
|
+
component.sendMessage();
|
|
138
|
+
expect(component.sendRecordingEvent.emit).not.toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
23
141
|
});
|
|
@@ -9,6 +9,7 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
|
|
9
9
|
export class ConversationAudioRecorderComponent {
|
|
10
10
|
|
|
11
11
|
@Input() stylesMap: Map<string, string>;
|
|
12
|
+
@Input() translationMap: Map<string, string>;
|
|
12
13
|
@Output() startRecordingEvent = new EventEmitter<void>();
|
|
13
14
|
@Output() deleteRecordingEvent = new EventEmitter<void>();
|
|
14
15
|
@Output() endRecordingEvent = new EventEmitter<Blob | null>();
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
<div class="c21-body-container">
|
|
4
4
|
|
|
5
|
-
<div class="c21-body-content"
|
|
5
|
+
<div class="c21-body-content"
|
|
6
|
+
role="log"
|
|
7
|
+
aria-live="polite"
|
|
8
|
+
aria-relevant="additions text"
|
|
9
|
+
aria-atomic="false"
|
|
10
|
+
[attr.aria-label]="translationMap?.get('CONVERSATION_LOG_LABEL') || 'Conversation messages'">
|
|
6
11
|
|
|
7
12
|
<!-- USER TYPING (WAIT MESSAGE) -->
|
|
8
13
|
<span *ngIf="messages && this.messages.length === 0 && !isTypings">
|
|
@@ -19,21 +24,22 @@
|
|
|
19
24
|
<div #scrollMe id="scroll-me" (scroll)="onScroll($event)">
|
|
20
25
|
|
|
21
26
|
<div id="{{idDivScroll}}" class="c21-contentScroll" > <!-- (resized)="onResized($event)" -->
|
|
22
|
-
<div *ngFor="let message of messages; let first = first; let last = last; let i = index"
|
|
23
|
-
|
|
27
|
+
<div *ngFor="let message of messages; let first = first; let last = last; let i = index" class="rowMsg">
|
|
28
|
+
|
|
24
29
|
<!-- message SENDER:: -->
|
|
25
|
-
|
|
30
|
+
<div role="article" *ngIf="messageType(MESSAGE_TYPE_MINE, message) && !message.isJustRecived" class="msg_container base_sent">
|
|
26
31
|
|
|
27
32
|
<!--backgroundColor non viene ancora usato -->
|
|
28
33
|
<!-- class="messages msg_sent slide-in-right" -->
|
|
29
34
|
<chat-bubble-message class="messages msg_sent"
|
|
30
|
-
[class.no-background]="(isImage(message) || isFrame(message)) && ((message?.text && message?.text.trim() === '') || !message?.text)"
|
|
35
|
+
[class.no-background]="(isImage(message) || isFrame(message)) && ((message?.text && message?.text.trim() === '') || !message?.text)"
|
|
31
36
|
[class.emoticon]="isEmojii(message?.text)"
|
|
32
37
|
[ngStyle]="{'background': stylesMap.get('bubbleSentBackground'), 'color': stylesMap.get('bubbleSentTextColor')}"
|
|
33
38
|
[ngClass]="{'button-in-msg' : message?.metadata && message?.metadata?.button}"
|
|
34
39
|
[message]="message"
|
|
35
40
|
[fontColor]="stylesMap.get('bubbleSentTextColor')"
|
|
36
41
|
[stylesMap]="stylesMap"
|
|
42
|
+
[translationMap]="translationMap"
|
|
37
43
|
(onBeforeMessageRender)="onBeforeMessageRenderFN($event)"
|
|
38
44
|
(onAfterMessageRender)="onAfterMessageRenderFN($event)"
|
|
39
45
|
(onElementRendered)="onElementRenderedFN($event)">
|
|
@@ -47,7 +53,7 @@
|
|
|
47
53
|
</div>
|
|
48
54
|
|
|
49
55
|
<!-- message RECIPIENT:: -->
|
|
50
|
-
<div role="
|
|
56
|
+
<div role="article" *ngIf="messageType(MESSAGE_TYPE_OTHERS, message)" class="msg_container base_receive">
|
|
51
57
|
|
|
52
58
|
<chat-avatar-image *ngIf="!isSameSender(message?.sender, i) && !isStreamAudioActive"
|
|
53
59
|
[ngClass]="{'slide-in-left': false}"
|
|
@@ -60,7 +66,7 @@
|
|
|
60
66
|
<!-- [ngClass]="{'slide-in-left': !isFirstMessage(message?.sender, i)}" -->
|
|
61
67
|
<chat-bubble-message class="messages msg_receive"
|
|
62
68
|
[ngClass]="{'slide-in-left': false}"
|
|
63
|
-
[class.no-background]="(isImage(message) || isFrame(message) || isCarousel(message)) && ((message?.text && message?.text.trim() === '') || !message?.text)"
|
|
69
|
+
[class.no-background]="(isImage(message) || isFrame(message) || isCarousel(message)) && ((message?.text && message?.text.trim() === '') || !message?.text)"
|
|
64
70
|
[class.emoticon]="isEmojii(message?.text)"
|
|
65
71
|
[class.fullSizeMessage]="isStreamAudioActive"
|
|
66
72
|
[style.margin-left]="isSameSender(message?.sender, i) ? 'calc(var(--avatar-width) + 10px)' : null"
|
|
@@ -69,6 +75,8 @@
|
|
|
69
75
|
[message]="message"
|
|
70
76
|
[fontColor]="stylesMap.get('bubbleReceivedTextColor')"
|
|
71
77
|
[stylesMap]="stylesMap"
|
|
78
|
+
[translationMap]="translationMap"
|
|
79
|
+
[streamOnArrival]="false"
|
|
72
80
|
(onBeforeMessageRender)="onBeforeMessageRenderFN($event)"
|
|
73
81
|
(onAfterMessageRender)="onAfterMessageRenderFN($event)"
|
|
74
82
|
(onElementRendered)="onElementRenderedFN($event)">
|
|
@@ -111,6 +119,7 @@
|
|
|
111
119
|
[isConversationArchived]="isConversationArchived"
|
|
112
120
|
[isLastMessage] = "isLastMessage(message?.uid)"
|
|
113
121
|
[stylesMap]="stylesMap"
|
|
122
|
+
[translationMap]="translationMap"
|
|
114
123
|
(onElementRendered)="onElementRenderedFN($event)"
|
|
115
124
|
(onAttachmentButtonClicked)="onAttachmentButtonClickedFN($event)">
|
|
116
125
|
</chat-carousel>
|
|
@@ -149,6 +158,7 @@
|
|
|
149
158
|
<user-typing class="loading thinking-dots"
|
|
150
159
|
[class.fullSize]="isStreamAudioActive"
|
|
151
160
|
[color]="stylesMap?.get('iconColor')"
|
|
161
|
+
[class.fullSize]="isStreamAudioActive"
|
|
152
162
|
[translationMap]="translationMap"
|
|
153
163
|
[idUserTypingNow]="idUserTypingNow"
|
|
154
164
|
[nameUserTypingNow]="nameUserTypingNow">
|
|
@@ -27,9 +27,8 @@
|
|
|
27
27
|
margin: 25px 50px
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
30
|
:host .loading.fullSize ::ng-deep > div.spinner{
|
|
32
|
-
margin:
|
|
31
|
+
margin: 15px 0px !important;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
// ============= CSS c21-body ================= //
|
|
@@ -169,6 +168,12 @@
|
|
|
169
168
|
min-width: 14px;
|
|
170
169
|
border: 0.1px solid #0000000f;
|
|
171
170
|
}
|
|
171
|
+
.msg_sent.json-resources{
|
|
172
|
+
border: 0 !important;
|
|
173
|
+
width: 100%;
|
|
174
|
+
max-width: 652px;
|
|
175
|
+
flex: 1 1 auto;
|
|
176
|
+
}
|
|
172
177
|
.message_innerhtml {
|
|
173
178
|
padding: 8px;
|
|
174
179
|
}
|
|
@@ -247,6 +252,13 @@
|
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
}
|
|
255
|
+
.msg_receive.json-resources{
|
|
256
|
+
min-height: unset;
|
|
257
|
+
padding: 0;
|
|
258
|
+
width: 100%;
|
|
259
|
+
max-width: 652px;
|
|
260
|
+
flex: 1 1 auto;
|
|
261
|
+
}
|
|
250
262
|
|
|
251
263
|
|
|
252
264
|
.message_innerhtml {
|
|
@@ -351,4 +363,4 @@
|
|
|
351
363
|
}
|
|
352
364
|
}
|
|
353
365
|
|
|
354
|
-
// ============= END CSS c21-body ================= //
|
|
366
|
+
// ============= END CSS c21-body ================= //
|