From 5e26e1bbb9a12739736810bdde7426ea104d512a Mon Sep 17 00:00:00 2001 From: Jason Schulz Date: Tue, 30 Apr 2024 17:36:52 -0400 Subject: [PATCH] Dark mode (#296) Co-authored-by: Jason Schulz Co-authored-by: Keith Schacht --- .../stylesheets/application.tailwind.css | 30 ++++++++-------- .../stylesheets/includes/daisyui_tooltip.css | 31 +++++++++++++++- app/controllers/settings/people_controller.rb | 4 +-- app/controllers/users_controller.rb | 2 +- app/models/user.rb | 9 +++++ app/views/assistants/_assistant.html.erb | 5 +-- .../conversations/_conversation.html.erb | 4 ++- app/views/layouts/application.html.erb | 6 +++- app/views/messages/_message.html.erb | 2 +- app/views/settings/people/_form.html.erb | 13 +++++++ config/tailwind.config.js | 36 ++++++++++++------- test/models/user_test.rb | 27 +++++++++++--- 12 files changed, 126 insertions(+), 43 deletions(-) diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index d59133582..872bc9665 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -44,26 +44,24 @@ @apply !text-white; } -.relationship .relationship\:bg-gray-700, -.relationship.relationship\:bg-gray-700 { - @apply bg-gray-700; -} - -.relationship .relationship\:bg-gray-200, -.relationship.relationship\:bg-gray-200 { - @apply bg-gray-200; -} - -@media (prefers-color-scheme: dark) { - .relationship .dark\:relationship\:bg-gray-700, - .relationship.dark\:relationship\:bg-gray-700 { +:root:not(.dark) { + .relationship .relationship\:bg-gray-700, + .relationship.relationship\:bg-gray-700 { @apply bg-gray-700; } + .relationship .relationship\:bg-gray-200, + .relationship.relationship\:bg-gray-200 { + @apply bg-gray-200; + } } -.relationship .relationship\:hidden, -.relationship.relationship\:hidden { - @apply !hidden; +@media (prefers-color-scheme: dark), (root: dark) { + .dark\:relationship\:bg-gray-700.relationship { + @apply bg-gray-700 !important; + } + .dark\:relationship\:bg-gray-900.relationship { + @apply bg-gray-900; + } } .relationship .relationship\:pl-4, diff --git a/app/assets/stylesheets/includes/daisyui_tooltip.css b/app/assets/stylesheets/includes/daisyui_tooltip.css index 2087c7897..7f1d725a9 100644 --- a/app/assets/stylesheets/includes/daisyui_tooltip.css +++ b/app/assets/stylesheets/includes/daisyui_tooltip.css @@ -193,13 +193,42 @@ dialog button:focus-visible { --tw-prose-pre-code: #ffffff !important; } +/* dark_mode overrides */ @media (prefers-color-scheme: dark) { + :root.light { + color-scheme: light; + } + :root .prose { + --tw-prose-body: rgb(236, 236, 236); + } +} +:root.dark { + :root .prose { + --tw-prose-body: rgb(236, 236, 236); + } +} +:root.dark { :root .prose { --tw-prose-body: rgb(236, 236, 236); } } -/* show only on touch devices */ +:root.dark { + :where(.menu li:not(.menu-title):not(.disabled) > :not(ul):not(details):not(.menu-title)):not(.active):hover, + :where(.menu li:not(.menu-title):not(.disabled) > details > summary:not(.menu-title)):not(.active):hover { + background-color: rgb(59 59 61); + } +} + +:root.dark { + :where(.menu li:not(.menu-title):not(.disabled) > :not(ul):not(details):not(.menu-title)):not(.active):hover, + :where(.menu li:not(.menu-title):not(.disabled) > details > summary:not(.menu-title)):not(.active):hover { + background-color: rgb(59 59 61); + } +} + +/* hide tooltip on touch devices */ + @media (hover: none), (hover: on-demand), (-moz-touch-enabled: 1), (pointer: coarse) { .tooltip:hover:after, .tooltip:hover:active:before, diff --git a/app/controllers/settings/people_controller.rb b/app/controllers/settings/people_controller.rb index d51dbf3a5..a0221cdbf 100644 --- a/app/controllers/settings/people_controller.rb +++ b/app/controllers/settings/people_controller.rb @@ -17,7 +17,7 @@ def update def person_params params.require(:person).permit(:email, personable_attributes: [ - :id, :first_name, :last_name, :password, :openai_key, :anthropic_key + :id, :first_name, :last_name, :password, :openai_key, :anthropic_key, preferences: [:dark_mode] ]) end @@ -27,4 +27,4 @@ def check_personable_id return render :edit, status: :unauthorized end end -end \ No newline at end of file +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 40c8b9c57..6bdefe82b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -47,7 +47,7 @@ def person_params end def user_params - params.require(:user).permit(preferences: [:nav_closed]) + params.require(:user).permit(preferences: [:nav_closed, :dark_mode]) end def ensure_registration diff --git a/app/models/user.rb b/app/models/user.rb index a727a8331..f45957a1d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -13,4 +13,13 @@ class User < ApplicationRecord has_many :conversations, dependent: :destroy serialize :preferences, coder: JsonSerializer + + before_create :set_default_preferences + + private + + def set_default_preferences + self.preferences ||= {} + self.preferences[:dark_mode] ||= 'system' + end end diff --git a/app/views/assistants/_assistant.html.erb b/app/views/assistants/_assistant.html.erb index 770623881..1a06efc6f 100644 --- a/app/views/assistants/_assistant.html.erb +++ b/app/views/assistants/_assistant.html.erb @@ -7,8 +7,9 @@
+ relationship:bg-gray-200 dark:relationship:bg-gray-700 + mb-px + <%= selected && 'relationship' %> " data-role="conversation" data-radio-behavior-target="radio" diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ae433e6b3..92f98ffb3 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,7 +1,11 @@ <% content_for :title, "HostedGPT" %> - + + > + <%= render "head" %> + <%= message.content_text %>
<% if message.has_document_image? %> <%= button_tag type: "button", diff --git a/app/views/settings/people/_form.html.erb b/app/views/settings/people/_form.html.erb index db75ed889..a353bca10 100644 --- a/app/views/settings/people/_form.html.erb +++ b/app/views/settings/people/_form.html.erb @@ -132,6 +132,19 @@ placeholder: "Anthropic Key" %>
+
+ <%= user_fields.label :dark_mode, "Color Theme" %> +
+ <%= user_fields.fields_for :preferences do |preferences_fields| %> + <% %w(dark light system).each do |value| %> +
+ <%= preferences_fields.radio_button :dark_mode, value, checked: Current.user.preferences[:dark_mode] == value %> + <%= user_fields.label :dark_mode, value.capitalize, class: "dark:text-gray-100", for: "person_personable_attributes_preferences_dark_mode_#{value}"%> +
+ <% end %> + <% end %> +
+
<% end %>
diff --git a/config/tailwind.config.js b/config/tailwind.config.js index 0c1f0c5ff..c9328588b 100644 --- a/config/tailwind.config.js +++ b/config/tailwind.config.js @@ -5,7 +5,7 @@ module.exports = { './public/*.html', './app/helpers/**/*.rb', './app/javascript/**/*.js', - './app/views/**/*.{erb,haml,html,slim}' + './app/views/**/*.{erb,haml,html,slim}', ], theme: { extend: { @@ -13,7 +13,7 @@ module.exports = { sans: ['Figtree', ...defaultTheme.fontFamily.sans], }, colors: { - 'gray': { + gray: { 50: '#f9f9f9', 100: '#ececec', 200: '#cdcdcd', @@ -26,27 +26,37 @@ module.exports = { 900: '#171717', 950: '#0d0d0d', }, - 'brand': { - 'blue': '#2f5ff2', - } + brand: { + blue: '#2f5ff2', + }, + 'base-100': '#ffffff', //this can be avodied by installing, requiring and configuring the daisyui plugin }, scale: { - '96': '0.96', - '97': '0.97', - '98': '0.98', - '99': '0.99', + 96: '0.96', + 97: '0.97', + 98: '0.98', + 99: '0.99', }, strokeWidth: { - '3': '3px', - '4': '4px', + 3: '3px', + 4: '4px', }, }, }, - + darkMode: [ + 'variant', + [ + '@media (prefers-color-scheme: dark) { &:is(.system *) }', + '&:is(.dark *)', + ], + ], plugins: [ require('@tailwindcss/forms'), require('@tailwindcss/aspect-ratio'), require('@tailwindcss/typography'), require('@tailwindcss/container-queries'), - ] + ], } + + + diff --git a/test/models/user_test.rb b/test/models/user_test.rb index eb3665c6b..13d5fb71c 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -105,27 +105,44 @@ class UserTest < ActiveSupport::TestCase test "boolean values within preferences get converted back and forth properly" do assert_nil users(:keith).preferences[:nav_closed] - assert_nil users(:keith).preferences[:dark_mode] assert_nil users(:keith).preferences[:kids] assert_nil users(:keith).preferences[:city] users(:keith).update!(preferences: { nav_closed: true, - dark_mode: false, kids: 2, city: "Austin" }) users(:keith).reload + assert users(:keith).preferences[:nav_closed] - refute users(:keith).preferences[:dark_mode] assert_equal 2, users(:keith).preferences[:kids] assert_equal "Austin", users(:keith).preferences[:city] users(:keith).update!(preferences: { nav_closed: "false", - dark_mode: "true", + }) + refute users(:keith).preferences[:nav_closed] - assert users(:keith).preferences[:dark_mode] + end + + test "dark_mode preference defaults to system and it can update user dark_mode preference" do + new_user = User.create!(password: 'password', first_name: 'First', last_name: 'Last') + assert_equal "system", new_user.preferences[:dark_mode] + + new_user.update!(preferences: { dark_mode: "light" }) + assert_equal "light", new_user.preferences[:dark_mode] + + new_user.update!(preferences: { dark_mode: "dark" }) + + assert_equal "dark", new_user.preferences[:dark_mode] + + new_user.update!(preferences: { dark_mode: "system" }) + + assert_equal "system", new_user.preferences[:dark_mode] + + end + end