@chat21/chat21-ionic 3.0.98 → 3.0.99

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 (24) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +4 -3
  3. package/src/app/app.component.ts +2 -3
  4. package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.scss +9 -0
  5. package/src/app/chatlib/conversation-detail/message/audio/audio.component.html +21 -0
  6. package/src/app/chatlib/conversation-detail/message/audio/audio.component.scss +122 -0
  7. package/src/app/chatlib/conversation-detail/message/audio/audio.component.spec.ts +23 -0
  8. package/src/app/chatlib/conversation-detail/message/audio/audio.component.ts +166 -0
  9. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html +5 -0
  10. package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +2 -1
  11. package/src/app/chatlib/conversation-detail/message/info-message/info-message.component.html +1 -1
  12. package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +3 -4
  13. package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.scss +4 -2
  14. package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.ts +6 -0
  15. package/src/app/components/sidebar-user-details/sidebar-user-details.component.ts +2 -2
  16. package/src/app/pages/conversation-detail/conversation-detail.page.ts +13 -3
  17. package/src/app/pages/conversations-list/conversations-list.page.ts +7 -5
  18. package/src/app/pages/profile-info/profile-info.page.html +12 -2
  19. package/src/app/pages/profile-info/profile-info.page.scss +7 -0
  20. package/src/app/pages/profile-info/profile-info.page.ts +31 -16
  21. package/src/app/shared/shared.module.ts +3 -0
  22. package/src/chat21-core/providers/abstract/notifications.service.ts +2 -2
  23. package/src/chat21-core/utils/constants.ts +3 -0
  24. package/src/chat21-core/utils/utils-message.ts +10 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # chat21-ionic ver 3.0
2
2
 
3
+ ### 3.0.99 in PROD
4
+
5
+ ### 3.0.99-rc.2
6
+ - bug-fixed: after tiledesk closes a conversation, call archiveConversation's conversationsHandler method to manually remote it from active conversations list
7
+
8
+ ### 3.0.99-rc.1
9
+ - added: audio file enabled
10
+ - added: audio icon if audio message is received in ion-list-conversations component
11
+ - bug-fixed: do not copy user if on mobile from profile-info modal
12
+ - bug-fixed: if lead email is deleted, leadInfo is not updated and can send email
13
+ - removed: PACKAGE.version in favour of environment.version
14
+
3
15
  ### 3.0.98 in PROD
4
16
 
5
17
  ### 3.0.98-rc.2
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-ionic",
3
3
  "author": "Tiledesk SRL",
4
- "version": "3.0.98",
4
+ "version": "3.0.99",
5
5
  "license": "MIT License",
6
6
  "homepage": "https://tiledesk.com/",
7
7
  "repository": {
@@ -23,7 +23,7 @@
23
23
  "@angular/common": "~8.2.14",
24
24
  "@angular/core": "~8.2.14",
25
25
  "@angular/forms": "~8.2.14",
26
- "@angular/google-maps": "^8.2.14",
26
+ "@angular/google-maps": "~9.0.0",
27
27
  "@angular/material": "^8.2.3",
28
28
  "@angular/platform-browser": "~8.2.14",
29
29
  "@angular/platform-browser-dynamic": "~8.2.14",
@@ -80,6 +80,7 @@
80
80
  "@ionic/angular-toolkit": "^2.1.1",
81
81
  "@types/jasmine": "~3.3.8",
82
82
  "@types/jasminewd2": "~2.0.3",
83
+ "@types/node": "^12.20.55",
83
84
  "codelyzer": "^5.0.0",
84
85
  "cordova-plugin-add-swift-support": "^2.0.2",
85
86
  "jasmine-core": "~4.4.0",
@@ -92,7 +93,7 @@
92
93
  "protractor": "~5.4.0",
93
94
  "ts-node": "~7.0.0",
94
95
  "tslint": "~5.15.0",
95
- "typescript": "~3.4.3"
96
+ "typescript": "^3.4.5"
96
97
  },
97
98
  "description": "An Ionic project",
98
99
  "cordova": {
@@ -56,7 +56,6 @@ import { getImageUrlThumbFromFirebasestorage } from 'src/chat21-core/utils/utils
56
56
  // import { mapTo } from 'rxjs/operators';
57
57
  import { TiledeskService } from './services/tiledesk/tiledesk.service';
58
58
  import { NetworkService } from './services/network-service/network.service';
59
- import * as PACKAGE from 'package.json';
60
59
  import { filter } from 'rxjs/operators'
61
60
  import { WebSocketJs } from './services/websocket/websocket-js';
62
61
  import { Location } from '@angular/common'
@@ -450,7 +449,7 @@ export class AppComponent implements OnInit {
450
449
 
451
450
  const appconfig = this.appConfigProvider.getConfig();
452
451
  // this.logger.info('[APP-COMP] appconfig: ', appconfig)
453
- this.version = PACKAGE.version;
452
+ this.version = environment.version;
454
453
  this.logger.info('[APP-COMP] version: ', this.version)
455
454
 
456
455
  this.logger.setLoggerConfig(true, appconfig.logLevel)
@@ -473,7 +472,7 @@ export class AppComponent implements OnInit {
473
472
  if (this.splashScreen) {
474
473
  this.splashScreen.hide();
475
474
  }
476
- this.statusBar.styleDefault();
475
+ this.statusBar.styleLightContent();
477
476
  this.navService.init(this.sidebarNav, this.detailNav);
478
477
  // this.persistence = appconfig.authPersistence;
479
478
  // this.appStorageService.initialize(environment.storage_prefix, this.persistence, '')
@@ -5,6 +5,11 @@
5
5
  :host .base_sent .msg_sent ::ng-deep > div > div > chat-image > div {
6
6
  // display: none !important;
7
7
  // border-radius: unset !important;
8
+ border-top-right-radius: 6px !important;
9
+ border-top-left-radius: 16px !important;
10
+ border-bottom-left-radius: 16px !important;
11
+ border-bottom-right-radius: 0px;
12
+
8
13
  img,
9
14
  .loader {
10
15
  border-top-right-radius: 6px !important;
@@ -17,6 +22,10 @@
17
22
  :host .base_receive .msg_receive ::ng-deep > div > div > chat-image > div > img {
18
23
  // display: none !important;
19
24
  // border-radius: unset !important;
25
+ border-top-left-radius: 6px !important;
26
+ border-top-right-radius: 16px !important;
27
+ border-bottom-right-radius: 16px !important;
28
+ border-bottom-left-radius: 0px;
20
29
  img,
21
30
  .loader {
22
31
  border-top-left-radius: 6px !important;
@@ -0,0 +1,21 @@
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
+ <div id="example"></div>
21
+
@@ -0,0 +1,122 @@
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
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { AudioComponent } from './audio.component';
4
+
5
+ describe('AudioComponent', () => {
6
+ let component: AudioComponent;
7
+ let fixture: ComponentFixture<AudioComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ AudioComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(AudioComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,166 @@
1
+ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
2
+ // import * as WaveSurfer from 'wavesurfer.js';
3
+
4
+ // declare var WaveSurfer
5
+ @Component({
6
+ selector: 'chat-audio',
7
+ templateUrl: './audio.component.html',
8
+ styleUrls: ['./audio.component.scss']
9
+ })
10
+ export class AudioComponent implements OnInit {
11
+
12
+ @Input() metadata: any;
13
+ @Output() onElementRendered = new EventEmitter<{element: string, status: boolean}>();
14
+
15
+ uidAudioPlayng: string = ''
16
+ divPlay: HTMLAudioElement
17
+ playState: HTMLElement
18
+ status: 'play' | 'pause' = 'play'
19
+
20
+ // wavesurfer: any;
21
+ constructor(private elementRef: ElementRef) { }
22
+
23
+ ngOnInit() {
24
+ // console.log('metadataaaaaa', this.metadata)
25
+ // this.divPlay = this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#audio_msg')
26
+ // this.playState= this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#duration')
27
+ this.loadLib()
28
+ }
29
+
30
+ // ionViewWillEnter(){
31
+ // this.loadLib()
32
+ // }
33
+
34
+ private async loadLib(){
35
+ // const SiriWave = await import("siriwave");
36
+ // console.log('elementttt', document.getElementById("example"), this.elementRef.nativeElement.querySelector("#example"))
37
+ // var instance = new SiriWave({
38
+ // // container: this.elementRef.nativeElement.querySelector("#example"),
39
+ // container: document.getElementById("example"),
40
+ // width: 300,
41
+ // height: 120,
42
+ // });
43
+ // instance.start();
44
+ // this.wavesurfer = WaveSurfer.create({
45
+ // container: "#" + 'example',
46
+ // waveColor: "#e1f5fe",
47
+ // progressColor: "#03a9f4",
48
+ // cursorColor: "rgb(255 255 255 / 50%)",
49
+ // barWidth: 4,
50
+ // barHeight: 1,
51
+ // barRadius: 2,
52
+ // cursorWidth: 1,
53
+ // // height: 150,
54
+ // fillParent: true,
55
+ // barGap: 0,
56
+ // // backend: 'MediaElement',
57
+ // // mediaType:'audio',
58
+ // normalize: true,
59
+ // // url: this.metadata.url
60
+ // })
61
+
62
+ // this.wavesurfer.load('https://eu.rtmv3.tiledesk.com/api/files/download?path=uploads/public/files/2f715ae1-6dc6-4cbf-a94c-42be26f1a723/media-2b92sy.ogg');
63
+
64
+ // this.wavesurfer.on('ready', function () {
65
+ // console.log('readyyyyy')
66
+ // // wavesurfer.play();
67
+ // });
68
+
69
+ }
70
+
71
+ onPlayPause(status: string){
72
+ // const divPlay = (<HTMLAudioElement>document.getElementById('audio_msg'));
73
+ if(status === 'play') {
74
+ this.divPlay.play();
75
+ this.status = 'pause'
76
+ } else {
77
+ this.divPlay.pause();
78
+ this.status = 'play'
79
+ }
80
+ }
81
+ pauseAudioMsg(e) {
82
+ try {
83
+ // stop all audio
84
+ if (this.uidAudioPlayng) {
85
+ const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
86
+ divPlay.pause();
87
+ // console.log('> pausa: ', divPlay);
88
+ }
89
+ } catch (error) {
90
+ console.log('> Error is: ', error);
91
+ }
92
+
93
+ try {
94
+ // console.log(e.target.id);
95
+ if (this.uidAudioPlayng) {
96
+ this.uidAudioPlayng = '';
97
+ }
98
+ } catch (error) {
99
+ console.log('> Error is: ', error);
100
+ }
101
+ }
102
+
103
+ playAudioMsg(e) {
104
+ // stop all audio
105
+ if (this.uidAudioPlayng) {
106
+ const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
107
+ divPlay.pause();
108
+ // console.log('> pausa: ', divPlay);
109
+ }
110
+ try {
111
+ // console.log(e.target.id);
112
+ // set uid audio playng
113
+ this.uidAudioPlayng = e.target.id;
114
+ } catch (error) {
115
+ console.log('> Error is: ', error);
116
+ }
117
+ }
118
+
119
+ updateTimeAudioMsg(ev){
120
+ var currTime = Math.floor(ev.target.currentTime);
121
+ var duration = Math.floor(ev.target.duration);
122
+
123
+ let minutes = 0;
124
+ if(currTime > 60){
125
+ minutes = Math.floor(currTime / 60);
126
+ }
127
+ const seconds = currTime - minutes * 60
128
+ // console.log('timeeee', minutes + ':' + seconds )
129
+ // this.playState.innerHTML = minutes + ':' + seconds
130
+ }
131
+
132
+
133
+
134
+ /**
135
+ *
136
+ * @param uid
137
+ */
138
+ playPausaAudioMsg(uid: string) {
139
+ // console.log('playPausaAudioMsg: ', uid);
140
+ const that = this;
141
+ try {
142
+ const divPause = (<HTMLAudioElement>document.getElementById(that.uidAudioPlayng));
143
+ const divPlay = (<HTMLAudioElement>document.getElementById(uid));
144
+ if (divPause) {
145
+ divPause.pause();
146
+ }
147
+
148
+ if (that.uidAudioPlayng === uid) {
149
+ that.uidAudioPlayng = '';
150
+ } else {
151
+ if (divPlay) {
152
+ setTimeout(function() {
153
+ // if (that.g.autoplay_activated) {
154
+ // divPlay.play();
155
+ // }
156
+ this.uidAudioPlayng = uid;
157
+ }, 300);
158
+ }
159
+ }
160
+
161
+ } catch (error) {
162
+ console.log('> Error is: ', error);
163
+ }
164
+ }
165
+
166
+ }
@@ -49,6 +49,11 @@
49
49
  (onElementRendered)="onElementRenderedFN($event)">
50
50
  </chat-frame>
51
51
 
52
+ <chat-audio *ngIf="isAudio(message)"
53
+ [metadata]="message.metadata"
54
+ (onElementRendered)="onElementRenderedFN($event)">
55
+ </chat-audio>
56
+
52
57
  <!-- <chat-frame *ngIf="message.metadata && message.metadata.type && message.metadata.type.includes('video')"
53
58
  [metadata]="message.metadata"
54
59
  [width]="message.metadata.width"
@@ -3,7 +3,7 @@ import { DomSanitizer } from '@angular/platform-browser';
3
3
  import { MessageModel } from 'src/chat21-core/models/message';
4
4
  import { MAX_WIDTH_IMAGES, MESSAGE_TYPE_MINE, MESSAGE_TYPE_OTHERS, MIN_WIDTH_IMAGES } from 'src/chat21-core/utils/constants';
5
5
  import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
6
- import { isFile, isFrame, isImage, messageType } from 'src/chat21-core/utils/utils-message';
6
+ import { isAudio, isFile, isFrame, isImage, messageType } from 'src/chat21-core/utils/utils-message';
7
7
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
8
8
  import { TranslateService } from '@ngx-translate/core';
9
9
  import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
@@ -33,6 +33,7 @@ export class BubbleMessageComponent implements OnInit, OnChanges {
33
33
  isImage = isImage;
34
34
  isFile = isFile;
35
35
  isFrame = isFrame;
36
+ isAudio = isAudio;
36
37
  convertColorToRGBA = convertColorToRGBA
37
38
 
38
39
  // ========== begin:: check message type functions ======= //
@@ -6,7 +6,7 @@
6
6
  </div>
7
7
 
8
8
  <div style="max-width: 70%;">
9
- <span class="base_info" [innerHTML]="message?.text | marked" tooltip="{{message.timestamp | amTimeAgo}} ({{message.timestamp | amLocal | amDateFormat: 'L HH:mm:ss'}})" placement="left"></span>
9
+ <span class="base_info" [innerHTML]="message?.text | marked" tooltip="{{message.timestamp | amTimeAgo}} ({{message.timestamp | amLocal | amDateFormat: 'L HH:mm:ss'}})" placement="bottom"></span>
10
10
  <!-- <ng-template #timeTooltipLeft>
11
11
  <span>{{message.timestamp | amTimeAgo}} ({{message.timestamp | amLocal | amDateFormat: 'L HH:mm:ss'}})</span>
12
12
  </ng-template> -->
@@ -133,10 +133,9 @@
133
133
  [innerHTML]="conversation.last_message_text"></p> -->
134
134
 
135
135
  <!-- <div *ngIf="conversation.type === 'image'" class="icon-image-before-msg-wpr"> -->
136
- <ion-icon *ngIf="conversation.type === 'image' && conversation.type !== 'file' " name="image-outline"
137
- class="icon-image-before-msg"></ion-icon>
138
- <ion-icon *ngIf="conversation.type === 'file' && conversation.type !== 'image'" name="attach-outline"
139
- class="icon-attach-before-msg"></ion-icon>
136
+ <ion-icon *ngIf="isImage(conversation)" name="image-outline" class="icon-image-before-msg"></ion-icon>
137
+ <ion-icon *ngIf="isFile(conversation)" name="attach-outline" class="icon-attach-before-msg"></ion-icon>
138
+ <ion-icon *ngIf="isAudio(conversation)" name="mic-outline" class="icon-mic-before-msg"></ion-icon>
140
139
  <!-- </div> -->
141
140
  <!-- [innerHTML]="conversation.last_message_text" -->
142
141
  <span [class.not-read]="conversation.is_new">
@@ -236,11 +236,13 @@ ion-item:hover {
236
236
  font-size: 12px;
237
237
  }
238
238
 
239
- .icon-image-before-msg-wpr {
239
+ .icon-image-before-msg-wpr{
240
240
  float: left;
241
241
  margin-right: 3px;
242
242
  }
243
- .icon-image-before-msg {
243
+
244
+ .icon-image-before-msg,
245
+ .icon-mic-before-msg {
244
246
  vertical-align: middle;
245
247
  color: #999999;
246
248
  padding-right: 3px;
@@ -17,6 +17,7 @@ import { DomSanitizer } from '@angular/platform-browser'
17
17
  import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
18
18
  import { AlertController } from '@ionic/angular';
19
19
  import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
20
+ import { isAudio, isFile, isFrame, isImage } from 'src/chat21-core/utils/utils-message';
20
21
  // import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
21
22
  // import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
22
23
 
@@ -34,6 +35,11 @@ export class IonListConversationsComponent extends ListConversationsComponent im
34
35
  @Output() onCloseAlert = new EventEmitter();
35
36
 
36
37
  convertMessage = convertMessage;
38
+ isImage = isImage
39
+ isFrame = isFrame
40
+ isFile = isFile
41
+ isAudio = isAudio
42
+
37
43
  isApp: boolean = false;
38
44
  public logger: LoggerService = LoggerInstance.getInstance();
39
45
  public currentYear: any;
@@ -12,7 +12,7 @@ import { AppConfigProvider } from 'src/app/services/app-config';
12
12
  import { EventsService } from 'src/app/services/events-service';
13
13
  import { tranlatedLanguage } from '../../../chat21-core/utils/constants';
14
14
  import { avatarPlaceholder, getColorBck } from 'src/chat21-core/utils/utils-user';
15
- import * as PACKAGE from 'package.json';
15
+ import { environment } from 'src/environments/environment';
16
16
  @Component({
17
17
  selector: 'app-sidebar-user-details',
18
18
  templateUrl: './sidebar-user-details.component.html',
@@ -70,7 +70,7 @@ export class SidebarUserDetailsComponent implements OnInit, OnChanges {
70
70
 
71
71
  ngOnInit() {
72
72
  this.DASHBOARD_URL = this.appConfigProvider.getConfig().dashboardUrl + '#/project/';
73
- this.version = PACKAGE.version;
73
+ this.version = environment.version;
74
74
  this.subcribeToAuthStateChanged();
75
75
  this.listenTocurrentProjectUserUserAvailability$();
76
76
  this.listenToCurrentStoredProject();
@@ -941,8 +941,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
941
941
  that.logger.debug('[CONVS-DETAIL] getLeadDetail - selected REQUEST detail', request)
942
942
  if(request && request.channel){
943
943
  this.conversation.attributes['request_channel'] = request.channel.name
944
- }
945
- if (request.lead && request.lead.email) {
944
+ }
945
+ if (request.lead && request.lead.email) { //LEAD has an email
946
946
  that.leadInfo = {
947
947
  lead_id: request.lead.lead_id,
948
948
  hasEmail: true,
@@ -954,6 +954,16 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
954
954
  }
955
955
  that.presenceService.userIsOnline(this.leadInfo.lead_id);
956
956
  that.webSocketService.subscribeToWS_RequesterPresence(projectId, that.leadInfo.lead_id)
957
+ } else{ // LEAD not has an email
958
+ that.leadInfo = {
959
+ lead_id: request.lead.lead_id,
960
+ hasEmail: false,
961
+ email: null,
962
+ projectId: projectId,
963
+ presence: {
964
+ status: 'offline'
965
+ }
966
+ }
957
967
  }
958
968
  }, (error) => {
959
969
  this.logger.error('[CONVS-DETAIL] - getLeadDetail - GET REQUEST DETAIL - ERROR ', error)
@@ -1286,8 +1296,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
1286
1296
  this.conversation.attributes['project_name'],
1287
1297
  this.conversation.attributes['request_channel']
1288
1298
  )
1289
- this.getLeadDetail()
1290
1299
  }
1300
+ this.getLeadDetail()
1291
1301
  }
1292
1302
 
1293
1303
  updateLiveInfo(msg) {
@@ -46,7 +46,7 @@ import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'
46
46
  import { NetworkService } from 'src/app/services/network-service/network.service'
47
47
  import { Subject } from 'rxjs'
48
48
  import { skip, takeUntil } from 'rxjs/operators'
49
- import { TYPE_DIRECT } from 'src/chat21-core/utils/constants';
49
+ import { REQUEST_ARCHIVED, TYPE_DIRECT } from 'src/chat21-core/utils/constants';
50
50
  import { getProjectIdSelectedConversation } from 'src/chat21-core/utils/utils-message';
51
51
  import { WebsocketService } from 'src/app/services/websocket/websocket.service';
52
52
 
@@ -791,7 +791,7 @@ export class ConversationListPage implements OnInit {
791
791
  }
792
792
 
793
793
  onConversationLoaded(conversation: ConversationModel) {
794
- // this.logger.log('[CONVS-LIST-PAGE] onConversationLoaded ', conversation)
794
+ this.logger.log('[CONVS-LIST-PAGE] onConversationLoaded ', conversation)
795
795
  // this.logger.log('[CONVS-LIST-PAGE] onConversationLoaded is new? ', conversation.is_new)
796
796
  // if (conversation.is_new === false) {
797
797
  // this.ionContentConvList.scrollToTop(0);
@@ -802,7 +802,7 @@ export class ConversationListPage implements OnInit {
802
802
  // Fixes the bug: if a snippet of code is pasted and sent it is not displayed correctly in the convesations list
803
803
 
804
804
  var regex = /<br\s*[\/]?>/gi
805
- if (conversation && conversation.last_message_text) {
805
+ if (conversation ) { //&& conversation.last_message_text
806
806
  conversation.last_message_text = conversation.last_message_text.replace(regex, '',)
807
807
 
808
808
  //FIX-BUG: 'YOU: YOU: YOU: text' on last-message-text in conversation-list
@@ -900,13 +900,13 @@ export class ConversationListPage implements OnInit {
900
900
  if (checkPlatformIsMobile()) {
901
901
  this.logger.log('[CONVS-LIST-PAGE] checkPlatformIsMobile(): ', checkPlatformIsMobile())
902
902
  this.logger.log('[CONVS-LIST-PAGE] DESKTOP (window < 768)', this.navService)
903
- this.logger.log('[CONVS-LIST-PAGE] navigateByUrl this.conversationSelected conversation_with_fullname ', this.conversationSelected.conversation_with_fullname)
903
+ this.logger.log('[CONVS-LIST-PAGE] navigateByUrl this.conversationSelected conversation_with_fullname ', this.conversationSelected)
904
904
  let pageUrl = 'conversation-detail/' + this.uidConvSelected + '/' + this.conversationSelected.conversation_with_fullname + '/' + converationType
905
905
  this.logger.log('[CONVS-LIST-PAGE] pageURL', pageUrl)
906
906
  // replace(/\(/g, '%28').replace(/\)/g, '%29') -> used for the encoder of any round brackets
907
907
  this.router.navigateByUrl(pageUrl.replace(/\(/g, '%28').replace(/\)/g, '%29').replace( /#/g, "%23" ), {replaceUrl: true})
908
908
  } else {
909
- this.logger.log('[CONVS-LIST-PAGE] navigateByUrl this.conversationSelected conversation_with_fullname ', this.conversationSelected.conversation_with_fullname)
909
+ this.logger.log('[CONVS-LIST-PAGE] navigateByUrl this.conversationSelected conversation_with_fullname ', this.conversationSelected)
910
910
  this.logger.log('[CONVS-LIST-PAGE] checkPlatformIsMobile(): ', checkPlatformIsMobile())
911
911
  this.logger.log('[CONVS-LIST-PAGE] MOBILE (window >= 768) ', this.navService)
912
912
  let pageUrl = 'conversation-detail/' + this.uidConvSelected
@@ -1058,6 +1058,8 @@ export class ConversationListPage implements OnInit {
1058
1058
  this.tiledeskService.closeSupportGroup(tiledeskToken, project_id, conversationId).subscribe((res) => {
1059
1059
  this.archiveActionNotAllowed = false
1060
1060
  this.logger.log('[CONVS-LIST-PAGE] - onCloseConversation closeSupportGroup RES',res)
1061
+ if(res.status === REQUEST_ARCHIVED)
1062
+ this.conversationsHandlerService.archiveConversation(conversationId)
1061
1063
  },(error) => {
1062
1064
  this.logger.error('[CONVS-LIST-PAGE] - onCloseConversation closeSupportGroup - ERROR ',error)
1063
1065
  this.logger.error('[CONVS-LIST-PAGE] - onCloseConversation closeSupportGroup - ERROR error.error.msg ',error.error.msg)
@@ -1,12 +1,22 @@
1
+ <!-- <ion-header no-border class="ion-no-border">
2
+ <ion-toolbar>
3
+ <ion-buttons slot="end">
4
+ <ion-button ion-button fill="clear" (click)="onClose()">
5
+ <ion-icon slot="icon-only" name="close"></ion-icon>
6
+ </ion-button>
7
+ </ion-buttons>
8
+ </ion-toolbar>
9
+ </ion-header> -->
10
+
1
11
  <ion-content class="current-user-profile">
2
12
 
3
- <div class="buttons-header">
13
+ <ion-toolbar>
4
14
  <ion-buttons slot="end">
5
15
  <ion-button ion-button fill="clear" (click)="onClose()">
6
16
  <ion-icon slot="icon-only" name="close"></ion-icon>
7
17
  </ion-button>
8
18
  </ion-buttons>
9
- </div>
19
+ </ion-toolbar>
10
20
 
11
21
  <div *ngIf="loggedUser" class="content-user-profile">
12
22
  <div class="user">
@@ -68,6 +68,12 @@
68
68
  // }
69
69
  // }
70
70
 
71
+ ion-toolbar{
72
+ position: absolute;
73
+ z-index: 2;
74
+ --ion-toolbar-background: transparent;
75
+ }
76
+
71
77
  .availability-section {
72
78
  // top: 320px;
73
79
  text-align: center;
@@ -310,6 +316,7 @@
310
316
  direction: ltr;
311
317
  -webkit-font-feature-settings: 'liga';
312
318
  -webkit-font-smoothing: antialiased;
319
+ font-feature-settings: 'liga'
313
320
  }
314
321
 
315
322
  .sidebar-labels {
@@ -1,3 +1,4 @@
1
+ import { environment } from 'src/environments/environment';
1
2
  import { AppConfigProvider } from 'src/app/services/app-config';
2
3
  import { ImageRepoService } from 'src/chat21-core/providers/abstract/image-repo.service';
3
4
  import { Component, OnInit, Input, EventEmitter, Output, ViewChild, Renderer2 } from '@angular/core';
@@ -14,16 +15,13 @@ import { PresenceService } from 'src/chat21-core/providers/abstract/presence.ser
14
15
  import { UserModel } from 'src/chat21-core/models/user';
15
16
 
16
17
  // utils
17
- import { isInArray, setLastDateWithLabels } from 'src/chat21-core/utils/utils';
18
- import * as PACKAGE from 'package.json';
19
18
  import { EventsService } from 'src/app/services/events-service';
20
19
 
21
20
  // Logger
22
21
  import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
23
22
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
24
23
  import { WebsocketService } from 'src/app/services/websocket/websocket.service';
25
- import { AppStorageService } from 'src/chat21-core/providers/abstract/app-storage.service';
26
- import { skip } from 'rxjs/operators';
24
+ import { checkPlatformIsMobile, setLastDateWithLabels } from 'src/chat21-core/utils/utils';
27
25
 
28
26
  @Component({
29
27
  selector: 'app-profile-info',
@@ -39,6 +37,7 @@ export class ProfileInfoPage implements OnInit {
39
37
  public translationsMap: Map<string, string>;
40
38
  private logger: LoggerService = LoggerInstance.getInstance();
41
39
 
40
+ isMobile: boolean = false;
42
41
  private subscriptions = [];
43
42
  borderColor = '#2d323e';
44
43
  fontColor = '#949494';
@@ -70,8 +69,19 @@ export class ProfileInfoPage implements OnInit {
70
69
 
71
70
  /** */
72
71
  ngOnInit() {
73
- this.version = PACKAGE.version;
72
+ this.version = environment.version;
74
73
  this.translations();
74
+
75
+ if (checkPlatformIsMobile()) {
76
+ this.isMobile = true
77
+ // this.openInfoConversation = false; // indica se è aperto il box info conversazione
78
+ this.logger.log('[CONVS-DETAIL] - initialize -> checkPlatformIsMobile isMobile? ', this.isMobile)
79
+ } else {
80
+ this.isMobile = false
81
+ this.logger.log('[CONVS-DETAIL] - initialize -> checkPlatformIsMobile isMobile? ', this.isMobile)
82
+ // this.openInfoConversation = true;
83
+ }
84
+
75
85
  }
76
86
 
77
87
  /** */
@@ -280,17 +290,22 @@ export class ProfileInfoPage implements OnInit {
280
290
  }
281
291
 
282
292
  copyLoggedUserUID() {
283
- var copyText = document.createElement("input");
284
- copyText.setAttribute("type", "text");
285
- copyText.setAttribute("value", this.loggedUser.uid);
286
-
287
- document.body.appendChild(copyText);
288
- copyText.select();
289
- copyText.setSelectionRange(0, 99999); /*For mobile devices*/
290
- document.execCommand("copy");
291
- this.logger.log("Copied the text: " + copyText.value);
292
- const tootipElem = <HTMLElement>document.querySelector('.chat-tooltip');
293
- this.renderer.appendChild(tootipElem, this.renderer.createText('Copied!'))
294
293
 
294
+ if(!this.isMobile){
295
+ var copyText = document.createElement("input");
296
+ copyText.setAttribute("type", "text");
297
+ copyText.setAttribute("value", this.loggedUser.uid);
298
+
299
+ document.body.appendChild(copyText);
300
+ copyText.select();
301
+ copyText.setSelectionRange(0, 99999); /*For mobile devices*/
302
+ document.execCommand("copy");
303
+ this.logger.log("Copied the text: " + copyText.value);
304
+ const tootipElem = <HTMLElement>document.querySelector('.chat-tooltip');
305
+ this.renderer.appendChild(tootipElem, this.renderer.createText('Copied!'))
306
+ }else{
307
+ navigator.clipboard.writeText(this.loggedUser.uid)
308
+ }
309
+
295
310
  }
296
311
  }
@@ -50,6 +50,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
50
50
  import { MatSnackBarModule } from '@angular/material/snack-bar';
51
51
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
52
52
  import { SafeHtmlPipe } from '../directives/safe-html.pipe';
53
+ import { AudioComponent } from '../chatlib/conversation-detail/message/audio/audio.component';
53
54
 
54
55
  // import { MessageTextAreaComponent } from '../components/conversation-detail/message-text-area/message-text-area.component'; // MessageTextAreaComponent is part of the declarations ConversationDetailPageModule
55
56
 
@@ -77,6 +78,7 @@ import { SafeHtmlPipe } from '../directives/safe-html.pipe';
77
78
  ActionButtonComponent,
78
79
  FrameComponent,
79
80
  ImageComponent,
81
+ AudioComponent,
80
82
  InfoMessageComponent,
81
83
  ReturnReceiptComponent,
82
84
  TextComponent,
@@ -120,6 +122,7 @@ import { SafeHtmlPipe } from '../directives/safe-html.pipe';
120
122
  ActionButtonComponent,
121
123
  FrameComponent,
122
124
  ImageComponent,
125
+ AudioComponent,
123
126
  InfoMessageComponent,
124
127
  ReturnReceiptComponent,
125
128
  TextComponent,
@@ -1,6 +1,6 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import { UserModel } from 'src/chat21-core/models/user';
3
- import * as PACKAGE from '../../../../package.json';
3
+ import { environment } from 'src/environments/environment';
4
4
 
5
5
  @Injectable({
6
6
  providedIn: 'root'
@@ -8,7 +8,7 @@ import * as PACKAGE from '../../../../package.json';
8
8
  export abstract class NotificationsService {
9
9
 
10
10
  private _tenant: string;
11
- public BUILD_VERSION = PACKAGE.version
11
+ public BUILD_VERSION = environment.version
12
12
 
13
13
  public setTenant(tenant): void {
14
14
  this._tenant = tenant;
@@ -25,6 +25,9 @@ export const MSG_STATUS_RECEIVED = 200;
25
25
  export const MSG_STATUS_RETURN_RECEIPT = 250;
26
26
  export const MSG_STATUS_SEEN = 300;
27
27
 
28
+ //REQUEST STATUS
29
+ export const REQUEST_ARCHIVED = 1000
30
+
28
31
  // constans messages detail
29
32
  export const MIN_HEIGHT_TEXTAREA = 24;
30
33
  export const MAX_HEIGHT_TEXTAREA = 180;
@@ -12,14 +12,14 @@ import {
12
12
 
13
13
  /** */
14
14
  export function isImage(message: any) {
15
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'image') {
15
+ if (message && message.type && message.type === 'image' && message.metadata && message.metadata.src) {
16
16
  return true;
17
17
  }
18
18
  return false;
19
19
  }
20
20
 
21
21
  export function isFrame(message: any) {
22
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'frame') {
22
+ if (message && message.type && message.type === 'frame' && message.metadata && message.metadata.src) {
23
23
  return true;
24
24
  }
25
25
  return false;
@@ -27,7 +27,14 @@ export function isFrame(message: any) {
27
27
 
28
28
  /** */
29
29
  export function isFile(message: any) {
30
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'file') {
30
+ if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && !message.metadata.type.includes('audio')) {
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ export function isAudio(message: any) {
37
+ if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && message.metadata.type.includes('audio') ) {
31
38
  return true;
32
39
  }
33
40
  return false;