from django.db.models.signals import m2m_changed from django.dispatch import receiver from .models import Card def color_is_dark(bg_color): """ Determine if a given hexadecimal color is dark. This function accepts a 6-digit hex color string (with or without a leading '#'). It calculates the brightness using the formula: brightness = (0.299 * red) + (0.587 * green) + (0.114 * blue) A brightness value less than or equal to 186 indicates that the color is dark. Args: bg_color (str): A 6-digit hex color string (e.g. "#FFFFFF" or "FFFFFF"). Returns: bool: True if the color is dark (brightness <= 186), False otherwise. """ # Remove the leading '#' if it exists. color = bg_color[1:7] if bg_color[0] == '#' else bg_color # Convert the hex color components to integers. r = int(color[0:2], 16) g = int(color[2:4], 16) b = int(color[4:6], 16) # Compute brightness based on weighted RGB values. brightness = (r * 0.299) + (g * 0.587) + (b * 0.114) return brightness <= 200 @receiver(m2m_changed, sender=Card.decks.through) def update_card_style(sender, instance, action, **kwargs): if action == "post_add": decks = instance.decks.all() num_decks = decks.count() if num_decks == 1: instance.style = "background-color: " + decks.first().hex_color + ";" elif num_decks >= 2: hex_colors = [deck.hex_color for deck in decks] instance.style = f"background: linear-gradient(to right, {', '.join(hex_colors)});" else: instance.style = "background: linear-gradient(to right, #AAAAAA, #AAAAAA, #AAAAAA);" if not color_is_dark(decks.first().hex_color): instance.style += "color: var(--color-gray-700); text-shadow: 0 0 0 var(--color-gray-700);" else: instance.style += "text-shadow: 0 0 0 #fff;" instance.save(update_fields=["style"])