12
12
from django .utils import timezone
13
13
from django .utils .translation import gettext_lazy as _
14
14
from graphene_django .types import ErrorType
15
+ from rest_framework import serializers
15
16
16
17
from baseapp_chats .graphql .subscriptions import ChatRoomOnMessagesCountUpdate
17
18
from baseapp_chats .utils import send_message , send_new_chat_message_notification
18
19
19
20
ChatRoom = swapper .load_model ("baseapp_chats" , "ChatRoom" )
20
21
ChatRoomParticipant = swapper .load_model ("baseapp_chats" , "ChatRoomParticipant" )
22
+ ChatRoomParticipantRoles = ChatRoomParticipant .ChatRoomParticipantRoles
21
23
Message = swapper .load_model ("baseapp_chats" , "Message" )
22
24
MessageStatus = swapper .load_model ("baseapp_chats" , "MessageStatus" )
23
25
UnreadMessageCount = swapper .load_model ("baseapp_chats" , "UnreadMessageCount" )
32
34
ChatRoomParticipantObjectType = ChatRoomParticipant .get_graphql_object_type ()
33
35
34
36
37
+ class ImageSerializer (serializers .Serializer ):
38
+ image = serializers .ImageField (required = False , allow_null = True )
39
+
40
+
35
41
class ChatRoomCreate (RelayMutation ):
36
42
room = graphene .Field (ChatRoomObjectType ._meta .connection .Edge )
37
43
profile = graphene .Field (ProfileObjectType )
@@ -129,17 +135,32 @@ def mutate_and_get_payload(cls, root, info, profile_id, participants, is_group,
129
135
),
130
136
)
131
137
image = info .context .FILES .get ("image" , None )
138
+ serializer = ImageSerializer (data = {"image" : image })
139
+ if not serializer .is_valid ():
140
+ return ChatRoomCreate (
141
+ errors = [ErrorType (field = "image" , messages = serializer .errors ["image" ])]
142
+ )
143
+
132
144
room = ChatRoom .objects .create (
133
145
created_by = info .context .user ,
134
146
last_message_time = timezone .now (),
135
147
is_group = is_group ,
136
148
title = title ,
137
- image = image ,
149
+ image = serializer . validated_data [ " image" ] ,
138
150
)
139
151
140
152
created_participants = ChatRoomParticipant .objects .bulk_create (
141
153
[
142
- ChatRoomParticipant (profile = participant , room = room , accepted_at = timezone .now ())
154
+ ChatRoomParticipant (
155
+ profile = participant ,
156
+ room = room ,
157
+ role = (
158
+ ChatRoomParticipantRoles .ADMIN
159
+ if participant == profile
160
+ else ChatRoomParticipantRoles .MEMBER
161
+ ),
162
+ accepted_at = timezone .now (),
163
+ )
143
164
for participant in participants
144
165
]
145
166
)
@@ -155,6 +176,136 @@ def mutate_and_get_payload(cls, root, info, profile_id, participants, is_group,
155
176
)
156
177
157
178
179
+ class ChatRoomUpdate (RelayMutation ):
180
+ room = graphene .Field (ChatRoomObjectType ._meta .connection .Edge )
181
+
182
+ class Input :
183
+ room_id = graphene .ID (required = True )
184
+ profile_id = graphene .ID (required = True )
185
+ title = graphene .String (required = False )
186
+ delete_image = graphene .Boolean (default_value = False )
187
+ add_participants = graphene .List (graphene .ID , default_value = [])
188
+ remove_participants = graphene .List (graphene .ID , default_value = [])
189
+
190
+ @classmethod
191
+ @login_required
192
+ def mutate_and_get_payload (
193
+ cls ,
194
+ root ,
195
+ info ,
196
+ room_id ,
197
+ profile_id ,
198
+ delete_image ,
199
+ add_participants ,
200
+ remove_participants ,
201
+ ** input ,
202
+ ):
203
+ room = get_obj_from_relay_id (info , room_id )
204
+ profile = get_obj_from_relay_id (info , profile_id )
205
+
206
+ if not room or not getattr (room , "is_group" , False ):
207
+ return ChatRoomUpdate (
208
+ errors = [
209
+ ErrorType (
210
+ field = "room_id" ,
211
+ messages = [_ ("This room cannot be updated" )],
212
+ )
213
+ ]
214
+ )
215
+
216
+ if not info .context .user .has_perm ("baseapp_profiles.use_profile" , profile ):
217
+ return ChatRoomUpdate (
218
+ errors = [
219
+ ErrorType (
220
+ field = "profile_id" ,
221
+ messages = [_ ("You don't have permission to act as this profile" )],
222
+ )
223
+ ]
224
+ )
225
+
226
+ add_participants = [
227
+ get_obj_from_relay_id (info , participant ) for participant in add_participants
228
+ ]
229
+ add_participants = [
230
+ participant for participant in add_participants if participant is not None
231
+ ]
232
+ add_participants_ids = [participant .pk for participant in add_participants ]
233
+
234
+ remove_participants = [
235
+ get_obj_from_relay_id (info , participant ) for participant in remove_participants
236
+ ]
237
+ remove_participants = [
238
+ participant for participant in remove_participants if participant is not None
239
+ ]
240
+ remove_participants_ids = [participant .pk for participant in remove_participants ]
241
+
242
+ # Check if added participants are blocked
243
+ if Block .objects .filter (
244
+ Q (actor_id = profile .id , target_id__in = add_participants_ids )
245
+ | Q (actor_id__in = add_participants_ids , target_id = profile .id )
246
+ ).exists ():
247
+ return ChatRoomUpdate (
248
+ errors = [
249
+ ErrorType (
250
+ field = "add_participants" ,
251
+ messages = [_ ("You can't add those participants to a chatroom" )],
252
+ )
253
+ ]
254
+ )
255
+
256
+ if not info .context .user .has_perm (
257
+ "baseapp_chats.modify_chatroom" ,
258
+ {"profile" : profile , "room" : room , "add_participants" : add_participants },
259
+ ):
260
+ return ChatRoomUpdate (
261
+ errors = [
262
+ ErrorType (
263
+ field = "room_id" ,
264
+ messages = [_ ("You don't have permission to update this room" )],
265
+ )
266
+ ]
267
+ )
268
+
269
+ title = input .get ("title" , None )
270
+ if title is not None :
271
+ room .title = title
272
+
273
+ image = info .context .FILES .get ("image" , None )
274
+ serializer = ImageSerializer (data = {"image" : image })
275
+ if not serializer .is_valid ():
276
+ return ChatRoomUpdate (
277
+ errors = [ErrorType (field = "image" , messages = serializer .errors ["image" ])]
278
+ )
279
+
280
+ if image is not None :
281
+ room .image = serializer .validated_data ["image" ]
282
+ elif delete_image :
283
+ room .image = None
284
+
285
+ room .save ()
286
+
287
+ for participant in remove_participants_ids :
288
+ # TODO: Delete participant
289
+ # ChatRoomParticipant.objects.filter(
290
+ # profile_id=participant.pk, room=room
291
+ # ).delete()
292
+ pass
293
+
294
+ for participant in add_participants :
295
+ # TODO: Add participant
296
+ # ChatRoomParticipant.objects.create(
297
+ # profile=participant, room=room, accepted_at=timezone.now()
298
+ # )
299
+ # Subscriptions?
300
+ pass
301
+
302
+ return ChatRoomUpdate (
303
+ room = ChatRoomObjectType ._meta .connection .Edge (
304
+ node = room ,
305
+ ),
306
+ )
307
+
308
+
158
309
class ChatRoomSendMessage (RelayMutation ):
159
310
message = graphene .Field (MessageObjectType ._meta .connection .Edge )
160
311
@@ -417,6 +568,7 @@ def mutate_and_get_payload(cls, root, info, room_id, profile_id, archive, **inpu
417
568
418
569
class ChatsMutations (object ):
419
570
chat_room_create = ChatRoomCreate .Field ()
571
+ chat_room_update = ChatRoomUpdate .Field ()
420
572
chat_room_send_message = ChatRoomSendMessage .Field ()
421
573
chat_room_read_messages = ChatRoomReadMessages .Field ()
422
574
chat_room_unread = ChatRoomUnread .Field ()
0 commit comments