Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions app/assets/stylesheets/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ button, input[type=submit] {
border-radius: $border-radius;
padding: 8px 16px;
cursor: pointer;
@media (prefers-color-scheme: dark) {

[data-theme="dark"] & {
color: $white;
border: 1px solid $light;

&:hover {
border-color: $white;
}
}

}

input[type=text] {
Expand All @@ -114,7 +114,7 @@ input[type=text] {
border-bottom: 1px solid $dark;
outline: none;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
color: $light;
border-bottom: 1px solid $light;
}
Expand All @@ -130,7 +130,7 @@ textarea {
padding: 0 8px;
resize: none;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
color: $light;
}
}
Expand All @@ -139,14 +139,10 @@ textarea {
display: none;
}

@media (prefers-color-scheme: dark) {
//transition: all 1s;

body {
background: $dark;
color: $light;
transition: ease all 1s;
}
body[data-theme="dark"] {
background: $dark;
color: $light;
transition: ease all 1s;

a {
color: $light;
Expand Down
27 changes: 25 additions & 2 deletions app/assets/stylesheets/home.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
border: 1px solid $dark;
padding: 10px;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
border: 1px solid $light;
}

Expand Down Expand Up @@ -60,7 +60,7 @@
}
}

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
.primary-link,
.secondary-link {
border-color: lightgray;
Expand All @@ -79,5 +79,28 @@
margin-top: 20px;
opacity: 0.4;
}

.theme-toggle {
border: none !important;
background: none;
padding: 4px 8px;
cursor: pointer;
color: gray;
font-size: 14px;
line-height: 30px;

&:hover {
color: black;
background: lightgray;
border-radius: $border-radius;
}

[data-theme="dark"] & {
&:hover {
color: white;
background: #202020;
}
}
}
}

24 changes: 10 additions & 14 deletions app/assets/stylesheets/mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,22 @@
}

@mixin logo-darkmode {
@media (prefers-color-scheme: dark) {
.logo {
&.light {
display: none;
}
&.dark {
display: block;
}
.logo {
&.light {
display: block;
}
&.dark {
display: none;
}

transition: ease all 1s;
}

@media (prefers-color-scheme: light) {
[data-theme="dark"] & {
.logo {
&.light {
display: block;
display: none;
}
&.dark {
display: none;
display: block;
}
}

Expand Down Expand Up @@ -84,7 +80,7 @@
}
}

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
textarea {
background: #202020;
color: lightgray;
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/sessions/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
}
}

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
.primary-link,
.secondary-link {
border-color: lightgray;
Expand Down
14 changes: 6 additions & 8 deletions app/assets/stylesheets/sessions/sessions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@
opacity: 1;
}

@media (prefers-color-scheme: light) {
color: $dark;
}
@media (prefers-color-scheme: dark) {
color: $dark;

[data-theme="dark"] & {
color: $light;
}

Expand Down Expand Up @@ -127,7 +126,7 @@
border-radius: $border-radius;
max-height: 100px;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
border: 1px solid $border-color-dark;
}

Expand Down Expand Up @@ -162,7 +161,7 @@
justify-content: flex-start;
border-left: 1px solid $border-color-dark;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
border-left: 1px solid $border-color-dark;
}

Expand All @@ -181,9 +180,8 @@
background: black;
color: white;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
background: rgba(255, 255, 255, 0.4);
// color: black;
}
}
}
Expand Down
38 changes: 27 additions & 11 deletions app/assets/stylesheets/user/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,36 @@
opacity: 1;
}

@media (prefers-color-scheme: light) {
border: 1px solid black;
color: black;
}
border: 1px solid black;
color: black;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
border: 1px solid white;
color: white;
}
}
}

.theme-options {
display: flex;
gap: 16px;
margin-top: 5px;

label {
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;
}

input[type="radio"] {
width: auto;
margin: 0;
padding: 0;
border: none;
}
}

.actions {
input[type="submit"] {
width: 100%;
Expand All @@ -65,13 +83,11 @@
opacity: 1;
}

@media (prefers-color-scheme: light) {
border: 1px solid black;
color: white;
background: black;
}
border: 1px solid black;
color: white;
background: black;

@media (prefers-color-scheme: dark) {
[data-theme="dark"] & {
border: 1px solid white;
color: black;
background: white;
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
class ApplicationController < ActionController::Base
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?

protected

def configure_permitted_parameters
devise_parameter_sanitizer.permit(:account_update, keys: [:theme])
end

rescue_from CanCan::AccessDenied do |_exception|
redirect_to root_path, flash: { error: 'You are not authorized to perform this action.' }
end
Expand Down
7 changes: 7 additions & 0 deletions app/controllers/users/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Users::RegistrationsController < Devise::RegistrationsController
protected

def after_update_path_for(resource)
edit_user_registration_path
end
end
9 changes: 9 additions & 0 deletions app/controllers/users/themes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Users::ThemesController < ApplicationController
def update
new_theme = params[:theme]
if %w[light dark system].include?(new_theme)
current_user.update!(theme: new_theme)
end
head :ok
end
end
3 changes: 3 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
module ApplicationHelper
def theme_preference
current_user&.theme || "system"
end
end
5 changes: 4 additions & 1 deletion app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
import '@hotwired/turbo-rails'
import 'jquery'
import 'sortablejs'
import 'controllers'
import toastr from 'toastr'
import 'controllers'

window.toastr = toastr
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class User < ApplicationRecord
has_many :writing_sessions, dependent: :destroy
has_many :stories, dependent: :destroy

validates :theme, inclusion: { in: %w[light dark system] }

after_create :subscribe_to_mailing

def password_required?
Expand Down
45 changes: 45 additions & 0 deletions app/views/home/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
<div class="header">
<h3 class="title"></h3>
<div class="header-actions">
<button class="header-action theme-toggle" data-theme-toggle data-current-theme="<%= theme_preference %>" title="Toggle theme" aria-label="Toggle theme">
<span data-theme-icon="light"><i class="fas fa-sun"></i></span>
<span data-theme-icon="dark"><i class="fas fa-moon"></i></span>
<span data-theme-icon="system"><i class="fas fa-desktop"></i></span>
</button>
<%= link_to 'Account', edit_user_registration_path, class: 'header-action', data: {'turbo-action': :replace} %>
<%= link_to 'Logout', destroy_user_session_path, method: 'DELETE', class: 'header-action', data: {'turbo-action': :restore, "turbo-method": :delete} %>
</div>
Expand All @@ -28,3 +33,43 @@
</div>
</div>
</div>

<script data-turbo-cache="false">
(function() {
var THEMES = ["light", "dark", "system"];
var btn = document.querySelector("[data-theme-toggle]");
if (!btn) return;

function syncIcons(theme) {
btn.querySelectorAll("[data-theme-icon]").forEach(function(el) {
el.style.display = el.getAttribute("data-theme-icon") === theme ? "" : "none";
});
btn.setAttribute("data-current-theme", theme);
}

syncIcons(btn.getAttribute("data-current-theme"));

btn.addEventListener("click", function() {
var current = btn.getAttribute("data-current-theme");
var next = THEMES[(THEMES.indexOf(current) + 1) % THEMES.length];

var resolved = next === "system"
? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
: next;
document.body.setAttribute("data-theme", resolved);
window.__themePref = next;
syncIcons(next);

var csrf = document.querySelector('meta[name="csrf-token"]').getAttribute("content");
fetch("<%= users_theme_path %>", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": csrf,
"Accept": "application/json"
},
body: JSON.stringify({ theme: next })
});
});
})();
</script>
3 changes: 2 additions & 1 deletion app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
<%= javascript_importmap_tags %>
</head>

<body class="<%= controller.controller_name %> <%= controller.action_name %>">
<body class="<%= controller.controller_name %> <%= controller.action_name %>" data-theme="<%= theme_preference %>">
<%= render "shared/theme" %>
<% unless flash.empty? %>
<script type="text/javascript" data-turbo-cache="false">
toastr.options.preventDuplicates = true;
Expand Down
3 changes: 2 additions & 1 deletion app/views/layouts/devise.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
<script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js" data-mutate-approach="sync"></script>
</head>

<body>
<body data-theme="<%= theme_preference %>">
<%= render "shared/theme" %>
<% unless flash.empty? %>
<script type="text/javascript">
<% flash.each do |f| %>
Expand Down
Loading