From 5b4cc95e8780d0d1221fe689b97f11f327a092c8 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Wed, 13 Apr 2022 14:43:22 +0300 Subject: [PATCH] track unread/read message status --- inbox_resolvers/inbox.py | 54 +++++++++++++++++++++++++++++++++++++++- inbox_schema.graphql | 2 ++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/inbox_resolvers/inbox.py b/inbox_resolvers/inbox.py index 30e3549b..b4b19447 100644 --- a/inbox_resolvers/inbox.py +++ b/inbox_resolvers/inbox.py @@ -42,6 +42,22 @@ class MessageResult: self.status = status self.message = message +async def add_user_to_chat(user_slug, chat_id, chat = None): + chats = await redis.execute("GET", f"chats_by_user/{user_slug}") + if not chats: + chats = set() + else: + chats = set(json.loads(chats)) + chats.add(str(chat_id)) + chats = list(chats) + await redis.execute("SET", f"chats_by_user/{user_slug}", json.dumps(chats)) + + if chat: + users = set(chat["users"]) + users.add(user_slug) + chat["users"] = list(users) + await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat)) + @mutation.field("createChat") @login_required async def create_chat(_, info, description): @@ -52,12 +68,15 @@ async def create_chat(_, info, description): "description" : description, "createdAt" : str(datetime.now), "createdBy" : user.slug, - "id" : str(chat_id) + "id" : str(chat_id), + "users" : [user.slug] } await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat)) await redis.execute("SET", f"chats/{chat_id}/next_message_id", 0) + await add_user_to_chat(user.slug, chat_id) + return { "chatId" : chat_id } async def load_messages(chatId, size, page): @@ -73,6 +92,8 @@ async def load_messages(chatId, size, page): @query.field("enterChat") @login_required async def enter_chat(_, info, chatId, size): + user = info.context["request"].user + chat = await redis.execute("GET", f"chats/{chatId}") if not chat: return { "error" : "chat not exist" } @@ -80,6 +101,8 @@ async def enter_chat(_, info, chatId, size): messages = await load_messages(chatId, size, 1) + await add_user_to_chat(user.slug, chatId, chat) + return { "chat" : chat, "messages" : messages @@ -110,6 +133,11 @@ async def create_message(_, info, chatId, body, replyTo = None): await redis.execute("LPUSH", f"chats/{chatId}/message_ids", str(message_id)) await redis.execute("SET", f"chats/{chatId}/next_message_id", str(message_id + 1)) + chat = json.loads(chat) + users = chat["users"] + for user_slug in users: + await redis.execute("LPUSH", f"chats/{chatId}/unread/{user_slug}", str(message_id)) + result = MessageResult("NEW", new_message) await MessageSubscriptions.put(result) @@ -172,11 +200,35 @@ async def delete_message(_, info, chatId, id): await redis.execute("LREM", f"chats/{chatId}/message_ids", 0, str(id)) await redis.execute("DEL", f"chats/{chatId}/messages/{id}") + chat = json.loads(chat) + users = chat["users"] + for user_slug in users: + await redis.execute("LREM", f"chats/{chatId}/unread/{user_slug}", 0, str(id)) + result = MessageResult("DELETED", message) await MessageSubscriptions.put(result) return {} +@mutation.field("markAsRead") +@login_required +async def mark_as_read(_, info, chatId, ids): + user = info.context["request"].user + + chat = await redis.execute("GET", f"chats/{chatId}") + if not chat: + return { "error" : "chat not exist" } + + chat = json.loads(chat) + users = set(chat["users"]) + if not user.slug in users: + return { "error" : "access denied" } + + for id in ids: + await redis.execute("LREM", f"chats/{chatId}/unread/{user.slug}", 0, str(id)) + + return {} + @subscription.source("chatUpdated") async def message_generator(obj, info, chatId): diff --git a/inbox_schema.graphql b/inbox_schema.graphql index 201582ce..e3ea4c6a 100644 --- a/inbox_schema.graphql +++ b/inbox_schema.graphql @@ -42,6 +42,8 @@ type Mutation { createMessage(chatId: String!, body: String!, replyTo: Int): MessageResult! updateMessage(chatId: String!, id: Int!, body: String!): MessageResult! deleteMessage(chatId: String!, id: Int!): Result! + + markAsRead(chatId: String!, ids: [Int]!): Result! } ################################### Query