@chat21/chat21-web-widget 5.0.83-rc.1 → 5.0.83-rc.3

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.
Files changed (26) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/deploy_amazon_beta.sh +11 -4
  3. package/deploy_amazon_prod.sh +11 -4
  4. package/package.json +1 -1
  5. package/src/app/app.module.ts +7 -6
  6. package/src/app/component/conversation-detail/conversation/conversation.component.html +7 -0
  7. package/src/app/component/conversation-detail/conversation/conversation.component.ts +15 -5
  8. package/src/app/component/{audio-recorder/audio-recorder.component.html → conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html} +9 -4
  9. package/src/app/component/{audio-recorder/audio-recorder.component.scss → conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.scss} +16 -8
  10. package/src/app/component/{audio-recorder/audio-recorder.component.spec.ts → conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.spec.ts} +5 -5
  11. package/src/app/component/{audio-recorder/audio-recorder.component.ts → conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.ts} +10 -9
  12. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +5 -4
  13. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +7 -3
  14. package/src/app/component/message/audio-track/audio-track.component.html +15 -10
  15. package/src/app/component/message/audio-track/audio-track.component.scss +95 -83
  16. package/src/app/component/message/audio-track/audio-track.component.ts +7 -2
  17. package/src/app/component/message/bubble-message/bubble-message.component.html +5 -2
  18. package/src/app/component/message/bubble-message/bubble-message.component.scss +4 -0
  19. package/src/app/modals/confirm-close/confirm-close.component.html +6 -0
  20. package/src/app/modals/confirm-close/confirm-close.component.scss +0 -0
  21. package/src/app/{component/message/audio/audio.component.spec.ts → modals/confirm-close/confirm-close.component.spec.ts} +6 -6
  22. package/src/app/modals/confirm-close/confirm-close.component.ts +24 -0
  23. package/src/app/utils/BrandResources.ts +8 -0
  24. package/src/app/component/message/audio/audio.component.html +0 -20
  25. package/src/app/component/message/audio/audio.component.scss +0 -122
  26. package/src/app/component/message/audio/audio.component.ts +0 -122
package/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@
6
6
  ### **Copyrigth**:
7
7
  *Tiledesk SRL*
8
8
 
9
+ # 5.0.83-rc.3
10
+ - **added**: send '/start' info message on restart header menu option
11
+ - **bug-fixed**: close header menu option not send the last conversation id to close
12
+
13
+ # 5.0.83-rc.2
14
+ - **changed**: ui improvements on audio elements
15
+
9
16
  # 5.0.83-rc.1
10
17
  - **added**: ability to send and receive voice message into the conversation
11
18
 
@@ -2,7 +2,12 @@
2
2
  version=`node -e 'console.log(require("./package.json").version)'`
3
3
  echo "version $version"
4
4
 
5
- ng build --configuration="pre" --aot=true --base-href --output-hashing none --build-optimizer=true
5
+ ng build --configuration="pre" --aot=true --base-href --build-optimizer=true
6
+
7
+ ### SET HASHING : START ###
8
+ cp ./src/launch_template.js ./dist/launch.js
9
+ node ./src/build_launch.js
10
+ ### SET HASHING : END ###
6
11
 
7
12
  # ########## --->>>> NATIVE-MQTT folder START <<<<<------ ########## #
8
13
 
@@ -23,11 +28,13 @@ ng build --configuration="pre" --aot=true --base-href --output-hashing none --bu
23
28
 
24
29
  # ########## --->>>> FIREBASE folder START <<<<<------ ########## #
25
30
  cd dist
26
- aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300
27
- aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control max-age=300
31
+ aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300 --exclude='launch.js' #7days
32
+ aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
33
+ aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control max-age=300 --exclude='launch.js' #7days
34
+ aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
28
35
  cd ..
29
36
 
30
- #aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*"
37
+ aws cloudfront create-invalidation --distribution-id E2V5O0YPR61V8P --paths "/*"
31
38
  # echo new version deployed $NEW_VER/$NEW_BUILD/ on s3://tiledesk-widget-pre/v2
32
39
  echo new version deployed $version/ on s3://tiledesk-widget-pre/v5 and s3://tiledesk-widget-pre/v5/$version/
33
40
  echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget-pre/v5/index.html
@@ -3,7 +3,13 @@ version=`node -e 'console.log(require("./package.json").version)'`
3
3
  echo "version $version"
4
4
 
5
5
  # --build-optimizer=false if localstorage is disabled (webview) appears https://github.com/firebase/angularfire/issues/970
6
- ng build --configuration="prod" --aot=true --base-href --output-hashing none --build-optimizer=true --vendor-chunk=true
6
+ ng build --configuration="prod" --aot=true --build-optimizer=true --vendor-chunk=true
7
+ ##--base-href='./v5/' --output-hashing none
8
+
9
+ ### SET HASHING : START ###
10
+ cp ./src/launch_template.js ./dist/launch.js
11
+ node ./src/build_launch.js
12
+ ### SET HASHING : END ###
7
13
 
8
14
  #### FIREBASE #####
9
15
  # cd dist
@@ -12,12 +18,13 @@ ng build --configuration="prod" --aot=true --base-href --output-hashing none --b
12
18
  # aws s3 sync . s3://tiledesk-widget/v5/ --cache-control max-age=300
13
19
  # cd ..
14
20
 
15
-
16
21
  # #### MQTT #####
17
22
  cd dist
18
23
  # aws s3 sync . s3://tiledesk-widget/v5/latest/
19
- aws s3 sync . s3://tiledesk-widget/v6/$version/ --cache-control max-age=300
20
- aws s3 sync . s3://tiledesk-widget/v6/ --cache-control max-age=300
24
+ aws s3 sync . s3://tiledesk-widget/v6/$version/ --cache-control max-age=86400 --exclude='launch.js' #8days
25
+ aws s3 sync . s3://tiledesk-widget/v6/$version/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
26
+ aws s3 sync . s3://tiledesk-widget/v6/ --cache-control max-age=86400 --exclude='launch.js' #8days
27
+ aws s3 sync . s3://tiledesk-widget/v6/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
21
28
  cd ..
22
29
 
23
30
  aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-web-widget",
3
3
  "author": "Tiledesk SRL",
4
- "version": "5.0.83-rc.1",
4
+ "version": "5.0.83-rc.3",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -15,6 +15,7 @@ import { ConversationContentComponent } from './component/conversation-detail/co
15
15
  import { ConversationFooterComponent } from './component/conversation-detail/conversation-footer/conversation-footer.component';
16
16
  import { ConversationInternalFrameComponent } from './component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component';
17
17
  import { ConversationPreviewComponent } from './component/conversation-detail/conversation-preview/conversation-preview.component';
18
+ import { ConversationAudioRecorderComponent } from './component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component';
18
19
  /** CONVERSATION-DETAIL COMPONENTS */
19
20
  import { BubbleMessageComponent } from './component/message/bubble-message/bubble-message.component';
20
21
  import { AvatarComponent } from './component/message/avatar/avatar.component';
@@ -23,7 +24,7 @@ import { ImageComponent } from './component/message/image/image.component';
23
24
  import { InfoMessageComponent } from './component/message/info-message/info-message.component';
24
25
  import { HtmlComponent } from './component/message/html/html.component';
25
26
  import { FrameComponent } from './component/message/frame/frame.component';
26
- import { AudioComponent } from './component/message/audio/audio.component';
27
+ import { AudioTrackComponent } from './component/message/audio-track/audio-track.component';
27
28
  import { UserTypingComponent } from './../chat21-core/utils/user-typing/user-typing.component';
28
29
  /** MESSAGE ATTACHMENTS COMPONENTS */
29
30
  import { MessageAttachmentComponent } from './component/message-attachment/message-attachment.component';
@@ -134,8 +135,8 @@ import { ScriptService } from 'src/chat21-core/providers/scripts/script.service'
134
135
  import { CarouselComponent } from './component/message/carousel/carousel.component';
135
136
  import { BrandService } from './providers/brand.service';
136
137
  import { NetworkOfflineComponent } from './component/network-offline/network-offline.component';
137
- import { AudioRecorderComponent } from './component/audio-recorder/audio-recorder.component';
138
- import { AudioTrackComponent } from './component/message/audio-track/audio-track.component';
138
+ import { ConfirmCloseComponent } from './modals/confirm-close/confirm-close.component';
139
+
139
140
 
140
141
 
141
142
 
@@ -277,6 +278,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
277
278
  ConversationFooterComponent,
278
279
  ConversationPreviewComponent,
279
280
  ConversationInternalFrameComponent,
281
+ ConversationAudioRecorderComponent,
280
282
  BubbleMessageComponent,
281
283
  AvatarComponent,
282
284
  FrameComponent,
@@ -288,6 +290,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
288
290
  ActionButtonComponent,
289
291
  LinkButtonComponent,
290
292
  TextButtonComponent,
293
+ AudioTrackComponent,
291
294
  UserTypingComponent,
292
295
  /**DIRECTIVES */
293
296
  HtmlEntitiesEncodePipe,
@@ -296,11 +299,9 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
296
299
  SafeHtmlPipe,
297
300
  LikeUnlikeComponent,
298
301
  TooltipDirective,
299
- AudioComponent,
300
302
  CarouselComponent,
301
303
  NetworkOfflineComponent,
302
- AudioRecorderComponent,
303
- AudioTrackComponent
304
+ ConfirmCloseComponent
304
305
  ],
305
306
  imports: [
306
307
  BrowserModule,
@@ -90,6 +90,13 @@
90
90
  (onCloseModalPreview)="onCloseModalPreview()">
91
91
  </chat-conversation-attachment-preview>
92
92
 
93
+
94
+ <dialog #mydialog>
95
+ <chat-confirm-close>
96
+
97
+ </chat-confirm-close>
98
+ </dialog>
99
+
93
100
  <!-- FOOTER -->
94
101
  <!-- [class.maximize-width]="(g?.singleConversation && hideTextAreaContent) || (isConversationArchived && !g?.allowReopen)" -->
95
102
  <div id="chat21-footer">
@@ -50,6 +50,8 @@ import { ConversationContentComponent } from '../conversation-content/conversati
50
50
  })
51
51
  export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
52
52
  @ViewChild('afConversationComponent') private afConversationComponent: ElementRef; // l'ID del div da scrollare
53
+ @ViewChild('mydialog') mydialog: ElementRef;
54
+
53
55
  // @HostListener('window:resize', ['$event'])
54
56
  // ========= begin:: Input/Output values
55
57
  // @Input() elRoot: ElementRef;
@@ -978,19 +980,27 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
978
980
  }
979
981
  /** CALLED BY: conv-header component */
980
982
  onCloseChat(){
981
- this.logger.debug('[CONV-COMP] close chat with uid ', this.conversation.uid)
982
- this.tiledeskRequestService.closeSupportGroup(this.conversation.uid).then(data => {
983
+ // this.mydialog.nativeElement.showModal()
984
+ this.logger.debug('[CONV-COMP] close chat with uid ', this.conversation.uid, this.conversationId)
985
+ this.tiledeskRequestService.closeSupportGroup(this.conversationId).then(data => {
983
986
  if(data === 'closed'){
984
987
  this.isMenuShow = false
985
- this.logger.debug('[CONV-COMP] chat closed successfully with uid ', this.conversation.uid)
988
+ this.logger.debug('[CONV-COMP] chat closed successfully with uid ', this.conversationId)
986
989
  }
987
990
  }).catch(error => {
988
- this.logger.error('[CONV-COMP] ERROR while closing chat with id: ', this.conversation.uid, error)
991
+ this.logger.error('[CONV-COMP] ERROR while closing chat with id: ', this.conversationId, error)
989
992
  })
990
993
  }
991
994
  /** CALLED BY: conv-header component */
992
995
  onRestartChat(){
993
- this.hideTextAreaContent = true
996
+ //restart SAME conversation calling /start againg
997
+ let attributes = {
998
+ subtype: 'info',
999
+ ... this.g.attributes
1000
+ }
1001
+ this.conversationFooter.sendMessage('/start', TYPE_MSG_TEXT, null, attributes)
1002
+
1003
+ // this.hideTextAreaContent = true
994
1004
  }
995
1005
  /** CALLED BY: conv-header component */
996
1006
  onWidgetHeightChange(mode){
@@ -1,15 +1,20 @@
1
1
  <div class="audio-recorder">
2
2
  <button *ngIf="audioUrl" (click)="deleteRecording()">
3
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><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"/></svg>
3
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><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"/></svg>
4
4
  <!-- <i class="material-icons">delete_outline</i> -->
5
5
  </button>
6
6
 
7
7
  <chat-audio-track *ngIf="audioBlob && audioUrl"
8
- [audioBlob] = "audioBlob"
9
- ></chat-audio-track>
8
+ [audioBlob] = "audioBlob"
9
+ [color]="stylesMap.get('themeColor')"
10
+ [fontSize]="stylesMap.get('fontSize')"
11
+ [stylesMap]="stylesMap">
12
+ </chat-audio-track>
10
13
 
11
14
  <button *ngIf="!audioUrl" class="mic-button" (mousedown)="startRecording()" (mouseup)="stopRecording()">
12
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><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"/></svg>
15
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
16
+ <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"/>
17
+ </svg>
13
18
  </button>
14
19
  <!-- <button *ngIf="isRecording" (click)="stopRecording()"><i class="material-icons">pause_circle_outline</i></button> -->
15
20
 
@@ -13,13 +13,20 @@
13
13
  margin: 0px;
14
14
  display: inline-flex;
15
15
  align-items: center;
16
+ justify-content: center;
16
17
  height: 100%;
18
+ width: 100%;
17
19
  float: left;
20
+ gap: 10px
18
21
  }
19
22
 
20
23
  chat-audio-track {
21
- margin-left: 10px;
22
- margin-right: 10px;
24
+ display: flex;
25
+ width: 70%;
26
+ margin: 8px 0;
27
+ pointer-events: auto;
28
+ border-radius: var(--chat-footer-border-radius);
29
+ background-color: var(--chat-footer-background-color);
23
30
  }
24
31
 
25
32
  button {
@@ -30,6 +37,7 @@ button {
30
37
  background-color: transparent;
31
38
  color: var(--icon-fill-color);
32
39
  fill: var(--icon-fill-color);
40
+ height: var(--chat-footer-height);
33
41
  }
34
42
 
35
43
  .mic-button {
@@ -57,9 +65,9 @@ button {
57
65
  position: absolute;
58
66
  top: auto;
59
67
  left: auto;
60
- width: 40px;
61
- height: 40px;
62
- background-color: rgba(82, 160, 252, 1);
68
+ width: 35px;
69
+ height: 35px;
70
+ background-color: var(--icon-fill-color);
63
71
  border-radius: 50%;
64
72
  transform: scale(0);
65
73
  transition: transform 0.3s ease;
@@ -68,7 +76,7 @@ button {
68
76
  }
69
77
 
70
78
  .mic-button:active::before {
71
- transform: scale(0.7);
79
+ transform: scale(0.5);
72
80
  animation: pulse 1s infinite ease-in-out;
73
81
  }
74
82
 
@@ -81,7 +89,7 @@ button {
81
89
 
82
90
  @keyframes pulse {
83
91
  0% {
84
- transform: scale(1.2);
92
+ transform: scale(1);
85
93
  opacity: 1;
86
94
  }
87
95
  50% {
@@ -89,7 +97,7 @@ button {
89
97
  opacity: 0.7;
90
98
  }
91
99
  100% {
92
- transform: scale(1.2);
100
+ transform: scale(1);
93
101
  opacity: 1;
94
102
  }
95
103
  }
@@ -1,18 +1,18 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { AudioRecorderComponent } from './audio-recorder.component';
3
+ import { ConversationAudioRecorderComponent } from './conversation-audio-recorder.component';
4
4
 
5
5
  describe('AudioRecorderComponent', () => {
6
- let component: AudioRecorderComponent;
7
- let fixture: ComponentFixture<AudioRecorderComponent>;
6
+ let component: ConversationAudioRecorderComponent;
7
+ let fixture: ComponentFixture<ConversationAudioRecorderComponent>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- declarations: [ AudioRecorderComponent ]
11
+ declarations: [ ConversationAudioRecorderComponent ]
12
12
  })
13
13
  .compileComponents();
14
14
 
15
- fixture = TestBed.createComponent(AudioRecorderComponent);
15
+ fixture = TestBed.createComponent(ConversationAudioRecorderComponent);
16
16
  component = fixture.componentInstance;
17
17
  fixture.detectChanges();
18
18
  });
@@ -1,12 +1,18 @@
1
- import { Component, EventEmitter, Output } from '@angular/core';
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
2
  import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
3
3
 
4
4
  @Component({
5
5
  selector: 'chat-audio-recorder',
6
- templateUrl: './audio-recorder.component.html',
7
- styleUrls: ['./audio-recorder.component.scss']
6
+ templateUrl: './conversation-audio-recorder.component.html',
7
+ styleUrls: ['./conversation-audio-recorder.component.scss']
8
8
  })
9
- export class AudioRecorderComponent {
9
+ export class ConversationAudioRecorderComponent {
10
+
11
+ @Input() stylesMap: Map<string, string>;
12
+ @Output() startRecordingEvent = new EventEmitter<void>();
13
+ @Output() deleteRecordingEvent = new EventEmitter<void>();
14
+ @Output() endRecordingEvent = new EventEmitter<Blob | null>();
15
+ @Output() sendRecordingEvent = new EventEmitter<Blob | null>();
10
16
 
11
17
  mediaRecorder: MediaRecorder | null = null;
12
18
  audioChunks: Blob[] = [];
@@ -18,11 +24,6 @@ export class AudioRecorderComponent {
18
24
  isPlaying: boolean = false;
19
25
  startTime: number;
20
26
 
21
-
22
- @Output() startRecordingEvent = new EventEmitter<void>();
23
- @Output() deleteRecordingEvent = new EventEmitter<void>();
24
- @Output() endRecordingEvent = new EventEmitter<Blob | null>();
25
- @Output() sendRecordingEvent = new EventEmitter<Blob | null>();
26
27
 
27
28
 
28
29
  constructor(private sanitizer: DomSanitizer) {}
@@ -78,10 +78,11 @@
78
78
  <!-- ICON REC -->
79
79
  <div *ngIf="!textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
80
80
  <chat-audio-recorder
81
- (startRecordingEvent)="onStartRecording()"
82
- (deleteRecordingEvent)="onDeleteRecording()"
83
- (endRecordingEvent)="onEndRecording($event)"
84
- (sendRecordingEvent)="onSendRecording($event)">
81
+ (startRecordingEvent)="onStartRecording()"
82
+ (deleteRecordingEvent)="onDeleteRecording()"
83
+ (endRecordingEvent)="onEndRecording($event)"
84
+ (sendRecordingEvent)="onSendRecording($event)"
85
+ [stylesMap]="stylesMap">
85
86
  </chat-audio-recorder>
86
87
  </div>
87
88
  </div>
@@ -196,8 +196,6 @@ textarea:active{
196
196
 
197
197
  #chat21-button-rec {
198
198
  display: flex;
199
- align-self: flex-end;
200
- margin: 0 8px;
201
199
  width: 34px;
202
200
  text-align: center;
203
201
  justify-content: center;
@@ -205,6 +203,12 @@ textarea:active{
205
203
  &.active{
206
204
  width: 100%;
207
205
  }
206
+ chat-audio-recorder {
207
+ width: 100%;
208
+ display: flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ }
208
212
  }
209
213
 
210
214
  #chat21-file{
@@ -352,4 +356,4 @@ textarea:active{
352
356
  // left: 10px;
353
357
  border: none;
354
358
  margin: -2px -2px 0px;
355
- }
359
+ }
@@ -2,26 +2,31 @@
2
2
  <!-- <audio *ngIf="metadata" controls>
3
3
  <source [src]="metadata.src" type="audio/mpeg">
4
4
  </audio> *ngIf="!metadata"-->
5
- <span style = "position: relative; display: inline-block;">
6
- <div class="audio-player-custom">
7
- <audio #audioElement [src]="audioUrl"></audio>
8
- <canvas #canvasElement class="waveformCanvas"></canvas>
9
- </div>
10
-
5
+ <div class="audio-container">
6
+
11
7
  <div class="audio-track">
12
8
  <button *ngIf="!isPlaying" class="play-pause" (click)="playPauseAudio()">
13
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M320-200v-560l440 280-440 280Z"/></svg>
9
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
10
+ <path d="M320-200v-560l440 280-440 280Z"/>
11
+ </svg>
14
12
  <!-- <i class="material-icons">play_arrow</i> -->
15
13
  </button>
16
14
  <button *ngIf="isPlaying" class="play-pause" (click)="playPauseAudio()">
17
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/></svg>
15
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
16
+ <path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/>
17
+ </svg>
18
18
  <!-- <i class="material-icons">pause</i> -->
19
19
  </button>
20
- <div class="duration">
20
+ <div class="duration" [style.color]="color" [style.font-size]="fontSize" >
21
21
  <span *ngIf="!isPlaying">{{ audioDuration ? formatTime(audioDuration) : '00:00' }}</span>
22
22
  <span *ngIf="isPlaying">{{ formatTime(currentTime) }}</span>
23
23
  </div>
24
24
 
25
25
  </div>
26
26
 
27
- </span>
27
+ <div class="audio-player-custom">
28
+ <audio #audioElement [src]="audioUrl"></audio>
29
+ <canvas #canvasElement class="waveformCanvas"></canvas>
30
+ </div>
31
+
32
+ </div>
@@ -1,95 +1,107 @@
1
- audio {
2
- width: 272px;
3
- height: 30px;
4
- margin: 0;
5
- padding: 10px;
6
- }
1
+
2
+ :host {
3
+ --backgroundColor: #{var(--blue)};
4
+ --textColor: #{var(--bck-msg-sent)};
5
+ --hoverBackgroundColor: #{var(--bck-msg-sent)};
6
+ --hoverTextColor: #{var(--blue)};
7
+ --max-width: #{var(--button-in-msg-max-width)};
8
+ }
7
9
 
8
- .audio-recorder {
9
- text-align: center;
10
- margin: 0px;
11
- display: inline-flex;
12
- align-items: center;
13
- height: 100%;
14
- float: left;
15
- }
10
+ .audio-container{
11
+ position: relative;
12
+ display: inline-flex;
13
+ width: 100%;
14
+ padding: 0px 12px;
15
+ margin: 6px 0px;
16
+ }
16
17
 
17
- button {
18
- margin: 0px;
19
- padding: 0px;
20
- font-size: 16px;
21
- border: none;
22
- background-color: transparent;
23
- color: var(--icon-fill-color);
24
- fill: var(--icon-fill-color);
25
- }
18
+ audio {
19
+ width: 272px;
20
+ height: 30px;
21
+ margin: 0;
22
+ padding: 10px;
23
+ }
26
24
 
27
- .waveformCanvas {
28
- width: 100%;
29
- height: 28px;
30
- z-index: 1;
31
- padding: 0px;
32
- margin: 0%;
33
- }
25
+ .audio-recorder {
26
+ text-align: center;
27
+ margin: 0px;
28
+ display: inline-flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ height: 100%;
32
+ width: 100%;
33
+ float: left;
34
+ }
34
35
 
35
- .audio-track {
36
- width: 247px;//272px;
36
+ button {
37
+ margin: 0px;
38
+ padding: 0px;
39
+ font-size: 16px;
40
+ border: none;
41
+ background-color: transparent;
42
+ color: var(--icon-fill-color);
43
+ fill: var(--icon-fill-color);
44
+ }
45
+
46
+ .waveformCanvas {
47
+ width: 100%;
48
+ height: 28px;
49
+ z-index: 1;
50
+ padding: 0px;
51
+ margin: 0%;
52
+ }
53
+
54
+ .audio-track {
55
+ // width: 247px;//272px;
56
+ // height: 30px;
57
+ position: relative;
58
+ display: flex;
59
+ align-items: center;
60
+ // margin: 0 13px;
61
+ margin: 0px;
62
+ .play-pause {
63
+ font-size: 20px;
64
+ width: 30px;
65
+ background-color: transparent;
66
+ border-radius: 50%;
37
67
  height: 30px;
38
- background-color: #f0f2f7;
39
- border-radius: 15px;
40
- position: relative;
41
- display: flex;
42
- align-items: center;
43
- // margin: 0 13px;
44
- border: 1px solid #f0f0f0;
45
68
  margin: 0px;
46
- .play-pause {
47
- font-size: 20px;
48
- width: 30px;
49
- background-color: transparent;
50
- border-radius: 50%;
51
- height: 30px;
52
- margin: 0px;
53
- transition: background-color 0.5s ease;
54
- svg {
55
- fill: rgb(82, 160, 252);
56
- }
57
- }
58
- .play-pause:hover {
59
- // background-color: #ddd;
60
- // background-color: rgb(82, 160, 252);
61
- background-color: #fff;
62
- svg{
63
- //fill:#fff;
64
- fill: rgb(82, 160, 252);
65
- }
66
- }
67
- .duration {
68
- font-size: 12px;
69
- padding: 0 3px;
70
- color: #5f6368;
69
+ transition: background-color 0.5s ease;
70
+
71
+ }
72
+ .play-pause:hover {
73
+ // background-color: #ddd;
74
+ // background-color: rgb(82, 160, 252);
75
+ background-color: #fff;
76
+ svg{
77
+ //fill:#fff;
78
+ fill: rgb(82, 160, 252);
71
79
  }
72
80
  }
81
+ .duration {
82
+ padding: 0 3px;
83
+ }
84
+ }
73
85
 
74
- .audio-player-custom {
75
- // width: 200px;
76
- // height: 32px;
77
- // margin-left: 75px;
78
- // position: absolute;
79
- // overflow: hidden;
80
- // z-index: 1;
81
- // display: flex;
82
- // align-items: center;
86
+ .audio-player-custom {
87
+ // width: 200px;
88
+ // height: 32px;
89
+ // margin-left: 75px;
90
+ // position: absolute;
91
+ // overflow: hidden;
92
+ // z-index: 1;
93
+ // display: flex;
94
+ // align-items: center;
83
95
 
84
- width: calc(100% - 75px);
85
- height: 32px;
86
- margin-left: 65px;
87
- position: absolute;
88
- overflow: hidden;
89
- z-index: 1;
90
- display: flex;
91
- align-items: center;
92
- }
96
+ // width: calc(100% - 75px);
97
+ // height: 32px;
98
+ // margin-left: 65px;
99
+ // position: absolute;
100
+ overflow: hidden;
101
+ z-index: 1;
102
+ display: flex;
103
+ align-items: center;
104
+ width: 100%;
105
+ }
93
106
 
94
107
 
95
-
@@ -1,5 +1,6 @@
1
1
  import { Component, ElementRef, AfterViewInit, Input, ViewChild } from '@angular/core';
2
2
  import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
3
+ import { convertColorToRGBA } from 'src/chat21-core/utils/utils';
3
4
 
4
5
  @Component({
5
6
  selector: 'chat-audio-track',
@@ -13,6 +14,9 @@ export class AudioTrackComponent implements AfterViewInit {
13
14
 
14
15
  @Input() audioBlob: Blob | null = null;
15
16
  @Input() metadata: any | null = null;
17
+ @Input() color: string;
18
+ @Input() fontSize: string;
19
+ @Input() stylesMap: Map<string, string>;
16
20
 
17
21
  audioUrl: SafeUrl | null = null;
18
22
  rawAudioUrl: string | null = null;
@@ -25,6 +29,7 @@ export class AudioTrackComponent implements AfterViewInit {
25
29
  constructor(private sanitizer: DomSanitizer) {}
26
30
 
27
31
  ngAfterViewInit() {
32
+ console.log('stylesssss', this.stylesMap)
28
33
  if (this.audioBlob) {
29
34
  this.rawAudioUrl = URL.createObjectURL(this.audioBlob);
30
35
  this.audioUrl = this.sanitizer.bypassSecurityTrustUrl(this.rawAudioUrl);
@@ -80,9 +85,9 @@ export class AudioTrackComponent implements AfterViewInit {
80
85
  const x = i * (barWidth + padding * 2) + padding;
81
86
 
82
87
  if (i / samples < playedPercent) {
83
- canvasCtx.fillStyle = 'rgb(82, 160, 252)';
88
+ canvasCtx.fillStyle = this.color;
84
89
  } else {
85
- canvasCtx.fillStyle = 'rgba(82, 160, 252, 0.5)';
90
+ canvasCtx.fillStyle = convertColorToRGBA(this.color, 50);;
86
91
  }
87
92
  canvasCtx.fillRect(x, height / 2 - barHeight, barWidth, barHeight);
88
93
  canvasCtx.fillRect(x, height / 2, barWidth, barHeight);
@@ -59,8 +59,11 @@
59
59
  </chat-audio> -->
60
60
 
61
61
  <chat-audio-track *ngIf="isAudio(message)"
62
- [metadata]="message.metadata"
63
- ></chat-audio-track>
62
+ [metadata]="message.metadata"
63
+ [color]="fontColor"
64
+ [fontSize]="fontSize"
65
+ [stylesMap]="stylesMap">
66
+ </chat-audio-track>
64
67
 
65
68
 
66
69
  <!-- <chat-frame *ngIf="message.metadata && message.metadata.type && message.metadata.type.includes('video')"
@@ -29,4 +29,8 @@
29
29
  height: auto;
30
30
  object-fit: cover;
31
31
  }
32
+
33
+ chat-audio-track {
34
+ display: flex;
35
+ }
32
36
  }
@@ -0,0 +1,6 @@
1
+ <div class="modal-container">
2
+ CLOSE CONVERSATION MODAL
3
+ </div>
4
+
5
+
6
+
@@ -1,18 +1,18 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { AudioComponent } from './audio.component';
3
+ import { ConfirmCloseComponent } from './confirm-close.component';
4
4
 
5
- describe('AudioComponent', () => {
6
- let component: AudioComponent;
7
- let fixture: ComponentFixture<AudioComponent>;
5
+ describe('ConfirmCloseComponent', () => {
6
+ let component: ConfirmCloseComponent;
7
+ let fixture: ComponentFixture<ConfirmCloseComponent>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- declarations: [ AudioComponent ]
11
+ declarations: [ ConfirmCloseComponent ]
12
12
  })
13
13
  .compileComponents();
14
14
 
15
- fixture = TestBed.createComponent(AudioComponent);
15
+ fixture = TestBed.createComponent(ConfirmCloseComponent);
16
16
  component = fixture.componentInstance;
17
17
  fixture.detectChanges();
18
18
  });
@@ -0,0 +1,24 @@
1
+ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'chat-confirm-close',
5
+ templateUrl: './confirm-close.component.html',
6
+ styleUrls: ['./confirm-close.component.scss']
7
+ })
8
+ export class ConfirmCloseComponent implements OnInit{
9
+
10
+ @ViewChild('mydialog') mydialog: ElementRef;
11
+
12
+ constructor() { }
13
+
14
+ ngOnInit(): void {
15
+ // console.log('[CONFIRM CLOSE MODAL] onInit-->', this.dialog);
16
+ // this.dialog.showModal();
17
+ }
18
+
19
+ ngAfterViewInit(){
20
+ // console.log('[CONFIRM CLOSE MODAL] ngAfterViewInit-->', this.mydialog);
21
+ // this.mydialog.nativeElement.showModal()
22
+ }
23
+
24
+ }
@@ -25,6 +25,14 @@ export class BrandResources {
25
25
  // var icon = document.querySelector("link[rel~='icon']") as HTMLElement;
26
26
  // icon.setAttribute('href', this.brand['FAVICON_URL'])
27
27
 
28
+ /** META sharing ELEMENTS */
29
+ if(this.brand['META_SHARE_INFO'] && this.brand['META_SHARE_INFO'].length > 0){
30
+ Object.keys(this.brand['META_SHARE_INFO']).forEach(key => {
31
+ var meta = document.querySelector("meta[property^='og:"+key.toLowerCase()+"']") as HTMLElement;
32
+ meta.setAttribute('content', this.brand['META_SHARE_INFO'][key])
33
+ })
34
+ }
35
+
28
36
  /** CSS */
29
37
  document.documentElement.style.setProperty('--base-brand-color', this.brand['BRAND_PRIMARY_COLOR']);
30
38
 
@@ -1,20 +0,0 @@
1
-
2
-
3
- <div id="audio_container" #audio_container>
4
-
5
- <audio aria-label="traccia audio" #audio_msg controls controlsList="nodownload" id="audio_msg" (pause)="pauseAudioMsg($event)" (play)="playAudioMsg($event)" (timeupdate)="updateTimeAudioMsg($event)">
6
- <source [src]="metadata?.src" [type]="metadata?.type">
7
- <!-- {{metadata?.src}} -->
8
- <!-- controlsList="nodownload" -->
9
- </audio>
10
-
11
- <!-- <button id="play-icon" (click)="onPlayPause('play')" *ngIf="status === 'play'">
12
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 8.64L15.27 12 10 15.36V8.64M8 5v14l11-7L8 5z"/></svg>
13
- </button>
14
- <button id="pause-icon" (click)="onPlayPause('pause')" *ngIf="status === 'pause'">
15
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
16
- </button>
17
- <div id="duration" #duration>0:00</div>
18
- <input type="range" id="seek-slider" max="100" value="0"> -->
19
- </div>
20
-
@@ -1,122 +0,0 @@
1
- #audio_container{
2
- display: flex;
3
- }
4
-
5
- #play-icon,
6
- #pause-icon {
7
- margin: 20px 2.5% 10px 2.5%;
8
- }
9
-
10
- .time {
11
- display: inline-block;
12
- width: 37px;
13
- text-align: center;
14
- font-size: 20px;
15
- margin: 28.5px 0 18.5px 0;
16
- float: left;
17
- }
18
- output {
19
- display: inline-block;
20
- width: 32px;
21
- text-align: center;
22
- font-size: 20px;
23
- margin: 10px 2.5% 0 5%;
24
- float: left;
25
- clear: left;
26
- }
27
-
28
- input[type="range"] {
29
- position: relative;
30
- -webkit-appearance: none;
31
- width: 48%;
32
- margin: 0;
33
- padding: 0;
34
- height: 19px;
35
- margin: 30px 2.5% 20px 2.5%;
36
- float: left;
37
- outline: none;
38
- }
39
- input[type="range"]::-webkit-slider-runnable-track {
40
- width: 100%;
41
- height: 3px;
42
- cursor: pointer;
43
- background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
44
- }
45
- input[type="range"]::before {
46
- position: absolute;
47
- content: "";
48
- top: 8px;
49
- left: 0;
50
- width: var(--seek-before-width);
51
- height: 3px;
52
- background-color: #007db5;
53
- cursor: pointer;
54
- }
55
- input[type="range"]::-webkit-slider-thumb {
56
- position: relative;
57
- -webkit-appearance: none;
58
- box-sizing: content-box;
59
- border: 1px solid #007db5;
60
- height: 15px;
61
- width: 15px;
62
- border-radius: 50%;
63
- background-color: #fff;
64
- cursor: pointer;
65
- margin: -7px 0 0 0;
66
- }
67
- input[type="range"]:active::-webkit-slider-thumb {
68
- transform: scale(1.2);
69
- background: #007db5;
70
- }
71
- input[type="range"]::-moz-range-track {
72
- width: 100%;
73
- height: 3px;
74
- cursor: pointer;
75
- background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
76
- }
77
- input[type="range"]::-moz-range-progress {
78
- background-color: #007db5;
79
- }
80
- input[type="range"]::-moz-focus-outer {
81
- border: 0;
82
- }
83
- input[type="range"]::-moz-range-thumb {
84
- box-sizing: content-box;
85
- border: 1px solid #007db5;
86
- height: 15px;
87
- width: 15px;
88
- border-radius: 50%;
89
- background-color: #fff;
90
- cursor: pointer;
91
- }
92
- input[type="range"]:active::-moz-range-thumb {
93
- transform: scale(1.2);
94
- background: #007db5;
95
- }
96
- input[type="range"]::-ms-track {
97
- width: 100%;
98
- height: 3px;
99
- cursor: pointer;
100
- background: transparent;
101
- border: solid transparent;
102
- color: transparent;
103
- }
104
- input[type="range"]::-ms-fill-lower {
105
- background-color: #007db5;
106
- }
107
- input[type="range"]::-ms-fill-upper {
108
- background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
109
- }
110
- input[type="range"]::-ms-thumb {
111
- box-sizing: content-box;
112
- border: 1px solid #007db5;
113
- height: 15px;
114
- width: 15px;
115
- border-radius: 50%;
116
- background-color: #fff;
117
- cursor: pointer;
118
- }
119
- input[type="range"]:active::-ms-thumb {
120
- transform: scale(1.2);
121
- background: #007db5;
122
- }
@@ -1,122 +0,0 @@
1
- import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
2
- // import lottieWeb from 'https://cdn.skypack.dev/lottie-web';
3
-
4
- @Component({
5
- selector: 'chat-audio',
6
- templateUrl: './audio.component.html',
7
- styleUrls: ['./audio.component.scss']
8
- })
9
- export class AudioComponent implements OnInit {
10
-
11
- @Input() metadata: any;
12
- @Output() onElementRendered = new EventEmitter<{element: string, status: boolean}>();
13
-
14
- uidAudioPlayng: string = ''
15
- divPlay: HTMLAudioElement
16
- playState: HTMLElement
17
- status: 'play' | 'pause' = 'play'
18
-
19
- constructor(private elementRef: ElementRef) { }
20
-
21
- ngOnInit() {
22
- // this.divPlay = this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#audio_msg')
23
- // this.playState= this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#duration')
24
- }
25
-
26
- onPlayPause(status: string){
27
- // const divPlay = (<HTMLAudioElement>document.getElementById('audio_msg'));
28
- if(status === 'play') {
29
- this.divPlay.play();
30
- this.status = 'pause'
31
- } else {
32
- this.divPlay.pause();
33
- this.status = 'play'
34
- }
35
- }
36
-
37
- pauseAudioMsg(e) {
38
- try {
39
- // stop all audio
40
- if (this.uidAudioPlayng) {
41
- const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
42
- divPlay.pause();
43
- // console.log('> pausa: ', divPlay);
44
- }
45
- } catch (error) {
46
- console.log('> Error is: ', error);
47
- }
48
-
49
- try {
50
- // console.log(e.target.id);
51
- if (this.uidAudioPlayng) {
52
- this.uidAudioPlayng = '';
53
- }
54
- } catch (error) {
55
- console.log('> Error is: ', error);
56
- }
57
- }
58
-
59
- playAudioMsg(e) {
60
- // stop all audio
61
- if (this.uidAudioPlayng) {
62
- const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
63
- divPlay.pause();
64
- // console.log('> pausa: ', divPlay);
65
- }
66
- try {
67
- // console.log(e.target.id);
68
- // set uid audio playng
69
- this.uidAudioPlayng = e.target.id;
70
- } catch (error) {
71
- console.log('> Error is: ', error);
72
- }
73
- }
74
-
75
- updateTimeAudioMsg(ev){
76
- var currTime = Math.floor(ev.target.currentTime);
77
- var duration = Math.floor(ev.target.duration);
78
-
79
- let minutes = 0;
80
- if(currTime > 60){
81
- minutes = Math.floor(currTime / 60);
82
- }
83
- const seconds = currTime - minutes * 60
84
- // console.log('timeeee', minutes + ':' + seconds )
85
- // this.playState.innerHTML = minutes + ':' + seconds
86
- }
87
-
88
-
89
-
90
- /**
91
- *
92
- * @param uid
93
- */
94
- playPausaAudioMsg(uid: string) {
95
- // console.log('playPausaAudioMsg: ', uid);
96
- const that = this;
97
- try {
98
- const divPause = (<HTMLAudioElement>document.getElementById(that.uidAudioPlayng));
99
- const divPlay = (<HTMLAudioElement>document.getElementById(uid));
100
- if (divPause) {
101
- divPause.pause();
102
- }
103
-
104
- if (that.uidAudioPlayng === uid) {
105
- that.uidAudioPlayng = '';
106
- } else {
107
- if (divPlay) {
108
- setTimeout(function() {
109
- // if (that.g.autoplay_activated) {
110
- // divPlay.play();
111
- // }
112
- this.uidAudioPlayng = uid;
113
- }, 300);
114
- }
115
- }
116
-
117
- } catch (error) {
118
- console.log('> Error is: ', error);
119
- }
120
- }
121
-
122
- }