@chat21/chat21-web-widget 5.0.71-rc.2 → 5.0.71-rc.5

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 (32) hide show
  1. package/.github/workflows/build.yml +2 -2
  2. package/CHANGELOG.md +16 -0
  3. package/Dockerfile +1 -1
  4. package/deploy_amazon_beta.sh +11 -4
  5. package/deploy_amazon_prod.sh +11 -4
  6. package/package.json +1 -1
  7. package/src/app/app.component.ts +12 -9
  8. package/src/app/component/conversation-detail/conversation/conversation.component.ts +1 -7
  9. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +0 -3
  10. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +8 -4
  11. package/src/app/component/last-message/last-message.component.scss +1 -1
  12. package/src/app/component/message/carousel/carousel.component.html +1 -1
  13. package/src/app/component/message/carousel/carousel.component.ts +2 -1
  14. package/src/app/component/message/image/image.component.ts +0 -3
  15. package/src/app/utils/constants.ts +0 -2
  16. package/src/app/utils/globals.ts +0 -2
  17. package/src/app/utils/rules.ts +1 -1
  18. package/src/assets/twp/chatbot-panel.html +5 -5
  19. package/src/assets/twp/index-dev.html +2 -1
  20. package/src/chat21-core/models/upload.ts +0 -1
  21. package/src/chat21-core/providers/abstract/upload.service.ts +3 -0
  22. package/src/chat21-core/providers/firebase/firebase-auth-service.ts +3 -3
  23. package/src/chat21-core/providers/firebase/firebase-conversations-handler.ts +1 -1
  24. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +128 -6
  25. package/src/chat21-core/providers/mqtt/mqtt-auth-service.ts +1 -1
  26. package/src/chat21-core/providers/mqtt/mqtt-conversations-handler.ts +5 -0
  27. package/src/chat21-core/providers/native/native-upload-service.ts +68 -0
  28. package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +3 -0
  29. package/src/chat21-core/utils/constants.ts +15 -1
  30. package/src/chat21-core/utils/triggerHandler.ts +0 -1
  31. package/src/chat21-core/utils/utils.ts +0 -39
  32. package/src/launch.js +0 -1
@@ -3,8 +3,8 @@ on:
3
3
  push:
4
4
  branches:
5
5
  - master # The default branch
6
- - branch-* # The other branches to be analyzed
7
- - features/*
6
+ - (branch|release)-.* # The other branches to be analyzed
7
+ - (features|release)/.*
8
8
  pull_request:
9
9
  types: [opened, synchronize, reopened]
10
10
  jobs:
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # chat21-web-widget ver 5.0
2
2
 
3
+ ### 5.0.71-rc.5
4
+ - bug-fixed: last-message box is visible also if text is empty
5
+
6
+ ### 5.0.71-rc.4
7
+ - added: uploadProfile method into upload.service files
8
+ - bug-fixed: if hiddenMessage is present and user restart conversation from header menu, flow does not restart from beginning
9
+ - bug-fixed: do not disable url buttons on carousel element
10
+ - bug-fixed: do not sound if convAdded is fired and on reconnect event
11
+ - bug-fixed: init Rules only if widget is closed
12
+ - removed: 'Powereb By Tiledesk' on conversation and home components only for cahtbot-panel.html page
13
+
14
+ ### 5.0.71-rc.3
15
+ - added: delete method for firebase-upload service
16
+ - added: size attribute to metadata object while uploading file
17
+ - bug-fixed: cannot read property of undefined while reading auth() in onOpenCloseWidget method with singleConversation mode active
18
+
3
19
  ### 5.0.71-rc.2
4
20
  - added: hiddenMessage tiledesk property to start a conversation with an hidden info message
5
21
  - added: ability to listen from parent message and start a new Conversation with an hidden intentName info message
package/Dockerfile CHANGED
@@ -15,7 +15,7 @@ COPY . .
15
15
 
16
16
  ## Build the angular app in production mode and store the artifacts in dist folder
17
17
 
18
- RUN npm run ng build -- --configuration="prod" --output-path=dist --base-href="./" --output-hashing=none --build-optimizer=false --vendor-chunk
18
+ RUN npm run ng build --configuration="prod" --output-path=dist --base-href="./" --output-hashing=none --build-optimizer=false --vendor-chunk
19
19
 
20
20
 
21
21
  ### STAGE 2: Setup ###
@@ -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.71-rc.2",
4
+ "version": "5.0.71-rc.5",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -140,7 +140,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
140
140
  const that = this;
141
141
  const subChangedConversation = this.conversationsHandlerService.conversationChanged.subscribe((conversation) => {
142
142
  // that.ngZone.run(() => {
143
- if (conversation) {
143
+ if (conversation) {
144
144
  this.onImageLoaded(conversation)
145
145
  this.onConversationLoaded(conversation)
146
146
 
@@ -148,9 +148,9 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
148
148
  that.disposeWidget();
149
149
  return;
150
150
  }
151
-
151
+
152
152
  if(conversation.is_new && conversation.sender !== this.g.senderId && !isInfo(conversation)){
153
- that.manageTabNotification();
153
+ that.manageTabNotification(conversation.sound);
154
154
  }
155
155
 
156
156
  if (that.g.isOpen === true) {
@@ -196,7 +196,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
196
196
  return;
197
197
  }
198
198
  if (conversation.is_new) {
199
- that.manageTabNotification()
199
+ that.manageTabNotification(false)
200
200
  // this.soundMessage();
201
201
  }
202
202
  if(this.g.isOpen === false){
@@ -421,7 +421,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
421
421
  that.showWidget();
422
422
  }
423
423
 
424
- if(this.g.botsRules){
424
+ if(this.g.botsRules && !this.g.isOpen){
425
425
  const rules = new Rules(that.tiledeskRequestsService, that.appStorageService,that.g)
426
426
  rules.initRules(that.g.windowContext, that.g.tiledeskToken, user, that.generateNewUidConversation(), that.g.botsRules)
427
427
  }
@@ -714,6 +714,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
714
714
  this.isConversationArchived = false;
715
715
 
716
716
  /** allow to start conversation with an hidden message (without publishing 'new_conversation' event) */
717
+ this.logger.debug('[APP-COMP] AppComponent::startNewConversation hiddenMessage',this.g.hiddenMessage );
717
718
  if(this.g.hiddenMessage){
718
719
  this.onNewConversationWithMessage(this.g.hiddenMessage)
719
720
  return;
@@ -910,7 +911,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
910
911
  }).then((res)=> { this.showWidget() });
911
912
  return;
912
913
  }
913
-
914
914
  this.conversationsHandlerService.getLastConversation((conv, error)=> {
915
915
  this.logger.debug('[APP-COMP] getConverationRESTApi: conversation from rest API --> ', conv)
916
916
  if(error){
@@ -1473,7 +1473,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1473
1473
  }
1474
1474
  }
1475
1475
 
1476
- private manageTabNotification() {
1476
+ private manageTabNotification(canSound: boolean) {
1477
1477
  if (!this.isTabVisible) {
1478
1478
  // TAB IS HIDDEN --> manage title and SOUND
1479
1479
  // this.g.windowContext.parent.title = "HIDDEN"
@@ -1493,7 +1493,8 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1493
1493
  }
1494
1494
  }, 1000);
1495
1495
  }
1496
- this.soundMessage()
1496
+ if(canSound)
1497
+ this.soundMessage()
1497
1498
  }
1498
1499
 
1499
1500
 
@@ -1552,7 +1553,8 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1552
1553
  if(this.g.singleConversation){
1553
1554
  this.isOpenHome = false;
1554
1555
  this.g.setParameter('isOpenPrechatForm', false)
1555
- this.manageWidgetSingleConversation()
1556
+ this.initConversationsHandler(this.g.tenant, this.g.senderId)
1557
+ // this.manageWidgetSingleConversation()
1556
1558
  } else if (this.g.startFromHome) {
1557
1559
  this.isOpenHome = true;
1558
1560
  this.isOpenConversation = false;
@@ -1842,6 +1844,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1842
1844
  */
1843
1845
  onNewConversationButtonClicked(event){
1844
1846
  this.logger.debug('[APP-COMP] onNewConversationButtonClicked');
1847
+ this.g.setParameter('hiddenMessage', null)
1845
1848
 
1846
1849
  this.isOpenConversation = false;
1847
1850
  this.g.singleConversation? this.isOpenHome = false: null;
@@ -16,7 +16,6 @@ import {
16
16
  import { MessageModel } from 'src/chat21-core/models/message';
17
17
 
18
18
  // utils
19
- import { isPopupUrl } from 'src/app/utils/utils';
20
19
  import { v4 as uuidv4 } from 'uuid';
21
20
 
22
21
 
@@ -41,7 +40,7 @@ import { CustomTranslateService } from 'src/chat21-core/providers/custom-transla
41
40
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
42
41
  import { TiledeskRequestsService } from 'src/chat21-core/providers/tiledesk/tiledesk-requests.service';
43
42
  import { LIVE_PAGE } from 'src/chat21-core/utils/constants';
44
- import { getDateDifference, popupUrl } from 'src/chat21-core/utils/utils';
43
+ import { getDateDifference } from 'src/chat21-core/utils/utils';
45
44
  import { isJustRecived, isUserBanned } from 'src/chat21-core/utils/utils-message';
46
45
  import { AppComponent } from '../../../app.component';
47
46
  import { ConversationContentComponent } from '../conversation-content/conversation-content.component';
@@ -113,11 +112,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
113
112
  isOpenAttachmentPreview: Boolean = false;
114
113
  attachments: Array<{ file: Array<any>, metadata: {}}>
115
114
 
116
-
117
-
118
- isPopupUrl = isPopupUrl;
119
- popupUrl = popupUrl;
120
-
121
115
  // availableAgentsStatus = false; // indica quando è impostato lo stato degli agenti nel subscribe
122
116
  messages: Array<MessageModel> = [];
123
117
 
@@ -5,7 +5,6 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service
5
5
  import { UploadService } from 'src/chat21-core/providers/abstract/upload.service';
6
6
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
7
7
  import { MESSAGE_TYPE_INFO, MESSAGE_TYPE_MINE, MESSAGE_TYPE_OTHERS } from 'src/chat21-core/utils/constants';
8
- import { isPopupUrl, popupUrl } from 'src/chat21-core/utils/utils';
9
8
  import { isCarousel, isEmojii, isFirstMessage, isFrame, isImage, isInfo, isLastMessage, isMine, isSameSender, messageType } from 'src/chat21-core/utils/utils-message';
10
9
 
11
10
  @Component({
@@ -43,8 +42,6 @@ export class ConversationContentComponent implements OnInit {
43
42
  // ========= end:: gestione scroll view messaggi ======= //
44
43
 
45
44
  // ========= begin:: dichiarazione funzioni ======= //
46
- isPopupUrl = isPopupUrl;
47
- popupUrl = popupUrl;
48
45
  isCarousel = isCarousel;
49
46
  // ========= end:: dichiarazione funzioni ======= //
50
47
 
@@ -131,6 +131,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
131
131
  if (event.target.files && event.target.files[0]) {
132
132
  const nameFile = event.target.files[0].name;
133
133
  const typeFile = event.target.files[0].type;
134
+ const size = event.target.files[0].size
134
135
  const reader = new FileReader();
135
136
  that.logger.debug('[CONV-FOOTER] OK preload: ', nameFile, typeFile, reader);
136
137
  reader.addEventListener('load', function () {
@@ -146,7 +147,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
146
147
  that.logger.debug('[CONV-FOOTER] onload image');
147
148
  // that.arrayFilesLoad.push(imageXLoad);
148
149
  const uid = (new Date().getTime()).toString(36); // imageXLoad.src.substring(imageXLoad.src.length - 16);
149
- that.arrayFilesLoad[0] = { uid: uid, file: imageXLoad, type: typeFile };
150
+ that.arrayFilesLoad[0] = { uid: uid, file: imageXLoad, type: typeFile, size: size };
150
151
  that.logger.debug('[CONV-FOOTER] OK: ', that.arrayFilesLoad[0]);
151
152
  // SEND MESSAGE
152
153
  that.loadFile();
@@ -159,7 +160,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
159
160
  };
160
161
  // that.arrayFilesLoad.push(imageXLoad);
161
162
  const uid = (new Date().getTime()).toString(36); // imageXLoad.src.substring(imageXLoad.src.length - 16);
162
- that.arrayFilesLoad[0] = { uid: uid, file: fileXLoad, type: typeFile };
163
+ that.arrayFilesLoad[0] = { uid: uid, file: fileXLoad, type: typeFile, size: size };
163
164
  that.logger.debug('[CONV-FOOTER] OK: ', that.arrayFilesLoad[0]);
164
165
  // SEND MESSAGE
165
166
  that.loadFile();
@@ -182,6 +183,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
182
183
  const fileXLoad = this.arrayFilesLoad[0].file;
183
184
  const uid = this.arrayFilesLoad[0].uid;
184
185
  const type = this.arrayFilesLoad[0].type;
186
+ const size = this.arrayFilesLoad[0].size
185
187
  this.logger.debug('[CONV-FOOTER] that.fileXLoad: ', type);
186
188
  let metadata;
187
189
  if (type.startsWith('image') && !type.includes('svg')) {
@@ -191,14 +193,16 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
191
193
  'width': fileXLoad.width,
192
194
  'height': fileXLoad.height,
193
195
  'type': type,
194
- 'uid': uid
196
+ 'uid': uid,
197
+ 'size': size
195
198
  };
196
199
  } else {
197
200
  metadata = {
198
201
  'name': fileXLoad.title,
199
202
  'src': fileXLoad.src,
200
203
  'type': type,
201
- 'uid': uid
204
+ 'uid': uid,
205
+ 'size': size
202
206
  };
203
207
  }
204
208
  this.logger.debug('[CONV-FOOTER] metadata -------> ', metadata);
@@ -110,7 +110,7 @@
110
110
  margin-left: 45px;
111
111
  margin-right: 16px;
112
112
  border-radius: 12px 12px 12px 12px;
113
- padding: 5px;
113
+ padding: 0px 5px;
114
114
  }
115
115
 
116
116
  .previewNewMessagge.no-background{
@@ -22,7 +22,7 @@
22
22
  <div class="buttons" *ngIf="card?.buttons && card?.buttons.length > 0">
23
23
  <div *ngFor="let button of card?.buttons"
24
24
  class="single-button action"
25
- [ngClass]="{'disabled': (isConversationArchived || !isLastMessage), 'active': button?.active}"
25
+ [ngClass]="{'disabled': (isConversationArchived || button.type !== TYPE_BUTTON.URL), 'active': button?.active}"
26
26
  (click)="actionButtonClick($event, button, i)" >
27
27
  {{button.value}}
28
28
  </div>
@@ -1,5 +1,6 @@
1
1
  import { Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChange, SimpleChanges, ViewChildren } from '@angular/core';
2
2
  import { MessageModel } from 'src/chat21-core/models/message';
3
+ import { TYPE_BUTTON } from 'src/chat21-core/utils/constants';
3
4
  import { isCarousel } from 'src/chat21-core/utils/utils-message';
4
5
 
5
6
  @Component({
@@ -31,7 +32,7 @@ export class CarouselComponent implements OnInit{
31
32
  hoverTextColor: string;
32
33
  type: string;
33
34
  button: any;
34
-
35
+ TYPE_BUTTON = TYPE_BUTTON;
35
36
  constructor(private elementRef: ElementRef) { }
36
37
 
37
38
  ngOnInit() {
@@ -1,6 +1,5 @@
1
1
  import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
2
  import { saveAs } from 'file-saver';
3
- import { popupUrl } from 'src/chat21-core/utils/utils';
4
3
 
5
4
  @Component({
6
5
  selector: 'chat-image',
@@ -16,9 +15,7 @@ export class ImageComponent implements OnInit {
16
15
 
17
16
  loading: boolean = true
18
17
  tooltipMessage: string;
19
-
20
18
 
21
- popupUrl = popupUrl;
22
19
 
23
20
  constructor() { }
24
21
 
@@ -65,8 +65,6 @@ export const FIREBASESTORAGE_BASE_URL_IMAGE = 'https://firebasestorage.googleapi
65
65
  export const IMG_PROFILE_BOT = '/assets/images/avatar_bot_tiledesk.svg';
66
66
  export const IMG_PROFILE_DEFAULT = '/assets/images/avatar_male_tiledesk.svg';
67
67
 
68
- // localstorage
69
- export const STORAGE_PREFIX = 'widget_';
70
68
 
71
69
  // start conversation bot (proxy)
72
70
  export const PROXY_MSG_START = '__start';
@@ -123,7 +123,6 @@ export class Globals {
123
123
  LABEL_PREVIEW: string;
124
124
 
125
125
  // ============ BEGIN: EXTERNAL PARAMETERS ==============//
126
- globalsParameters: any;
127
126
  autoStart: boolean;
128
127
  startHidden: boolean;
129
128
  isShown: boolean;
@@ -228,7 +227,6 @@ export class Globals {
228
227
  * 1: initParameters
229
228
  */
230
229
  initDefafultParameters() {
231
- this.globalsParameters = {};
232
230
 
233
231
  let wContext: any = window;
234
232
  if (window.frameElement && window.frameElement.getAttribute('tiledesk_context') === 'parent') {
@@ -11,7 +11,7 @@ import { Globals } from './globals';
11
11
 
12
12
  @Injectable({
13
13
  providedIn: 'root'
14
- })
14
+ })
15
15
  export class Rules {
16
16
 
17
17
  private windowContext:Window = window
@@ -368,8 +368,7 @@
368
368
  });
369
369
 
370
370
  window.Tiledesk('onBeforeInit', function(event_data) {
371
- console.log("onBeforeInit Tiledesk FN", event_data);
372
-
371
+ // console.log("onBeforeInit Tiledesk FN", event_data);
373
372
  setTimeout(() => {
374
373
  document.getElementById("preloader").style.display = "none";
375
374
  if(event_data && event_data.detail && event_data.detail.appConfigs){
@@ -387,7 +386,8 @@
387
386
  });
388
387
 
389
388
  window.Tiledesk('onInit', function(event_data) {
390
- console.log("onInit Tiledesk FN", event_data);
389
+ // console.log("onInit Tiledesk FN", event_data);
390
+ window.Tiledesk('setParameter', {key: 'poweredBy', value: ''})
391
391
  // setTimeout(() => {
392
392
  // document.getElementById("preloader").style.display = "none";
393
393
  // }, 1000);
@@ -400,7 +400,7 @@
400
400
  });
401
401
 
402
402
  window.Tiledesk('onAuthStateChanged', function(event_data) {
403
- console.log("AUTHENTICATED!", event_data);
403
+ // console.log("AUTHENTICATED!", event_data);
404
404
  // if(event_data.detail.isLogged){
405
405
  // console.log("isLogged!!!!", event_data);
406
406
  // window.Tiledesk('show')
@@ -408,7 +408,7 @@
408
408
  });
409
409
 
410
410
  window.Tiledesk('onMessageCreated', function(event_data) {
411
- console.log("onMessageCreated!", event_data);
411
+ // console.log("onMessageCreated!", event_data);
412
412
  window.parent.postMessage(event_data.detail, '*')
413
413
  // if(event_data.detail.isLogged){
414
414
  // console.log("isLogged!!!!", event_data);
@@ -610,7 +610,7 @@
610
610
  TelegramShareUrl,
611
611
  '_blank'
612
612
  );
613
- }
613
+ }
614
614
 
615
615
  function shareOnWhatsapp() {
616
616
  var WhatsappShareUrl = "whatsapp://send?text=" + currentUrl;
@@ -640,6 +640,7 @@
640
640
  }else{
641
641
  window.Tiledesk(event);
642
642
  }
643
+ window.Tiledesk('setParameter', {key: 'poweredBy', value: ''})
643
644
  }
644
645
 
645
646
  function onClickSignInAnonymous(){
@@ -5,7 +5,6 @@ export class UploadModel {
5
5
  url: string;
6
6
  progress: number;
7
7
  createdAt: Date = new Date();
8
-
9
8
  constructor(file: File) {
10
9
  this.file = file;
11
10
  }
@@ -29,4 +29,7 @@ export abstract class UploadService {
29
29
  // functions
30
30
  abstract initialize(): void;
31
31
  abstract upload(userId: string, upload: UploadModel): Promise<any>;
32
+ abstract uploadProfile(userId: string, upload: UploadModel): Promise<any>;
33
+ abstract delete(userId: string, path: string): Promise<any>;
34
+ abstract deleteProfile(userId: string, path: string): Promise<any>
32
35
  }
@@ -131,8 +131,8 @@ export class FirebaseAuthService extends MessagingAuthService {
131
131
  break;
132
132
  }
133
133
  }
134
- return this.firebase.auth().setPersistence(firebasePersistence).then(async () => {
135
- return this.firebase.auth().signInWithCustomToken(token).then(async () => {
134
+ return that.firebase.auth().setPersistence(firebasePersistence).then(async () => {
135
+ return that.firebase.auth().signInWithCustomToken(token).then(async () => {
136
136
  // that.firebaseSignInWithCustomToken.next(response);
137
137
  }).catch((error) => {
138
138
  that.logger.error('[FIREBASEAuthSERVICE] signInFirebaseWithCustomToken Error: ', error);
@@ -181,7 +181,7 @@ export class FirebaseAuthService extends MessagingAuthService {
181
181
  */
182
182
  private signOut(): Promise<boolean> {
183
183
  const that = this;
184
- return new Promise((resolve, reject)=> {this.firebase.auth().signOut().then(() => {
184
+ return new Promise((resolve, reject)=> {that.firebase.auth().signOut().then(() => {
185
185
  that.logger.debug('[FIREBASEAuthSERVICE] firebase-sign-out');
186
186
  // cancello token
187
187
  // this.appStorage.removeItem('tiledeskToken');
@@ -478,7 +478,7 @@ export class FirebaseConversationsHandler extends ConversationsHandlerService {
478
478
  private changed(childSnapshot: any) {
479
479
  const oldConversation = this.conversations[searchIndexInArrayForUid(this.conversations, childSnapshot.key)]
480
480
  //skip info message updates
481
- if(messageType(MESSAGE_TYPE_INFO, oldConversation) ){
481
+ if(messageType(MESSAGE_TYPE_INFO, childSnapshot.val()) ){
482
482
  return;
483
483
  }
484
484
  if (this.conversationGenerate(childSnapshot)) {
@@ -39,6 +39,14 @@ export class FirebaseUploadService extends UploadService {
39
39
  this.firebase = firebase
40
40
 
41
41
  }
42
+
43
+ private createGuid() {
44
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
45
+ // tslint:disable-next-line:no-bitwise
46
+ const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
47
+ return v.toString(16);
48
+ });
49
+ }
42
50
 
43
51
  public upload(userId: string, upload: UploadModel): Promise<any> {
44
52
  const that = this;
@@ -97,12 +105,126 @@ export class FirebaseUploadService extends UploadService {
97
105
 
98
106
  }
99
107
 
100
- private createGuid() {
101
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
102
- // tslint:disable-next-line:no-bitwise
103
- const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
104
- return v.toString(16);
105
- });
108
+ public uploadProfile(userId: string, upload: UploadModel): Promise<any> {
109
+ const that = this;
110
+ const urlImagesNodeFirebase = '/profiles/' + userId + '/photo.jpg'
111
+ this.logger.debug('[FIREBASEUploadSERVICE] uploadProfile ', urlImagesNodeFirebase, upload.file);
112
+
113
+ // Create a root reference
114
+ const storageRef = this.firebase.storage().ref();
115
+ this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
116
+
117
+ // Create a reference to 'mountains.jpg'
118
+ const mountainsRef = storageRef.child(urlImagesNodeFirebase);
119
+ this.logger.debug('[FIREBASEUploadSERVICE] mountainsRef ', mountainsRef);
120
+
121
+ // const metadata = {};
122
+ const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
123
+
124
+ let uploadTask = mountainsRef.put(upload.file, metadata);
125
+
126
+ return new Promise((resolve, reject) => {
127
+ uploadTask.on('state_changed', function progress(snapshot) {
128
+ // Observe state change events such as progress, pause, and resume
129
+ // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
130
+ var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
131
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is ' + progress + '% done');
132
+
133
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
134
+ // BehaviorSubject publish the upload progress state - the subscriber is in ion-conversastion-detail.component.ts > listenToUploadFileProgress()
135
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
136
+
137
+ that.BSStateUpload.next({ upload: progress, type: upload.file.type });
138
+
139
+ switch (snapshot.state) {
140
+ case that.firebase.storage.TaskState.PAUSED: // or 'paused'
141
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is paused');
142
+
143
+ break;
144
+ case that.firebase.storage.TaskState.RUNNING: // or 'running'
145
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is running');
146
+
147
+ break;
148
+ }
149
+ }, function error(error) {
150
+ // Handle unsuccessful uploads
151
+ reject(error)
152
+ }, function complete() {
153
+ // Handle successful uploads on complete
154
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
155
+
156
+ resolve(uploadTask.snapshot.ref.getDownloadURL())
157
+ // that.BSStateUpload.next({upload: upload});
158
+
159
+ });
160
+ })
161
+
162
+ }
163
+
164
+ public async delete(userId: string, path: string): Promise<any>{
165
+ const that = this;
166
+ const file_name_photo = 'photo.jpg';
167
+ const file_name_thumb_photo = 'thumb_photo.jpg';
168
+
169
+ that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
170
+
171
+ let uid = path.split(userId)[1].split('%2F')[1]; // get the UID of the image
172
+ let imageName = path.split(uid + '%2F')[1].split('?')[0];
173
+
174
+ // Create a root reference
175
+ const storageRef = this.firebase.storage().ref();
176
+ const ref = storageRef.child('public/images/' + userId + '/'+ uid + '/')
177
+ let arrayPromise = []
178
+ await ref.listAll().then((dir => {
179
+ dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
180
+ })).catch(error => {
181
+ that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
182
+ })
183
+
184
+ //AWAIT to return ALL the promise delete()
185
+ return new Promise((resolve, reject)=> {
186
+ Promise.all(arrayPromise).then(()=>{
187
+ resolve(true)
188
+ }).catch((error)=>{
189
+ reject(error)
190
+ })
191
+ })
192
+ }
193
+
194
+ public async deleteProfile(userId: string, path: string): Promise<any>{
195
+ const that = this;
196
+ const file_name_photo = 'photo.jpg';
197
+ const file_name_thumb_photo = 'thumb_photo.jpg';
198
+
199
+ that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
200
+
201
+ // Create a root reference
202
+ const storageRef = this.firebase.storage().ref();
203
+ const ref = storageRef.child('profiles/' + userId + '/')
204
+ let arrayPromise = []
205
+ await ref.listAll().then((dir => {
206
+ dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
207
+ })).catch(error => {
208
+ that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
209
+ })
210
+
211
+ //AWAIT to return ALL the promise delete()
212
+ return new Promise((resolve, reject)=> {
213
+ Promise.all(arrayPromise).then(()=>{
214
+ resolve(true)
215
+ }).catch((error)=>{
216
+ reject(error)
217
+ })
218
+ })
219
+ }
220
+
221
+ // // ------------------------------------
222
+ // // Delete the file photo
223
+ // // ------------------------------------
224
+ private deleteFile(pathToFile, fileName){
225
+ const ref = this.firebase.storage().ref(pathToFile);
226
+ const childRef = ref.child(fileName);
227
+ return childRef.delete()
106
228
  }
107
229
 
108
230
  }
@@ -263,7 +263,7 @@ z
263
263
  this.logger.debug('[MQTTAuthService] connectMQTT: **** credentials:', credentials);
264
264
  const userid = credentials.userid;
265
265
  this.chat21Service.chatClient.connect(userid, credentials.token, () => {
266
- this.logger.debug('[MQTTAuthService] connectMQTT: Chat connected.');
266
+ this.logger.debug('[MQTTAuthService] connectMQTT: Chat connected');
267
267
  this.BSAuthStateChanged.next('online');
268
268
  });
269
269
  }
@@ -334,6 +334,11 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
334
334
  // this.logger.debug('[MQTTConversationsHandler] aggiorno key:' + k);
335
335
  conv.type = snap[k];
336
336
  }
337
+ if (k === 'conversation_with_fullname') {
338
+ // this.logger.debug('[MQTTConversationsHandler] aggiorno key:' + k);
339
+ conv.conversation_with_fullname = snap[k];
340
+ }
341
+ conv = this.completeConversation(conv)
337
342
 
338
343
  });
339
344
  }
@@ -77,4 +77,72 @@ export class NativeUploadService extends UploadService {
77
77
  }
78
78
 
79
79
  }
80
+
81
+ uploadProfile(userId: string, upload: UploadModel): Promise<any> {
82
+ this.logger.log('[NATIVE UPLOAD] - upload new photo profile ... upload', upload)
83
+ const headers = new HttpHeaders({
84
+ Authorization: this.tiledeskToken,
85
+ // 'Content-Type': 'multipart/form-data',
86
+ });
87
+ const requestOptions = { headers: headers };
88
+ const formData = new FormData();
89
+ formData.append('file', upload.file);
90
+
91
+ // USE IMAGE API
92
+ const that = this;
93
+ const url = this.URL_TILEDESK_IMAGES + `/users/photo?force=true&user_id=${userId}`
94
+ return new Promise((resolve, reject) => {
95
+ that.http.put(url, formData, requestOptions).subscribe(data => {
96
+ const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['thumbnail'];
97
+ resolve(downloadURL)
98
+ // that.BSStateUpload.next({upload: upload});
99
+ }, (error) => {
100
+ reject(error)
101
+ });
102
+ });
103
+ }
104
+
105
+ delete(userId: string, path: string): Promise<any>{
106
+ this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
107
+ const headers = new HttpHeaders({
108
+ Authorization: this.tiledeskToken,
109
+ //'Content-Type': 'multipart/form-data',
110
+ });
111
+ const requestOptions = { headers: headers };
112
+
113
+ //USE IMAGE API
114
+ const that = this;
115
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + path.split('path=')[1]
116
+ return new Promise((resolve, reject) => {
117
+ that.http.delete(url, requestOptions).subscribe(data => {
118
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
119
+ resolve(true)
120
+ // that.BSStateUpload.next({upload: upload});
121
+ }, (error) => {
122
+ reject(error)
123
+ });
124
+ });
125
+ }
126
+
127
+ deleteProfile(userId: string, path: string): Promise<any>{
128
+ this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
129
+ const headers = new HttpHeaders({
130
+ Authorization: this.tiledeskToken,
131
+ //'Content-Type': 'multipart/form-data',
132
+ });
133
+ const requestOptions = { headers: headers };
134
+
135
+ //USE IMAGE API
136
+ const that = this;
137
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
138
+ return new Promise((resolve, reject) => {
139
+ that.http.delete(url, requestOptions).subscribe(data => {
140
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
141
+ resolve(true)
142
+ // that.BSStateUpload.next({upload: upload});
143
+ }, (error) => {
144
+ reject(error)
145
+ });
146
+ });
147
+ }
80
148
  }
@@ -130,6 +130,7 @@ export class TiledeskAuthService {
130
130
  this.logger.debug('[TILEDESK-AUTH] logOut()');
131
131
  this.appStorage.removeItem('tiledeskToken');
132
132
  this.appStorage.removeItem('currentUser');
133
+ localStorage.removeItem('tiledesk_token')
133
134
  this.setCurrentUser(null);
134
135
  }
135
136
 
@@ -178,6 +179,8 @@ export class TiledeskAuthService {
178
179
  } else if (storedTiledeskToken && storedTiledeskToken === tiledeskToken) {
179
180
  this.logger.log('[TILEDESK-AUTH] - checkAndSetInStorageTiledeskToken STORED-TOKEN EXIST AND IS = TO TOKEN ')
180
181
  }
182
+
183
+ localStorage.setItem('tiledesk_token', tiledeskToken)
181
184
  }
182
185
 
183
186
 
@@ -114,4 +114,18 @@ export const LogLevel = {
114
114
  'WARN' : 1,
115
115
  'INFO' : 2,
116
116
  'DEBUG' : 3
117
- }
117
+ }
118
+
119
+ export enum PLAN_NAME {
120
+ A = 'Growth',
121
+ B = 'Scale',
122
+ C = 'Plus',
123
+ }
124
+
125
+ export enum TYPE_BUTTON {
126
+ TEXT = 'text',
127
+ URL = 'url',
128
+ ACTION = 'action'
129
+ }
130
+
131
+ export const tranlatedLanguage = ['it', 'en', 'de', 'es', 'pt', 'fr', 'ru', 'tr', 'sr', 'ar', 'uk', 'sv', 'az', 'kk', 'uz']
@@ -1,6 +1,5 @@
1
1
  import { DepartmentModel } from './../../models/department';
2
2
  import { Injectable, ElementRef } from '@angular/core';
3
- import { Globals } from '../../app/utils/globals';
4
3
  import { ConversationModel } from '../models/conversation';
5
4
  import { LoggerInstance } from '../providers/logger/loggerInstance';
6
5
  import { LoggerService } from '../providers/abstract/logger.service';
@@ -284,41 +284,6 @@ function convertUrlToTag(url) {
284
284
  //// <a href="#" onclick="openPopup(' + url + ')">' + url + '</a>';
285
285
  }
286
286
 
287
-
288
- export function isPopupUrl(url) {
289
- try {
290
- const TEMP = url.split('popup=')[1];
291
- // può essere seguito da & oppure "
292
- if (TEMP) {
293
- if (TEMP.startsWith('true')) {
294
- return true;
295
- } else {
296
- return false;
297
- }
298
- } else {
299
- return false;
300
- }
301
- } catch (e) {
302
- return false;
303
- }
304
- }
305
-
306
- export function popupUrl(windowContext, html, title) {
307
- const url = stripTags(html);
308
- const w = 600;
309
- const h = 600; // screen.height - 40;
310
- const left = (screen.width / 2) - (w / 2);
311
- const top = (screen.height / 2) - (h / 2);
312
-
313
- // tslint:disable-next-line:whitespace
314
- // tslint:disable-next-line:max-line-length
315
- const newWindow = windowContext.open(url, '_blank', 'fullscreen=1, titlebar=0, toolbar=no, location=0, status=0, menubar=0, scrollbars=0, resizable=0, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
316
- if (windowContext.focus) {
317
- newWindow.focus();
318
- }
319
- }
320
-
321
-
322
287
  export function encodeHTML(str) {
323
288
  return convert(str);
324
289
  // return str.replace(/[\u00A0-\u9999<>&](?!#)/gim, function(i) {
@@ -343,10 +308,6 @@ function convert(str) {
343
308
  return str;
344
309
  }
345
310
 
346
- export function stripTags(html) {
347
- return (html.replace(/<.*?>/g, '')).trim();
348
- }
349
-
350
311
  export function htmlEntities(str) {
351
312
  return String(str)
352
313
  .replace(/&/g, '&amp;')
package/src/launch.js CHANGED
@@ -35,7 +35,6 @@ function ready(callbackFunction){
35
35
  document.removeEventListener('mousedown', start);
36
36
  document.removeEventListener('mousemove', start);
37
37
  document.removeEventListener('touchstart', start);
38
- document.removeEventListener('scroll', start);
39
38
  document.removeEventListener('keydown', start);
40
39
  }
41
40