Browse Source

improve dark mode nick colours

Byron Jones 6 years ago
parent
commit
60f57be9d4

+ 1 - 1
dev-util

@@ -149,7 +149,7 @@ if ($command eq 'svg-inline') {
     push @combined, @sass;
     push @combined, 'body.dark';
     foreach my $line (@sass) {
-        $line =~ s/\$(.+?-colour)/\$night-$1/;
+        $line =~ s/\$(.+?-colour)/\$night-$1/g;
         push @combined, $line;
     }
 

+ 98 - 4
lib/LogBot/Web/Colour.pm

@@ -5,8 +5,10 @@ use strict;
 use warnings;
 
 use Digest::xxHash qw( xxhash32 );
+use List::Util qw( max min );
 use Memoize qw( memoize );
 use Memoize::ExpireLRU ();
+use POSIX qw( ceil floor );
 
 our @EXPORT_OK = qw(
     nick_hash nick_colour
@@ -27,11 +29,103 @@ sub nick_colour {
     my ($hash) = @_;
     $hash = $hash + 0;
 
-    my $h = $hash % 360;
-    my $l = $h >= 30 && $h <= 210 ? 30 : 50;
-    my $s = 20 + $hash % 80;
+    my @light_hsl =
+        ($hash % 360, (20 + $hash % 80) / 100, (($hash % 360) >= 30 && ($hash % 360) <= 210 ? 30 : 50) / 100,);
+    my @dark_hsl = darken(@light_hsl);
 
-    return 'hsl(' . $h . ',' . $s . '%,' . $l . '%)';
+    return (hsl_to_rgb(@light_hsl), hsl_to_rgb(@dark_hsl));
+}
+
+# from https://github.com/darkreader/
+sub darken {
+    my ($h, $s, $l) = @_;
+
+    my $l_max            = 0.9;
+    my $l_min_s0         = 0.7;
+    my $l_min_s1         = 0.6;
+    my $s_neutral_lim_l0 = 0.12;
+    my $s_neutral_lim_l1 = 0.36;
+    my $s_coloured       = 0.24;
+    my $h_coloured_l0    = 35;
+    my $h_coloured_l1    = 45;
+
+    my $l_min = scale($s, 0, 1, $l_min_s0, $l_min_s1);
+    my $l_x = $l < 0.5 ? scale($l, 0, 0.5, $l_max, $l_min) : max($l, $l_min);
+    my $h_x = $h;
+    my $s_x = $s;
+
+    my $s_netural_lim = scale(clamp($l_x, $l_min, $l_max), $l_min, $l_max, $s_neutral_lim_l0, $s_neutral_lim_l1);
+    if ($s < $s_netural_lim) {
+        $s_x = $s_coloured;
+        $h_x = scale(clamp($l_x, $l_min, $l_max), $l_min, $l_max, $h_coloured_l0, $h_coloured_l1);
+    }
+
+    return ($h_x, $s_x, $l_x);
+}
+
+sub rgb_to_hsl {
+    my ($colour) = @_;
+
+    die unless $colour =~ /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/;
+    my ($r, $g, $b) = (hex($1) / 255, hex($2) / 255, hex($3) / 255);
+
+    my $max = max($r, $g, $b);
+    my $min = min($r, $g, $b);
+    my $c   = $max - $min;
+    my $l   = ($max + $min) / 2;
+
+    return { h => 0, s => 0, l => $l } if $c == 0;
+
+    my $h = ($max == $r ? ((($g - $b) / $c) % 6) : ($max == $g ? (($b - $r) / $c + 2) : (($r - $g) / $c + 4))) * 60;
+    $h += 360 if $h < 0;
+
+    my $s = $c / (1 - abs(2 * $l - 1));
+
+    return ($h, $s, $l);
+}
+
+sub hsl_to_rgb {
+    my ($h, $s, $l) = @_;
+    my ($r, $g, $b);
+
+    if ($s == 0) {
+        $r = $b = $g = $l;
+
+    } else {
+        my $c = (1 - abs(2 * $l - 1)) * $s;
+        my $x = $c * (1 - abs(($h / 60) % 2 - 1));
+        my $m = $l - $c / 2;
+        if ($h < 60) {
+            ($r, $g, $b) = map { $_ + $m } ($c, $x, 0);
+        } elsif ($h < 120) {
+            ($r, $g, $b) = map { $_ + $m } ($x, $c, 0);
+        } elsif ($h < 180) {
+            ($r, $g, $b) = map { $_ + $m } (0, $c, $x);
+        } elsif ($h < 240) {
+            ($r, $g, $b) = map { $_ + $m } (0, $x, $c);
+        } elsif ($h < 300) {
+            ($r, $g, $b) = map { $_ + $m } ($x, 0, $c);
+        } else {
+            ($r, $g, $b) = map { $_ + $m } ($c, 0, $x);
+        }
+    }
+
+    return sprintf('#%02x%02x%02x', map { round($_ * 255) } ($r, $g, $b));
+}
+
+sub scale {
+    my ($x, $in_low, $in_high, $out_low, $out_high) = @_;
+    return ($x - $in_low) * ($out_high - $out_low) / ($in_high - $in_low) + $out_low;
+}
+
+sub clamp {
+    my ($x, $min, $max) = @_;
+    return min($max, max($min, $x));
+}
+
+sub round {
+    my ($x) = @_;
+    return $x > 0 ? floor($x + 0.50000000000008) : ceil($x - 0.50000000000008);
 }
 
 {

+ 7 - 1
lib/LogBot/Web/Stats.pm

@@ -6,6 +6,7 @@ use warnings;
 
 use DateTime ();
 use JSON::XS qw( decode_json );
+use List::Util qw( uniq );
 use LogBot::Database qw( dbh );
 use LogBot::Util qw( commify file_for plural slurp time_to_datetimestr );
 use LogBot::Web::Util qw( channel_from_param irc_host );
@@ -129,7 +130,12 @@ sub render_nicks {
     my $file = file_for($config, 'meta', $c->stash('channel'), 'nicks');
     my $data = decode_json(-e $file ? slurp($file) : slurp(file_for($config, 'meta', '_empty', 'nicks')));
 
-    $c->stash(nicks => $data);
+    my @nick_hashes;
+    foreach my $nick (@{$data}) {
+        push @nick_hashes, $nick->{hash};
+    }
+
+    $c->stash(nicks => $data, nick_hashes => [uniq @nick_hashes]);
     $c->render('stats_nicks');
 }
 

+ 0 - 2
web/_variables.sass

@@ -36,8 +36,6 @@ $night-warning-colour: #411
 // dark mode overrides
 
 body.dark
-  #stats #hours-now
-    filter: none !important
 
   .pika-prev, .pika-next
     filter: invert(100%)

+ 19 - 14
web/logbot.js

@@ -619,19 +619,7 @@ $(function() {
 
     // channel stats
 
-    if ($('body').hasClass('stats')) {
-        var channel = $('#stats').data('channel');
-        var base = channel ? 'stats/' : '_stats/';
-
-        $.getJSON(base + 'meta', function(data) {
-            $.each(data, function(name, value) {
-                $('#' + name)
-                    .text(value)
-                    .removeClass('loading');
-            });
-            $('.loading-hide').removeClass('loading-hide');
-        });
-
+    function update_hours_plot() {
         $.ajax({
             url: base + 'hours',
             method: 'GET',
@@ -661,7 +649,7 @@ $(function() {
                         grid: {
                             borderWidth: 0
                         },
-                        colors: ['#444']
+                        colors: [$('#loc-container').css('background-color')]
                     }
                 );
 
@@ -676,6 +664,23 @@ $(function() {
                 $container.append('<div id="hours-now" style="' + style + '">Now</div>');
             }
         });
+    }
+
+    if ($('body').hasClass('stats')) {
+        var channel = $('#stats').data('channel');
+        var base = channel ? 'stats/' : '_stats/';
+
+        $.getJSON(base + 'meta', function(data) {
+            $.each(data, function(name, value) {
+                $('#' + name)
+                    .text(value)
+                    .removeClass('loading');
+            });
+            $('.loading-hide').removeClass('loading-hide');
+        });
+
+        update_hours_plot();
+        $(document).on('setting:dark', update_hours_plot);
 
         if (channel) {
             $.ajax({

File diff suppressed because it is too large
+ 0 - 0
web/public/static/logbot.min.css


File diff suppressed because it is too large
+ 0 - 0
web/public/static/logbot.min.js


+ 0 - 1
web/templates/channel.html.ep

@@ -2,7 +2,6 @@
 
 % use DateTime ();
 % use LogBot::Util qw( time_to_datestr time_ago );
-% use LogBot::Web::Colour qw( nick_colour );
 % use LogBot::Web::Util qw( url_for_channel );
 % use Mojo::Util qw( trim );
 

+ 0 - 1
web/templates/search.html.ep

@@ -2,7 +2,6 @@
 
 % use List::Util qw( any uniq );
 % use LogBot::Util qw( time_to_ymd time_to_datestr );
-% use LogBot::Web::Colour qw( nick_colour );
 % use LogBot::Web::Util qw( url_for_channel );
 
 % my $last_channel = $ch eq '' ? $last_c : $ch;

+ 4 - 1
web/templates/shared/nick_styles.html.ep

@@ -1,5 +1,8 @@
+% use LogBot::Web::Colour qw( nick_colour );
 <style>
 % foreach my $hash (@{$nick_hashes}) {
-body:not(.nick-u) .nc[data-hash="<%= $hash %>"]{color:<%= nick_colour($hash) %>!important}
+%   my ($light, $dark) = nick_colour($hash);
+body:not(.nick-u) .nc[data-hash="<%= $hash %>"]{color:<%= $light %>!important}
+body:not(.nick-u).dark .nc[data-hash="<%= $hash %>"]{color:<%= $dark %>!important}
 % }
 </style>

+ 1 - 7
web/templates/stats_nicks.html.ep

@@ -1,13 +1,7 @@
 <table id="top-nicks">
-% use List::Util qw( uniq );
-% use LogBot::Web::Colour qw( nick_colour );
 % use LogBot::Util qw( commify );
 
-<style>
-% foreach my $hash (uniq grep { $_ } map { $_->{hash} } @$nicks) {
-body:not(.nick-u) .nc[data-hash="<%= $hash %>"]{color:<%= nick_colour($hash) %>!important}
-% }
-</style>
+%= include 'shared/nick_styles', nick_hashes => $nick_hashes
 
 % if (@$nicks) {
   % my $top_count = $nicks->[0]->{count};

Some files were not shown because too many files changed in this diff