Skip to content

Commit 1df610c

Browse files
authored
🎨 [Frontend] Support Conversations: Listen to websocket (#8276)
1 parent 6953507 commit 1df610c

File tree

9 files changed

+158
-71
lines changed

9 files changed

+158
-71
lines changed

services/static-webserver/client/source/class/osparc/data/model/Conversation.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,22 @@ qx.Class.define("osparc.data.model.Conversation", {
4040
});
4141

4242
this.__messages = [];
43-
this.__fetchLastMessage();
43+
this.__listenToConversationMessageWS();
44+
45+
if (conversationData.type === "SUPPORT") {
46+
this.__fetchLastMessage();
47+
}
48+
},
49+
50+
statics: {
51+
CHANNELS: {
52+
CONVERSATION_CREATED: "conversation:created",
53+
CONVERSATION_UPDATED: "conversation:updated",
54+
CONVERSATION_DELETED: "conversation:deleted",
55+
CONVERSATION_MESSAGE_CREATED: "conversation:message:created",
56+
CONVERSATION_MESSAGE_UPDATED: "conversation:message:updated",
57+
CONVERSATION_MESSAGE_DELETED: "conversation:message:deleted",
58+
},
4459
},
4560

4661
properties: {
@@ -121,6 +136,12 @@ qx.Class.define("osparc.data.model.Conversation", {
121136
},
122137
},
123138

139+
events: {
140+
"messageAdded": "qx.event.type.Data",
141+
"messageUpdated": "qx.event.type.Data",
142+
"messageDeleted": "qx.event.type.Data",
143+
},
144+
124145
members: {
125146
__fetchLastMessagePromise: null,
126147
__nextRequestParams: null,
@@ -139,6 +160,35 @@ qx.Class.define("osparc.data.model.Conversation", {
139160
}
140161
},
141162

163+
__listenToConversationMessageWS: function() {
164+
const socket = osparc.wrapper.WebSocket.getInstance();
165+
[
166+
this.self().CHANNELS.CONVERSATION_MESSAGE_CREATED,
167+
this.self().CHANNELS.CONVERSATION_MESSAGE_UPDATED,
168+
this.self().CHANNELS.CONVERSATION_MESSAGE_DELETED,
169+
].forEach(eventName => {
170+
const eventHandler = message => {
171+
if (message) {
172+
const conversationId = message["conversationId"];
173+
if (conversationId === this.getConversationId()) {
174+
switch (eventName) {
175+
case this.self().CHANNELS.CONVERSATION_MESSAGE_CREATED:
176+
this.addMessage(message);
177+
break;
178+
case this.self().CHANNELS.CONVERSATION_MESSAGE_UPDATED:
179+
this.updateMessage(message);
180+
break;
181+
case this.self().CHANNELS.CONVERSATION_MESSAGE_DELETED:
182+
this.deleteMessage(message);
183+
break;
184+
}
185+
}
186+
}
187+
};
188+
socket.on(eventName, eventHandler, this);
189+
});
190+
},
191+
142192
__fetchLastMessage: function() {
143193
if (this.__fetchLastMessagePromise) {
144194
return this.__fetchLastMessagePromise;
@@ -201,13 +251,34 @@ qx.Class.define("osparc.data.model.Conversation", {
201251
const found = this.__messages.find(msg => msg["messageId"] === message["messageId"]);
202252
if (!found) {
203253
this.__messages.push(message);
254+
this.fireDataEvent("messageAdded", message);
204255
}
205256
// latest first
206257
this.__messages.sort((a, b) => new Date(b.created) - new Date(a.created));
207258
this.setLastMessage(this.__messages[0]);
208259
}
209260
},
210261

262+
updateMessage: function(message) {
263+
if (message) {
264+
const found = this.__messages.find(msg => msg["messageId"] === message["messageId"]);
265+
if (found) {
266+
Object.assign(found, message);
267+
this.fireDataEvent("messageUpdated", found);
268+
}
269+
}
270+
},
271+
272+
deleteMessage: function(message) {
273+
if (message) {
274+
const found = this.__messages.find(msg => msg["messageId"] === message["messageId"]);
275+
if (found) {
276+
this.__messages.splice(this.__messages.indexOf(found), 1);
277+
this.fireDataEvent("messageDeleted", found);
278+
}
279+
}
280+
},
281+
211282
getContextProjectId: function() {
212283
if (this.getExtraContext() && "projectId" in this.getExtraContext()) {
213284
return this.getExtraContext()["projectId"];

services/static-webserver/client/source/class/osparc/info/StudyLarge.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ qx.Class.define("osparc.info.StudyLarge", {
6060
if (
6161
this.__canIWrite() &&
6262
this.getStudy().getTemplateType() &&
63-
osparc.data.Permissions.getInstance().isTester()
63+
osparc.data.Permissions.getInstance().isProductOwner()
6464
) {
65-
// let testers change the template type
65+
// let product owners change the template type
6666
const hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({
6767
alignY: "middle",
6868
}));

services/static-webserver/client/source/class/osparc/product/Utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ qx.Class.define("osparc.product.Utils", {
289289
},
290290

291291
showTemplates: function() {
292-
if (osparc.data.Permissions.getInstance().isTester()) {
292+
if (osparc.data.Permissions.getInstance().isProductOwner()) {
293293
return true;
294294
}
295295

@@ -300,7 +300,7 @@ qx.Class.define("osparc.product.Utils", {
300300
},
301301

302302
showPublicProjects: function() {
303-
if (osparc.data.Permissions.getInstance().isTester()) {
303+
if (osparc.data.Permissions.getInstance().isProductOwner()) {
304304
return true;
305305
}
306306

services/static-webserver/client/source/class/osparc/store/ConversationsSupport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ qx.Class.define("osparc.store.ConversationsSupport", {
3737
},
3838

3939
members: {
40-
getConversations: function() {
40+
fetchConversations: function() {
4141
const params = {
4242
url: {
4343
offset: 0,

services/static-webserver/client/source/class/osparc/study/Conversation.js

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ qx.Class.define("osparc.study.Conversation", {
2121

2222
/**
2323
* @param studyData {String} Study Data
24-
* @param conversationId {String} Conversation Id
24+
* @param conversationData {Object} Conversation Data
2525
*/
26-
construct: function(studyData, conversationId) {
26+
construct: function(studyData, conversationData) {
2727
this.base(arguments);
2828

2929
this.__studyData = studyData;
3030
this.__messages = [];
3131

32-
if (conversationId) {
33-
this.setConversationId(conversationId);
32+
if (conversationData) {
33+
const conversation = new osparc.data.model.Conversation(conversationData);
34+
this.setConversation(conversation);
3435
}
3536

3637
this._setLayout(new qx.ui.layout.VBox(5));
@@ -51,11 +52,12 @@ qx.Class.define("osparc.study.Conversation", {
5152
},
5253

5354
properties: {
54-
conversationId: {
55-
check: "String",
55+
conversation: {
56+
check: "osparc.data.model.Conversation",
5657
init: null,
5758
nullable: false,
58-
event: "changeConversationId"
59+
event: "changeConversation",
60+
apply: "__applyConversation",
5961
},
6062
},
6163

@@ -68,6 +70,28 @@ qx.Class.define("osparc.study.Conversation", {
6870
__messagesList: null,
6971
__loadMoreMessages: null,
7072

73+
__applyConversation: function(conversation) {
74+
conversation.addListener("messageAdded", e => {
75+
const message = e.getData();
76+
this.addMessage(message);
77+
}, this);
78+
conversation.addListener("messageUpdated", e => {
79+
const message = e.getData();
80+
this.updateMessage(message);
81+
}, this);
82+
conversation.addListener("messageDeleted", e => {
83+
const message = e.getData();
84+
this.deleteMessage(message);
85+
}, this);
86+
},
87+
88+
getConversationId: function() {
89+
if (this.getConversation()) {
90+
return this.getConversation().getConversationId();
91+
}
92+
return null;
93+
},
94+
7195
__addConversationButtons: function() {
7296
const tabButton = this.getChildControl("button");
7397

@@ -93,7 +117,8 @@ qx.Class.define("osparc.study.Conversation", {
93117
// create new conversation first
94118
osparc.store.ConversationsProject.getInstance().postConversation(this.__studyData["uuid"], newLabel)
95119
.then(data => {
96-
this.setConversationId(data["conversationId"]);
120+
const conversation = new osparc.data.model.Conversation(data);
121+
this.setConversation(conversation);
97122
this.getChildControl("button").setLabel(newLabel);
98123
});
99124
}
@@ -135,7 +160,7 @@ qx.Class.define("osparc.study.Conversation", {
135160
row: 0,
136161
column: 4
137162
});
138-
this.bind("conversationId", closeButton, "visibility", {
163+
this.bind("conversation", closeButton, "visibility", {
139164
converter: value => value ? "visible" : "excluded"
140165
});
141166
},
@@ -174,8 +199,14 @@ qx.Class.define("osparc.study.Conversation", {
174199
});
175200
addMessages.addListener("messageAdded", e => {
176201
const data = e.getData();
177-
if (data["conversationId"]) {
178-
this.setConversationId(data["conversationId"]);
202+
if (data["conversationId"] && this.getConversation() === null) {
203+
osparc.store.ConversationsProject.getInstance().getConversation(this.__studyData["uuid"], data["conversationId"])
204+
.then(conversationData => {
205+
const conversation = new osparc.data.model.Conversation(conversationData);
206+
this.setConversation(conversation);
207+
});
208+
} else {
209+
this.getConversation().addMessage(data);
179210
this.addMessage(data);
180211
}
181212
});

services/static-webserver/client/source/class/osparc/study/Conversations.js

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ qx.Class.define("osparc.study.Conversations", {
4747
},
4848

4949
statics: {
50-
CHANNELS: {
51-
CONVERSATION_CREATED: "conversation:created",
52-
CONVERSATION_UPDATED: "conversation:updated",
53-
CONVERSATION_DELETED: "conversation:deleted",
54-
CONVERSATION_MESSAGE_CREATED: "conversation:message:created",
55-
CONVERSATION_MESSAGE_UPDATED: "conversation:message:updated",
56-
CONVERSATION_MESSAGE_DELETED: "conversation:message:deleted",
57-
},
58-
5950
popUpInWindow: function(studyData, openConversationId = null) {
6051
const conversations = new osparc.study.Conversations(studyData, openConversationId);
6152
const title = qx.locale.Manager.tr("Conversations");
@@ -72,7 +63,7 @@ qx.Class.define("osparc.study.Conversations", {
7263

7364
makeButtonBlink: function(button) {
7465
const socket = osparc.wrapper.WebSocket.getInstance();
75-
Object.values(osparc.study.Conversations.CHANNELS).forEach(eventName => {
66+
Object.values(osparc.data.model.Conversation.CHANNELS).forEach(eventName => {
7667
socket.on(eventName, () => {
7768
if (button) {
7869
osparc.utils.Utils.makeButtonBlink(button);
@@ -112,22 +103,22 @@ qx.Class.define("osparc.study.Conversations", {
112103
const socket = osparc.wrapper.WebSocket.getInstance();
113104

114105
[
115-
this.self().CHANNELS.CONVERSATION_CREATED,
116-
this.self().CHANNELS.CONVERSATION_UPDATED,
117-
this.self().CHANNELS.CONVERSATION_DELETED,
106+
osparc.data.model.Conversation.CHANNELS.CONVERSATION_CREATED,
107+
osparc.data.model.Conversation.CHANNELS.CONVERSATION_UPDATED,
108+
osparc.data.model.Conversation.CHANNELS.CONVERSATION_DELETED,
118109
].forEach(eventName => {
119110
const eventHandler = conversation => {
120111
if (conversation) {
121112
switch (eventName) {
122-
case this.self().CHANNELS.CONVERSATION_CREATED:
113+
case osparc.data.model.Conversation.CHANNELS.CONVERSATION_CREATED:
123114
if (conversation["projectId"] === this.getStudyData()["uuid"]) {
124115
this.__addConversationPage(conversation);
125116
}
126117
break;
127-
case this.self().CHANNELS.CONVERSATION_UPDATED:
118+
case osparc.data.model.Conversation.CHANNELS.CONVERSATION_UPDATED:
128119
this.__updateConversationName(conversation);
129120
break;
130-
case this.self().CHANNELS.CONVERSATION_DELETED:
121+
case osparc.data.model.Conversation.CHANNELS.CONVERSATION_DELETED:
131122
this.__removeConversationPage(conversation["conversationId"]);
132123
break;
133124
}
@@ -136,38 +127,10 @@ qx.Class.define("osparc.study.Conversations", {
136127
socket.on(eventName, eventHandler, this);
137128
this.__wsHandlers.push({ eventName, handler: eventHandler });
138129
});
139-
140-
[
141-
this.self().CHANNELS.CONVERSATION_MESSAGE_CREATED,
142-
this.self().CHANNELS.CONVERSATION_MESSAGE_UPDATED,
143-
this.self().CHANNELS.CONVERSATION_MESSAGE_DELETED,
144-
].forEach(eventName => {
145-
const eventHandler = message => {
146-
if (message) {
147-
const conversationId = message["conversationId"];
148-
const conversationPage = this.__getConversationPage(conversationId);
149-
if (conversationPage) {
150-
switch (eventName) {
151-
case this.self().CHANNELS.CONVERSATION_MESSAGE_CREATED:
152-
conversationPage.addMessage(message);
153-
break;
154-
case this.self().CHANNELS.CONVERSATION_MESSAGE_UPDATED:
155-
conversationPage.updateMessage(message);
156-
break;
157-
case this.self().CHANNELS.CONVERSATION_MESSAGE_DELETED:
158-
conversationPage.deleteMessage(message);
159-
break;
160-
}
161-
}
162-
}
163-
};
164-
socket.on(eventName, eventHandler, this);
165-
this.__wsHandlers.push({ eventName, handler: eventHandler });
166-
});
167130
},
168131

169132
__getConversationPage: function(conversationId) {
170-
return this.__conversationsPages.find(conversation => conversation.getConversationId() === conversationId);
133+
return this.__conversationsPages.find(conversationPage => conversationPage.getConversationId() === conversationId);
171134
},
172135

173136
__applyStudyData: function(studyData) {
@@ -200,9 +163,9 @@ qx.Class.define("osparc.study.Conversations", {
200163
const studyData = this.getStudyData();
201164
let conversationPage = null;
202165
if (conversationData) {
203-
const conversationId = conversationData["conversationId"];
204-
conversationPage = new osparc.study.Conversation(studyData, conversationId);
166+
conversationPage = new osparc.study.Conversation(studyData, conversationData);
205167
conversationPage.setLabel(conversationData["name"]);
168+
const conversationId = conversationData["conversationId"];
206169
osparc.store.ConversationsProject.getInstance().addListener("conversationDeleted", e => {
207170
const data = e.getData();
208171
if (conversationId === data["conversationId"]) {

services/static-webserver/client/source/class/osparc/study/SaveAsTemplate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ qx.Class.define("osparc.study.SaveAsTemplate", {
6767
});
6868
form.add(publishWithData, this.tr("Publish with data"), null, "publishWithData");
6969

70-
if (osparc.data.Permissions.getInstance().isTester()) {
70+
if (osparc.data.Permissions.getInstance().isProductOwner()) {
7171
const templateTypeSB = osparc.study.Utils.createTemplateTypeSB();
7272
form.add(templateTypeSB, this.tr("Template Type"), null, "templateType");
7373
}

0 commit comments

Comments
 (0)