@chat21/chat21-ionic 3.0.59-rc1 → 3.0.59-rc10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +4 -0
- package/config.xml +11 -2
- package/env.sample +2 -0
- package/package.json +1 -1
- package/resources/Android/splash/drawable-land-hdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-ldpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-mdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-land-xxxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-hdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-ldpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-mdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xxhdpi-screen.png +0 -0
- package/resources/Android/splash/drawable-port-xxxhdpi-screen.png +0 -0
- package/resources/Android/splash.png +0 -0
- package/src/app/app-routing.module.ts +21 -17
- package/src/app/app.component.html +6 -3
- package/src/app/app.component.ts +242 -51
- package/src/app/app.module.ts +16 -8
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.html +4 -4
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.scss +8 -2
- package/src/app/chatlib/conversation-detail/ion-conversation-detail/ion-conversation-detail.component.ts +6 -1
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.html +1 -1
- package/src/app/chatlib/conversation-detail/message/bubble-message/bubble-message.component.ts +1 -1
- package/src/app/chatlib/conversation-detail/message/image/image.component.html +7 -6
- package/src/app/chatlib/conversation-detail/message/image/image.component.ts +20 -1
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.html +39 -9
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.scss +8 -144
- package/src/app/chatlib/list-conversations-component/ion-list-conversations/ion-list-conversations.component.ts +14 -17
- package/src/app/components/authentication/login/login.component.html +2 -2
- package/src/app/components/authentication/login/login.component.ts +2 -1
- package/src/app/components/conversation-detail/bubble-my-message/bubble-my-message.component.ts +1 -1
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.html +3 -2
- package/src/app/components/conversation-detail/header-conversation-detail/header-conversation-detail.component.ts +3 -3
- package/src/app/components/conversation-detail/message-text-area/message-text-area.component.ts +46 -5
- package/src/app/components/ddp-header/ddp-header.component.html +1 -1
- package/src/app/components/ddp-header/ddp-header.component.ts +4 -2
- package/src/app/components/image-viewer/image-viewer.component.html +23 -0
- package/src/app/components/image-viewer/image-viewer.component.scss +107 -0
- package/src/app/components/image-viewer/image-viewer.component.spec.ts +24 -0
- package/src/app/components/image-viewer/image-viewer.component.ts +38 -0
- package/src/app/components/project-item/project-item.component.html +147 -0
- package/src/app/components/project-item/project-item.component.scss +669 -0
- package/src/app/components/project-item/project-item.component.spec.ts +24 -0
- package/src/app/components/project-item/project-item.component.ts +316 -0
- package/src/app/components/utils/avatar-profile/avatar-profile.component.html +9 -3
- package/src/app/components/utils/avatar-profile/avatar-profile.component.ts +6 -4
- package/src/app/pages/authentication/login/login.page.ts +1 -1
- package/src/app/pages/conversation-detail/conversation-detail.page.html +5 -3
- package/src/app/pages/conversation-detail/conversation-detail.page.ts +122 -30
- package/src/app/pages/conversations-list/conversations-list.page.html +40 -24
- package/src/app/pages/conversations-list/conversations-list.page.scss +146 -1
- package/src/app/pages/conversations-list/conversations-list.page.ts +87 -6
- package/src/app/pages/unassigned-conversations/unassigned-conversations-routing.module.ts +17 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.module.ts +22 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.html +22 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.scss +79 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.spec.ts +24 -0
- package/src/app/pages/unassigned-conversations/unassigned-conversations.page.ts +108 -0
- package/src/app/services/nav-proxy.service.ts +1 -1
- package/src/app/services/tiledesk/tiledesk.service.ts +22 -1
- package/src/app/services/websocket/websocket-js.ts +559 -0
- package/src/app/services/websocket/websocket.service.spec.ts +12 -0
- package/src/app/services/websocket/websocket.service.ts +274 -0
- package/src/app/shared/shared.module.ts +7 -1
- package/src/assets/i18n/en.json +9 -1
- package/src/assets/i18n/it.json +9 -1
- package/src/assets/js/chat21client.js +141 -67
- package/src/assets/transparent.png +0 -0
- package/src/chat-config-pre-test.json +3 -1
- package/src/chat-config-template.json +3 -1
- package/src/chat-config.json +3 -1
- package/src/chat21-core/providers/chat-manager.ts +3 -3
- package/src/chat21-core/providers/firebase/firebase-archivedconversations-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-auth-service.ts +3 -3
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-notifications.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-presence.service.ts +2 -2
- package/src/chat21-core/providers/firebase/firebase-typing.service.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +1 -1
- package/src/chat21-core/providers/mqtt/mqtt-auth-service.ts +27 -27
- package/src/chat21-core/providers/mqtt/mqtt-conversations-handler.ts +13 -5
- package/src/chat21-core/providers/mqtt/mqtt-notifications.ts +101 -11
- package/src/chat21-core/providers/tiledesk/tiledesk-auth.service.ts +1 -1
- package/src/chat21-core/utils/utils.ts +1 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { Component, EventEmitter, HostListener, OnInit, Output } from '@angular/core';
|
|
2
|
+
import { WebsocketService } from 'src/app/services/websocket/websocket.service';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import { takeUntil } from 'rxjs/operators';
|
|
5
|
+
import { AppStorageService } from 'src/chat21-core/providers/abstract/app-storage.service';
|
|
6
|
+
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
7
|
+
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
8
|
+
import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
|
|
9
|
+
import { TiledeskAuthService } from 'src/chat21-core/providers/tiledesk/tiledesk-auth.service';
|
|
10
|
+
import { TiledeskService } from 'src/app/services/tiledesk/tiledesk.service';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'app-project-item',
|
|
14
|
+
templateUrl: './project-item.component.html',
|
|
15
|
+
styleUrls: ['./project-item.component.scss'],
|
|
16
|
+
})
|
|
17
|
+
export class ProjectItemComponent implements OnInit {
|
|
18
|
+
@Output() projectIdEvent = new EventEmitter<string>()
|
|
19
|
+
|
|
20
|
+
private unsubscribe$: Subject<any> = new Subject<any>();
|
|
21
|
+
project: any;
|
|
22
|
+
tiledeskToken: string;
|
|
23
|
+
|
|
24
|
+
unservedRequestCount: number = 0;
|
|
25
|
+
currentUserRequestCount: number;
|
|
26
|
+
ROLE_IS_AGENT: boolean;
|
|
27
|
+
currentUserId: string;
|
|
28
|
+
public translationMap: Map<string, string>;
|
|
29
|
+
private logger: LoggerService = LoggerInstance.getInstance();
|
|
30
|
+
window_width_is_60: boolean;
|
|
31
|
+
newInnerWidth: any;
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
public wsService: WebsocketService,
|
|
35
|
+
public appStorageService: AppStorageService,
|
|
36
|
+
private translateService: CustomTranslateService,
|
|
37
|
+
public tiledeskAuthService: TiledeskAuthService,
|
|
38
|
+
public tiledeskService: TiledeskService
|
|
39
|
+
) { }
|
|
40
|
+
|
|
41
|
+
ngOnInit() {
|
|
42
|
+
this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
|
|
43
|
+
this.getStoredToken();
|
|
44
|
+
this.getStoredCurrenUser();
|
|
45
|
+
this.translations();
|
|
46
|
+
this.listenToPostMsgs();
|
|
47
|
+
this.onInitWindowWidth();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
listenToPostMsgs() {
|
|
51
|
+
window.addEventListener("message", (event) => {
|
|
52
|
+
// console.log("[PROJECT-ITEM] post message event ", event);
|
|
53
|
+
|
|
54
|
+
if (event && event.data && event.data) {
|
|
55
|
+
// console.log("[APP-COMP] message event data ", event.data);
|
|
56
|
+
if (event.data === 'hasChangedProject') {
|
|
57
|
+
this.getLastProjectStoredAndSubscToWSAvailabilityAndConversations();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public translations() {
|
|
64
|
+
const keys = [
|
|
65
|
+
'Available',
|
|
66
|
+
'Unavailable',
|
|
67
|
+
'Busy'
|
|
68
|
+
];
|
|
69
|
+
this.translationMap = this.translateService.translateLanguage(keys);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@HostListener('window:resize', ['$event'])
|
|
73
|
+
onResize(event: any) {
|
|
74
|
+
this.newInnerWidth = event.target.innerWidth;
|
|
75
|
+
this.logger.log('[PROJECTS-X-PANEL] - INNER WIDTH ', this.newInnerWidth)
|
|
76
|
+
|
|
77
|
+
if (this.newInnerWidth <= 150) {
|
|
78
|
+
this.window_width_is_60 = true;
|
|
79
|
+
} else {
|
|
80
|
+
this.window_width_is_60 = false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
onInitWindowWidth(): any {
|
|
85
|
+
const actualWidth = window.innerWidth;
|
|
86
|
+
this.logger.log('[PROJECTS-X-PANEL] - ACTUAL Width ', actualWidth);
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
// if (actualWidth <= 60) {
|
|
90
|
+
if (actualWidth <= 150) {
|
|
91
|
+
this.window_width_is_60 = true;
|
|
92
|
+
} else {
|
|
93
|
+
this.window_width_is_60 = false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
getStoredToken() {
|
|
100
|
+
this.tiledeskToken = this.appStorageService.getItem('tiledeskToken');
|
|
101
|
+
this.logger.log('[PROJECT-ITEM] - STORED TILEDEK TOKEN ', this.tiledeskToken)
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
getStoredCurrenUser() {
|
|
106
|
+
const storedCurrentUser = this.appStorageService.getItem('currentUser');
|
|
107
|
+
this.logger.log('[PROJECT-ITEM] - STORED CURRENT USER ', storedCurrentUser)
|
|
108
|
+
if (storedCurrentUser) {
|
|
109
|
+
const currentUser = JSON.parse(storedCurrentUser)
|
|
110
|
+
this.logger.log('[PROJECT-ITEM] - STORED CURRENT USER OBJCT', currentUser);
|
|
111
|
+
this.currentUserId = currentUser.uid
|
|
112
|
+
this.logger.log('[PROJECT-ITEM] - CURRENT USER ID', this.currentUserId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
getLastProjectStoredAndSubscToWSAvailabilityAndConversations() {
|
|
117
|
+
let stored_project = ''
|
|
118
|
+
try {
|
|
119
|
+
stored_project = localStorage.getItem('last_project')
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.log('Get loacal storage item LAST PROJECT ', err)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
if (!stored_project) {
|
|
126
|
+
console.log('PROJECT-ITEM - THERE IS NOT STORED LAST PROJECT ', stored_project)
|
|
127
|
+
const tiledeskToken = this.appStorageService.getItem('tiledeskToken');
|
|
128
|
+
this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - tiledeskToken', tiledeskToken);
|
|
129
|
+
this.tiledeskService.getProjects(tiledeskToken).subscribe(projects => {
|
|
130
|
+
this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - RES', projects);
|
|
131
|
+
this.project = projects[0];
|
|
132
|
+
this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS - RES this.project', this.project);
|
|
133
|
+
|
|
134
|
+
localStorage.setItem('last_project', JSON.stringify(projects[0]))
|
|
135
|
+
this.doProjectSubscriptions(this.project)
|
|
136
|
+
|
|
137
|
+
}, (error) => {
|
|
138
|
+
this.logger.error('[INFO-CONTENT-COMP] - GET PROJECTS - ERROR ', error);
|
|
139
|
+
|
|
140
|
+
}, () => {
|
|
141
|
+
this.logger.log('[INFO-CONTENT-COMP] - GET PROJECTS * COMPLETE *');
|
|
142
|
+
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
if (stored_project) {
|
|
148
|
+
this.logger.log('PROJECT-ITEM - THERE IS STORED LAST PROJECT ', stored_project)
|
|
149
|
+
this.project = JSON.parse(stored_project)
|
|
150
|
+
this.doProjectSubscriptions(this.project)
|
|
151
|
+
this.logger.log('[PROJECT-ITEM] - LAST PROJECT PARSED ', this.project)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
doProjectSubscriptions(project) {
|
|
158
|
+
if (project) {
|
|
159
|
+
const user_role = this.project.role
|
|
160
|
+
this.logger.log('[PROJECT-ITEM] - user_role ', user_role)
|
|
161
|
+
this.projectIdEvent.emit(project.id_project._id)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
if (user_role === 'agent') {
|
|
165
|
+
this.ROLE_IS_AGENT = true;
|
|
166
|
+
|
|
167
|
+
} else {
|
|
168
|
+
this.ROLE_IS_AGENT = false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
this.logger.log('[PROJECT-ITEM] - LAST PROJECT PARSED > user_role ', user_role)
|
|
173
|
+
this.wsService.subscriptionToWsCurrentProjectUserAvailability(project.id_project._id, this.project._id);
|
|
174
|
+
this.listenTocurrentProjectUserUserAvailability$(project)
|
|
175
|
+
|
|
176
|
+
this.wsService.subscriptionToWsConversations(project.id_project._id)
|
|
177
|
+
// this.updateCurrentUserRequestCount();
|
|
178
|
+
this.updateUnservedRequestCount();
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
listenTocurrentProjectUserUserAvailability$(project) {
|
|
184
|
+
this.wsService.currentProjectUserAvailability$
|
|
185
|
+
.pipe(
|
|
186
|
+
takeUntil(this.unsubscribe$)
|
|
187
|
+
)
|
|
188
|
+
.subscribe((projectUser) => {
|
|
189
|
+
this.logger.log('[PROJECT-ITEM] - $UBSC TO WS USER AVAILABILITY & BUSY STATUS RES ', projectUser);
|
|
190
|
+
|
|
191
|
+
if (project.id_project._id === projectUser['id_project']) {
|
|
192
|
+
project['ws_projct_user_available'] = projectUser['user_available'];
|
|
193
|
+
project['ws_projct_user_isBusy'] = projectUser['isBusy']
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
}, (error) => {
|
|
197
|
+
this.logger.error('[PROJECT-ITEM] - $UBSC TO WS USER AVAILABILITY & BUSY STATUS error ', error);
|
|
198
|
+
}, () => {
|
|
199
|
+
this.logger.log('[PROJECT-ITEM] - $UBSC TO WS USER AVAILABILITY & BUSY STATUS * COMPLETE *');
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
changeAvailabilityState(projectid, available) {
|
|
204
|
+
this.logger.log('[PROJECT-ITEM] - changeAvailabilityState projectid', projectid, ' available: ', available);
|
|
205
|
+
|
|
206
|
+
available = !available
|
|
207
|
+
this.logger.log('[PROJECT-ITEM] - changeAvailabilityState projectid', projectid, ' available: ', available);
|
|
208
|
+
|
|
209
|
+
this.wsService.updateCurrentUserAvailability(this.tiledeskToken, projectid, available)
|
|
210
|
+
.subscribe((projectUser: any) => {
|
|
211
|
+
|
|
212
|
+
this.logger.log('[PROJECT-ITEM] - PROJECT-USER UPDATED ', projectUser)
|
|
213
|
+
|
|
214
|
+
// NOTIFY TO THE USER SERVICE WHEN THE AVAILABLE / UNAVAILABLE BUTTON IS CLICKED
|
|
215
|
+
// this.usersService.availability_btn_clicked(true)
|
|
216
|
+
|
|
217
|
+
if (this.project['id_project']._id === projectUser.id_project) {
|
|
218
|
+
this.project['ws_projct_user_available'] = projectUser.user_available;
|
|
219
|
+
// this.project['ws_projct_user_isBusy'] = projectUser['isBusy']
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
}, (error) => {
|
|
223
|
+
this.logger.error('[PROJECT-ITEM] - PROJECT-USER UPDATED - ERROR ', error);
|
|
224
|
+
|
|
225
|
+
}, () => {
|
|
226
|
+
this.logger.log('[PROJECT-ITEM] - PROJECT-USER UPDATED * COMPLETE *');
|
|
227
|
+
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
updateUnservedRequestCount() {
|
|
232
|
+
// this.requestsService.requestsList_bs.subscribe((requests) => {
|
|
233
|
+
this.wsService.wsRequestsList$
|
|
234
|
+
.pipe(
|
|
235
|
+
takeUntil(this.unsubscribe$)
|
|
236
|
+
)
|
|
237
|
+
.subscribe((requests) => {
|
|
238
|
+
|
|
239
|
+
if (requests) {
|
|
240
|
+
let count = 0;
|
|
241
|
+
requests.forEach(r => {
|
|
242
|
+
// this.logger.log('NAVBAR - UPDATE-UNSERVED-REQUEST-COUNT request agents', r.agents)
|
|
243
|
+
// *bug fix: when the user is an agent also for the unserved we have to consider if he is present in agents
|
|
244
|
+
if (r['status'] === 100 && this.ROLE_IS_AGENT === true) {
|
|
245
|
+
if (this.hasmeInAgents(r['agents']) === true) {
|
|
246
|
+
count = count + 1;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (r['status'] === 100 && this.ROLE_IS_AGENT === false) {
|
|
250
|
+
count = count + 1;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
this.unservedRequestCount = count;
|
|
254
|
+
this.logger.log('[PROJECT-ITEM] UNSERVED REQUEST COUNT - RES ', this.unservedRequestCount)
|
|
255
|
+
}
|
|
256
|
+
}, error => {
|
|
257
|
+
this.logger.error('[PROJECT-ITEM] UNSERVED REQUEST COUNT * error * ', error)
|
|
258
|
+
}, () => {
|
|
259
|
+
this.logger.log('[PROJECT-ITEM] UNSERVED REQUEST COUNT */* COMPLETE */*')
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
hasmeInAgents(agents) {
|
|
264
|
+
if (agents) {
|
|
265
|
+
for (let j = 0; j < agents.length; j++) {
|
|
266
|
+
this.logger.log('[PROJECT-ITEM] hasmeInAgents currentUserId ', this.currentUserId)
|
|
267
|
+
this.logger.log('[PROJECT-ITEM] hasmeInAgents agent ', agents[j].id_user)
|
|
268
|
+
if (this.currentUserId === agents[j].id_user) {
|
|
269
|
+
this.logger.log('[PROJECT-ITEM] hasmeInAgents ')
|
|
270
|
+
return true
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
this.logger.log('[PROJECT-ITEM] hasmeInAgents OOPS!!! AGENTS THERE ARE NOT ')
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
updateCurrentUserRequestCount() {
|
|
279
|
+
// this.requestsService.requestsList_bs.subscribe((requests) => {
|
|
280
|
+
this.wsService.wsRequestsList$
|
|
281
|
+
.pipe(
|
|
282
|
+
takeUntil(this.unsubscribe$)
|
|
283
|
+
)
|
|
284
|
+
.subscribe((requests) => {
|
|
285
|
+
if (requests) {
|
|
286
|
+
let count = 0;
|
|
287
|
+
requests.forEach(r => {
|
|
288
|
+
|
|
289
|
+
// const membersArray = Object.keys(r.members);
|
|
290
|
+
const participantsArray = r['participants'] // new used with ws
|
|
291
|
+
// this.logger.log('[NAVBAR] »» WIDGET updateCurrentUserRequestCount REQUEST currentUserRequestCount membersArray ', membersArray);
|
|
292
|
+
|
|
293
|
+
// const currentUserIsInParticipants = membersArray.includes(this.user._id);
|
|
294
|
+
const currentUserIsInParticipants = participantsArray.includes(this.currentUserId); // new used with ws
|
|
295
|
+
|
|
296
|
+
// this.logger.log('[NAVBAR] »» WIDGET updateCurrentUserRequestCount REQUEST currentUserRequestCount currentUserIsInParticipants ', currentUserIsInParticipants);
|
|
297
|
+
if (currentUserIsInParticipants === true) {
|
|
298
|
+
count = count + 1;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
this.currentUserRequestCount = count;
|
|
302
|
+
this.logger.log('[PROJECT-ITEM] CURRENT USER REQUEST COUNT - RES', this.currentUserRequestCount);
|
|
303
|
+
}
|
|
304
|
+
}, error => {
|
|
305
|
+
this.logger.error('[PROJECT-ITEM] CURRENT USER REQUEST COUNT * error * ', error)
|
|
306
|
+
}, () => {
|
|
307
|
+
this.logger.log('[PROJECT-ITEM] CURRENT USER REQUEST COUNT */* COMPLETE */*')
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
<div *ngIf="itemAvatar" class="avatar-circle" [style.width]="itemAvatar.width" [style.height]="itemAvatar.height">
|
|
2
|
-
|
|
1
|
+
<!-- <div *ngIf="itemAvatar" class="avatar-circle" [style.width]="itemAvatar.width" [style.height]="itemAvatar.height">
|
|
2
|
+
|
|
3
3
|
<div class="avatar avatar-placeholder" [ngStyle]="{'background': 'linear-gradient(rgb(255,255,255) -125%,' + color + ')'}" [innerHTML]="avatar" ></div>
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
<div *ngIf="avatarUrl" class="avatar avatar-image" [style.background-image]="'url(' + avatarUrl + ')'" ></div>
|
|
6
|
+
</div> -->
|
|
7
|
+
|
|
8
|
+
<div *ngIf="itemAvatar" class="avatar-circle" [style.width]="itemAvatar.width" [style.height]="itemAvatar.height">
|
|
9
|
+
<!-- [style.background-color]="itemAvatar.color" -->
|
|
10
|
+
<div class="avatar avatar-placeholder" [ngStyle]="{'background': 'linear-gradient(rgb(255,255,255) -125%,' + itemAvatar.color + ')'}" [innerHTML]="itemAvatar.avatar" ></div>
|
|
11
|
+
<div class="avatar avatar-image" [style.background-image]="'url(' + itemAvatar.imageurl + ')'" ></div>
|
|
6
12
|
</div>
|
|
@@ -16,14 +16,16 @@ export class AvatarProfileComponent implements OnInit, OnChanges {
|
|
|
16
16
|
private logger: LoggerService = LoggerInstance.getInstance();
|
|
17
17
|
constructor() {
|
|
18
18
|
this.logger.log('AvatarProfileComponent:::: constructor');
|
|
19
|
-
|
|
19
|
+
}
|
|
20
20
|
|
|
21
21
|
ngOnInit() {
|
|
22
22
|
this.logger.log('AvatarProfileComponent:::: ngOnInit');
|
|
23
23
|
// console.log('AvatarProfileComponent itemAvatar ',this.itemAvatar);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
if (this.itemAvatar) {
|
|
25
|
+
this.avatarUrl = this.itemAvatar.imageurl
|
|
26
|
+
this.avatar = this.itemAvatar.avatar
|
|
27
|
+
this.color = this.itemAvatar.color
|
|
28
|
+
}
|
|
27
29
|
// console.log('AvatarProfileComponent avatarUrl ',this.avatarUrl);
|
|
28
30
|
// console.log('AvatarProfileComponent avatar ',this.avatar);
|
|
29
31
|
// console.log('AvatarProfileComponent color ',this.color);
|
|
@@ -144,7 +144,7 @@ export class LoginPage implements OnInit {
|
|
|
144
144
|
this.presentToast(error_msg)
|
|
145
145
|
})
|
|
146
146
|
.finally(() => {
|
|
147
|
-
this.showSpinnerInLoginBtn = false;
|
|
147
|
+
// this.showSpinnerInLoginBtn = false;
|
|
148
148
|
this.logger.log('[LOGIN PAGE] signInWithEmailAndPassword ');
|
|
149
149
|
});
|
|
150
150
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
here is ignored
|
|
43
43
|
</span>
|
|
44
44
|
|
|
45
|
-
<div class="overlay" *ngIf="tagsCannedFilter.length > 0
|
|
45
|
+
<div class="overlay" *ngIf="tagsCannedFilter.length > 0 && HIDE_CANNED_RESPONSES === false"></div>
|
|
46
46
|
|
|
47
47
|
<ng-template #content_welcome>
|
|
48
48
|
<!-- <div class="messageFirst">
|
|
@@ -139,12 +139,13 @@
|
|
|
139
139
|
<!-- ----------------------------------------------------------- -->
|
|
140
140
|
<!-- Canned responses -->
|
|
141
141
|
<!-- ----------------------------------------------------------- -->
|
|
142
|
-
|
|
142
|
+
|
|
143
|
+
<div id="canned" *ngIf="tagsCannedFilter.length > 0 && HIDE_CANNED_RESPONSES === false">
|
|
143
144
|
<ion-list class="canned-list">
|
|
144
145
|
<ion-item button="true" [ngClass]="{'is_active_item': i == arrowkeyLocation}" lines="none"
|
|
145
146
|
class="canned-item" id="{{'canned-item_'+ i }}"
|
|
146
147
|
*ngFor="let canned of tagsCannedFilter; let i = index;" [innerHtml]="canned.title"
|
|
147
|
-
(click)="replaceTagInMessage(canned)">
|
|
148
|
+
(click)="replaceTagInMessage(canned, $event)">
|
|
148
149
|
</ion-item>
|
|
149
150
|
</ion-list>
|
|
150
151
|
</div>
|
|
@@ -153,6 +154,7 @@
|
|
|
153
154
|
<!-- openInfoConversation {{openInfoConversation}} - isMobile {{isMobile}} -->
|
|
154
155
|
<app-message-text-area
|
|
155
156
|
*ngIf="(openInfoConversation === false && isMobile === true) || (openInfoConversation === true && isMobile === false) || (openInfoConversation === false && isMobile === false)"
|
|
157
|
+
|
|
156
158
|
[loggedUser]="loggedUser"
|
|
157
159
|
[conversationWith]="conversationWith"
|
|
158
160
|
[tagsCannedFilter]="tagsCannedFilter"
|
|
@@ -40,6 +40,7 @@ import { Subject } from 'rxjs';
|
|
|
40
40
|
import { takeUntil } from 'rxjs/operators';
|
|
41
41
|
import { TiledeskService } from '../../services/tiledesk/tiledesk.service';
|
|
42
42
|
import { NetworkService } from '../../services/network-service/network.service';
|
|
43
|
+
import { EventsService } from '../../services/events-service';
|
|
43
44
|
|
|
44
45
|
@Component({
|
|
45
46
|
selector: 'app-conversation-detail',
|
|
@@ -51,6 +52,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
51
52
|
@ViewChild('ionContentChatArea', { static: false }) ionContentChatArea: IonContent;
|
|
52
53
|
@ViewChild('rowMessageTextArea', { static: false }) rowTextArea: ElementRef;
|
|
53
54
|
|
|
55
|
+
|
|
56
|
+
|
|
54
57
|
// @ViewChild('info_content', { static: false }) info_content_child : InfoContentComponent;
|
|
55
58
|
|
|
56
59
|
showButtonToBottom = false; // indica lo stato del pulsante per scrollare la chat (showed/hidden)
|
|
@@ -90,6 +93,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
90
93
|
|
|
91
94
|
public tagsCanned: any = [];
|
|
92
95
|
public tagsCannedFilter: any = [];
|
|
96
|
+
public HIDE_CANNED_RESPONSES: boolean = false;
|
|
97
|
+
|
|
93
98
|
|
|
94
99
|
public window: any = window;
|
|
95
100
|
public styleMap: Map<string, string> = new Map();
|
|
@@ -164,7 +169,8 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
164
169
|
public presenceService: PresenceService,
|
|
165
170
|
public toastController: ToastController,
|
|
166
171
|
public tiledeskService: TiledeskService,
|
|
167
|
-
private networkService: NetworkService
|
|
172
|
+
private networkService: NetworkService,
|
|
173
|
+
private events: EventsService
|
|
168
174
|
) {
|
|
169
175
|
|
|
170
176
|
// Change list on date change
|
|
@@ -533,23 +539,27 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
533
539
|
if (this.conversationWith && this.conversationsHandlerService && this.conv_type === 'active') {
|
|
534
540
|
this.logger.log('[CONVS-DETAIL] - setHeaderContent getConversationDetail CALLING')
|
|
535
541
|
this.conversationsHandlerService.getConversationDetail(this.conversationWith, (conv) => {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
+
if (conv) {
|
|
543
|
+
this.logger.log('[CONVS-DETAIL] - setHeaderContent getConversationDetail (active)', this.conversationWith, conv)
|
|
544
|
+
this.conversationAvatar = setConversationAvatar(
|
|
545
|
+
conv.conversation_with,
|
|
546
|
+
conv.conversation_with_fullname,
|
|
547
|
+
conv.channel_type
|
|
548
|
+
);
|
|
549
|
+
}
|
|
542
550
|
this.logger.log('[CONVS-DETAIL] - setHeaderContent > conversationAvatar: ', this.conversationAvatar);
|
|
543
551
|
})
|
|
544
552
|
}
|
|
545
553
|
else { //get conversation from 'conversations' firebase node
|
|
546
554
|
this.archivedConversationsHandlerService.getConversationDetail(this.conversationWith, (conv) => {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
555
|
+
if (conv) {
|
|
556
|
+
this.logger.log('[CONVS-DETAIL] - setHeaderContent getConversationDetail (archived)', this.conversationWith, conv)
|
|
557
|
+
this.conversationAvatar = setConversationAvatar(
|
|
558
|
+
conv.conversation_with,
|
|
559
|
+
conv.conversation_with_fullname,
|
|
560
|
+
conv.channel_type
|
|
561
|
+
);
|
|
562
|
+
}
|
|
553
563
|
})
|
|
554
564
|
}
|
|
555
565
|
|
|
@@ -628,23 +638,23 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
628
638
|
msg = `[${metadata.name}](${metadata.src})`
|
|
629
639
|
}
|
|
630
640
|
}
|
|
631
|
-
|
|
641
|
+
|
|
632
642
|
// else if (type === 'image') {
|
|
633
643
|
// if (msg) {
|
|
634
644
|
// // msg = msg + '<br>' + 'File: ' + metadata.src;
|
|
635
645
|
// msg = metadata.name + '\n' + msg
|
|
636
646
|
|
|
637
647
|
// } else {
|
|
638
|
-
|
|
648
|
+
|
|
639
649
|
// msg = metadata.name
|
|
640
650
|
// }
|
|
641
|
-
|
|
651
|
+
|
|
642
652
|
// }
|
|
643
|
-
|
|
653
|
+
|
|
644
654
|
|
|
645
655
|
(metadata) ? metadata = metadata : metadata = '';
|
|
646
656
|
this.logger.log('[CONVS-DETAIL] - SEND MESSAGE msg: ', msg, ' - messages: ', this.messages, ' - loggedUser: ', this.loggedUser);
|
|
647
|
-
|
|
657
|
+
|
|
648
658
|
if (msg && msg.trim() !== '' || type !== TYPE_MSG_TEXT) {
|
|
649
659
|
this.conversationHandlerService.sendMessage(
|
|
650
660
|
msg,
|
|
@@ -835,12 +845,12 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
835
845
|
|
|
836
846
|
logScrolling(event: any) {
|
|
837
847
|
// EVENTO IONIC-NATIVE: SCATTA SEMPRE, QUINDI DECIDO SE MOSTRARE O MENO IL BADGE
|
|
838
|
-
this.logger.log('[CONVS-DETAIL] logScrolling: ', event);
|
|
848
|
+
// this.logger.log('[CONVS-DETAIL] logScrolling: ', event);
|
|
839
849
|
this.detectBottom()
|
|
840
850
|
}
|
|
841
851
|
|
|
842
852
|
logScrollEnd(event: any) {
|
|
843
|
-
this.logger.log('[CONVS-DETAIL] logScrollEnd: ', event);
|
|
853
|
+
// this.logger.log('[CONVS-DETAIL] logScrollEnd: ', event);
|
|
844
854
|
}
|
|
845
855
|
|
|
846
856
|
|
|
@@ -882,17 +892,83 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
882
892
|
// ----------------------------------------------------------
|
|
883
893
|
setTimeout(() => {
|
|
884
894
|
if (this.conversationWith.startsWith("support-group")) {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
895
|
+
|
|
896
|
+
const pos = message.lastIndexOf("/");
|
|
897
|
+
// console.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses pos of / (using lastIndexOf) ", pos);
|
|
898
|
+
|
|
899
|
+
// test
|
|
900
|
+
// var rest = message.substring(0, message.lastIndexOf("/") + 1);
|
|
901
|
+
// var last = message.substring(message.lastIndexOf("/") + 1, message.length);
|
|
902
|
+
// console.log('[CONVS-DETAIL] - returnChangeTextArea rest', rest);
|
|
903
|
+
// console.log('[CONVS-DETAIL] - returnChangeTextArea last', last);
|
|
904
|
+
// console.log('[CONVS-DETAIL] - returnChangeTextArea last', last.length);
|
|
905
|
+
// if (last.length === 1 && last.trim() === '') {
|
|
906
|
+
// console.log('[CONVS-DETAIL] - returnChangeTextArea last is a white space ');
|
|
907
|
+
// } else if (last.length === 1 && last.trim() !== '') {
|
|
908
|
+
// console.log('[CONVS-DETAIL] - returnChangeTextArea last is NOT space ');
|
|
909
|
+
// }
|
|
910
|
+
|
|
888
911
|
|
|
889
912
|
if (pos >= 0) {
|
|
890
|
-
// if (pos === 0) {
|
|
891
|
-
// && that.tagsCanned.length > 0
|
|
892
913
|
var strSearch = message.substr(pos + 1);
|
|
893
914
|
this.logger.log("[CONVS-DETAIL] - returnChangeTextArea - canned responses strSearch ", strSearch);
|
|
915
|
+
|
|
916
|
+
// --------------------------------------------
|
|
917
|
+
// Load canned responses
|
|
918
|
+
// --------------------------------------------
|
|
894
919
|
this.loadTagsCanned(strSearch, this.conversationWith);
|
|
895
920
|
|
|
921
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------
|
|
922
|
+
// Hide / display Canned when the SLASH has POSITION POS 0 and checking if there is a space after the SLASH (in this case it will be hidden)
|
|
923
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------
|
|
924
|
+
|
|
925
|
+
var after_slash = message.substring(message.lastIndexOf("/") + 1, message.length);
|
|
926
|
+
if (pos === 0 && after_slash.length === 1 && after_slash.trim() === '') {
|
|
927
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is a white space after ');
|
|
928
|
+
this.HIDE_CANNED_RESPONSES = true
|
|
929
|
+
this.tagsCannedFilter = []
|
|
930
|
+
} else if (pos === 0 && after_slash.length === 0) {
|
|
931
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea after_slash --> there is NOT a white space after');
|
|
932
|
+
this.HIDE_CANNED_RESPONSES = false
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
if (pos > 0) {
|
|
937
|
+
|
|
938
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------
|
|
939
|
+
// Hide / display Canned when the SLASH has POSITION POS > and checking if there is a space after the SLASH (in this case they it be hidden)
|
|
940
|
+
// and if there is not a space before the SLASH (in this it will be hidden)
|
|
941
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------
|
|
942
|
+
|
|
943
|
+
let beforeSlash = message.substr(pos - 1)
|
|
944
|
+
let afterSlash = message.substr(pos + 1)
|
|
945
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea * POS ', pos);
|
|
946
|
+
|
|
947
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash', beforeSlash);
|
|
948
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash', afterSlash);
|
|
949
|
+
var afterSlashParts = afterSlash.split("/")
|
|
950
|
+
var beforeSlashParts = beforeSlash.split("/")
|
|
951
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> afterSlash parts', afterSlashParts);
|
|
952
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash parts', beforeSlashParts);
|
|
953
|
+
|
|
954
|
+
if (beforeSlashParts.length === 2) {
|
|
955
|
+
if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === '') {
|
|
956
|
+
this.HIDE_CANNED_RESPONSES = false
|
|
957
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash there is a white space After Not');
|
|
958
|
+
// if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0].indexOf(' ') >= 0)
|
|
959
|
+
} else if (beforeSlashParts[0].indexOf(' ') < 0 && afterSlashParts[0] === '') {
|
|
960
|
+
this.HIDE_CANNED_RESPONSES = true;
|
|
961
|
+
this.tagsCannedFilter = []
|
|
962
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After Not');
|
|
963
|
+
} else if (beforeSlashParts[0].indexOf(' ') >= 0 && afterSlashParts[0] === ' ') {
|
|
964
|
+
this.logger.log('[CONVS-DETAIL] - returnChangeTextArea --> beforeSlash not thete is a white space After YES');
|
|
965
|
+
this.HIDE_CANNED_RESPONSES = true;
|
|
966
|
+
this.tagsCannedFilter = []
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
|
|
896
972
|
} else {
|
|
897
973
|
this.tagsCannedFilter = [];
|
|
898
974
|
}
|
|
@@ -974,7 +1050,10 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
974
1050
|
this.logger.log('[CONVS-DETAIL] - loadTagsCanned getCannedResponses RES', res);
|
|
975
1051
|
|
|
976
1052
|
this.tagsCanned = res
|
|
977
|
-
|
|
1053
|
+
|
|
1054
|
+
if (this.HIDE_CANNED_RESPONSES === false) {
|
|
1055
|
+
this.showTagsCanned(strSearch);
|
|
1056
|
+
}
|
|
978
1057
|
|
|
979
1058
|
}, (error) => {
|
|
980
1059
|
this.logger.error('[CONVS-DETAIL] - loadTagsCanned getCannedResponses - ERROR ', error);
|
|
@@ -1030,12 +1109,20 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
1030
1109
|
return str;
|
|
1031
1110
|
}
|
|
1032
1111
|
|
|
1033
|
-
replaceTagInMessage(canned) {
|
|
1112
|
+
replaceTagInMessage(canned, event) {
|
|
1113
|
+
this.logger.log("[CONVS-DETAIL] replaceTagInMessage event ", event);
|
|
1034
1114
|
const elTextArea = this.rowTextArea['el'];
|
|
1035
1115
|
const textArea = elTextArea.getElementsByTagName('ion-textarea')[0];
|
|
1116
|
+
|
|
1036
1117
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage textArea ", textArea);
|
|
1037
1118
|
this.logger.log("[CONVS-DETAIL] replaceTagInMessage textArea value", textArea.value)
|
|
1038
1119
|
|
|
1120
|
+
// var lastChar = textArea.value.substr(-1); // Selects the last character
|
|
1121
|
+
// if (lastChar === '/') {
|
|
1122
|
+
// textArea.value = textArea.value.substring(0, textArea.value.length() - 1);
|
|
1123
|
+
// }
|
|
1124
|
+
// this.insertAtCursor(this.textArea, textArea.value)
|
|
1125
|
+
|
|
1039
1126
|
|
|
1040
1127
|
this.arrowkeyLocation = -1
|
|
1041
1128
|
this.tagsCannedFilter = [];
|
|
@@ -1051,12 +1138,14 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
1051
1138
|
|
|
1052
1139
|
var strTEMP = textArea.value.replace(strSearch, canned.text);
|
|
1053
1140
|
strTEMP = this.replacePlaceholderInCanned(strTEMP);
|
|
1141
|
+
this.logger.log("[CONVS-DETAIL] replaceTagInMessage strSearch ", strTEMP);
|
|
1054
1142
|
// strTEMP = this.replacePlaceholderInCanned(strTEMP);
|
|
1055
1143
|
// textArea.value = '';
|
|
1056
1144
|
// that.messageString = strTEMP;
|
|
1057
1145
|
textArea.value = strTEMP;
|
|
1058
1146
|
setTimeout(() => {
|
|
1059
|
-
textArea.focus();
|
|
1147
|
+
// textArea.focus();
|
|
1148
|
+
textArea.setFocus();
|
|
1060
1149
|
this.resizeTextArea();
|
|
1061
1150
|
}, 200);
|
|
1062
1151
|
}
|
|
@@ -1088,9 +1177,12 @@ export class ConversationDetailPage implements OnInit, OnDestroy, AfterViewInit
|
|
|
1088
1177
|
|
|
1089
1178
|
if (event.key === 'Enter') {
|
|
1090
1179
|
const canned_selected = this.tagsCannedFilter[this.arrowkeyLocation]
|
|
1091
|
-
|
|
1180
|
+
this.logger.log('[CONVS-DETAIL] replaceTagInMessage canned_selected ', canned_selected)
|
|
1092
1181
|
if (canned_selected) {
|
|
1093
|
-
|
|
1182
|
+
|
|
1183
|
+
this.replaceTagInMessage(canned_selected, 'enter')
|
|
1184
|
+
// event.preventDefault();
|
|
1185
|
+
// return false;
|
|
1094
1186
|
}
|
|
1095
1187
|
}
|
|
1096
1188
|
}
|