From 8b2750c4139f7ea9eaefdf34dbb7cdb776957cec Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Thu, 22 Aug 2024 22:22:04 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(backend)=20attribute=20a=20color=20to?= =?UTF-8?q?=20each=20participant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Color is stored in participant's metadata. Using a hash of some participant's info allow to persist the color for logged-in participant without storing the color in db. Please feel free to tune the saturation and lightness range. Code is inspired by a tutorial found online. --- src/backend/core/utils.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/backend/core/utils.py b/src/backend/core/utils.py index 514d5bc7..2fb16615 100644 --- a/src/backend/core/utils.py +++ b/src/backend/core/utils.py @@ -2,6 +2,10 @@ Utils functions used in the core app """ +# ruff: noqa:S311 + +import json +import random from typing import Optional from uuid import uuid4 @@ -10,6 +14,24 @@ from django.conf import settings from livekit.api import AccessToken, VideoGrants +def generate_color(identity: str) -> str: + """Generates a consistent HSL color based on a given identity string. + + The function seeds the random generator with the identity's hash, + ensuring consistent color output. The HSL format allows fine-tuned control + over saturation and lightness, empirically adjusted to produce visually + appealing and distinct colors. HSL is preferred over hex to constrain the color + range and ensure predictability. + """ + + random.seed(hash(identity)) + hue = random.randint(0, 360) + saturation = random.randint(50, 75) + lightness = random.randint(25, 60) + + return f"hsl({hue}, {saturation}%, {lightness}%)" + + def generate_token(room: str, user, username: Optional[str] = None) -> str: """Generate a LiveKit access token for a user in a specific room. @@ -49,6 +71,7 @@ def generate_token(room: str, user, username: Optional[str] = None) -> str: .with_grants(video_grants) .with_identity(identity) .with_name(username or default_username) + .with_metadata(json.dumps({"color": generate_color(identity)})) ) return token.to_jwt()