Skip to content
Closed
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
21 changes: 14 additions & 7 deletions app/assets/stylesheets/components/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@
border-color: var(--color-border);
}

.theme-choice {
.theme-choice,
.density-choice {
display: flex;
align-items: center;
justify-content: space-between;
Expand All @@ -135,18 +136,21 @@
border: var(--border-width) solid var(--color-border);
}

.theme-choice-label {
.theme-choice-label,
.density-choice-label {
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
}

.theme-choice-buttons {
.theme-choice-buttons,
.density-choice-buttons {
display: inline-flex;
align-items: center;
gap: var(--spacing-2);
}

.theme-choice-button {
.theme-choice-button,
.density-choice-button {
display: inline-flex;
align-items: center;
gap: var(--spacing-2);
Expand All @@ -159,19 +163,22 @@
transition: background-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
}

.theme-choice-button:hover {
.theme-choice-button:hover,
.density-choice-button:hover {
background: var(--color-bg-hover);
box-shadow: var(--shadow-sm);
transform: translateY(-1px);
}

.theme-choice-button.is-active {
.theme-choice-button.is-active,
.density-choice-button.is-active {
background: var(--color-bg-button);
color: var(--color-text-button);
border-color: transparent;
}

.theme-choice-button.is-active i {
.theme-choice-button.is-active i,
.density-choice-button.is-active i {
color: currentColor;
}

Expand Down
66 changes: 66 additions & 0 deletions app/assets/stylesheets/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,69 @@
--avatar-size-md: 32px;
--avatar-size-default: 40px;
}

:root[data-density="tiny"] {
--font-size-xs: 0.625rem;
--font-size-sm: 0.675rem;
--font-size-base: 0.725rem;
--font-size-md: 0.775rem;
--font-size-lg: 0.825rem;

--spacing-2: 0.25rem;
--spacing-3: 0.375rem;
--spacing-4: 0.625rem;
--spacing-5: 0.75rem;
--spacing-6: 1rem;

--line-height-normal: 1.4;
--line-height-relaxed: 1.45;
}

:root[data-density="compact"] {
--font-size-xs: 0.70rem;
--font-size-sm: 0.75rem;
--font-size-base: 0.80rem;
--font-size-md: 0.875rem;
--font-size-lg: 0.90rem;

--spacing-2: 0.375rem;
--spacing-3: 0.5rem;
--spacing-4: 0.75rem;
--spacing-5: 1rem;
--spacing-6: 1.25rem;

--line-height-normal: 1.5;
--line-height-relaxed: 1.55;
}

:root[data-density="comfortable"] {
--font-size-xs: 0.875rem;
--font-size-sm: 0.95rem;
--font-size-base: 1rem;
--font-size-md: 1.1rem;
--font-size-lg: 1.15rem;

--spacing-3: 0.875rem;
--spacing-4: 1.25rem;
--spacing-5: 1.5rem;
--spacing-6: 1.75rem;

--line-height-normal: 1.65;
--line-height-relaxed: 1.80;
}

:root[data-density="spacious"] {
--font-size-xs: 0.95rem;
--font-size-sm: 1.05rem;
--font-size-base: 1.1rem;
--font-size-md: 1.2rem;
--font-size-lg: 1.25rem;

--spacing-3: 1rem;
--spacing-4: 1.5rem;
--spacing-5: 1.75rem;
--spacing-6: 2rem;

--line-height-normal: 1.70;
--line-height-relaxed: 1.85;
}
48 changes: 48 additions & 0 deletions app/javascript/controllers/density_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Controller } from "@hotwired/stimulus"

const STORAGE_KEY = "hackorum-density"
const DEFAULT_DENSITY = "default"
const VALID_DENSITIES = ["tiny", "compact", "default", "comfortable", "spacious"]

export default class extends Controller {
static targets = ["button"]

connect() {
this.applyInitialDensity()
}

select(event) {
event.preventDefault()
const { densityValue } = event.currentTarget.dataset
this.setDensity(densityValue)
}

applyInitialDensity() {
const stored = window.localStorage.getItem(STORAGE_KEY)
const initial = VALID_DENSITIES.includes(stored) ? stored : DEFAULT_DENSITY
this.setDensity(initial, { persist: false })
}

setDensity(density, { persist = true } = {}) {
const normalized = VALID_DENSITIES.includes(density) ? density : DEFAULT_DENSITY
document.documentElement.dataset.density = normalized

if (persist) {
window.localStorage.setItem(STORAGE_KEY, normalized)
}

this.updateButtons(normalized)
}

updateButtons(density) {
if (this.hasButtonTarget) {
this.buttonTargets.forEach((button) => {
button.classList.toggle("is-active", button.dataset.densityValue === density)
})
}
}

get currentDensity() {
return document.documentElement.dataset.density || DEFAULT_DENSITY
}
}
8 changes: 6 additions & 2 deletions app/views/layouts/application.html.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
doctype html
html data-theme="light"
html data-theme="light" data-density="default"
head
title = meta_title
meta[name="description" content=meta_description]
Expand Down Expand Up @@ -30,14 +30,18 @@ html data-theme="light"
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
var theme = stored || (prefersDark ? 'dark' : 'light');
document.documentElement.dataset.theme = theme;
var densityKey = 'hackorum-density';
var validDensities = ['tiny', 'compact', 'default', 'comfortable', 'spacious'];
var storedDensity = window.localStorage.getItem(densityKey);
document.documentElement.dataset.density = validDensities.includes(storedDensity) ? storedDensity : 'default';
})();
= stylesheet_link_tag "application", "data-turbo-track": "reload"
= javascript_importmap_tags
script[src="https://kit.fontawesome.com/92fb6aa8ba.js"]
- if ENV["UMAMI_WEBSITE_ID"].present?
- umami_host = ENV["UMAMI_HOST"].presence || "https://umami.hackorum.dev"
script[async defer data-website-id=ENV["UMAMI_WEBSITE_ID"] src="#{umami_host}/script.js"]
body class=(content_for?(:sidebar) ? "has-sidebar" : nil) data-controller="sidebar swipe-nav"
body class=(content_for?(:sidebar) ? "has-sidebar" : nil) data-controller="sidebar swipe-nav density"
- if user_signed_in? && current_user.username.blank?
.global-warning
span Please set a username in Settings.
Expand Down
17 changes: 17 additions & 0 deletions app/views/settings/profiles/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@
i.fa-regular.fa-moon aria-hidden="true"
span Dark

.settings-section
h2 Text Density
p.settings-hint Choose your preferred text size and spacing.
.density-choice data-controller="density"
span.density-choice-label Density
.density-choice-buttons
button.density-choice-button type="button" data-density-value="tiny" data-density-target="button" data-action="click->density#select"
span Tiny
button.density-choice-button type="button" data-density-value="compact" data-density-target="button" data-action="click->density#select"
span Compact
button.density-choice-button type="button" data-density-value="default" data-density-target="button" data-action="click->density#select"
span Default
button.density-choice-button type="button" data-density-value="comfortable" data-density-target="button" data-action="click->density#select"
span Comfortable
button.density-choice-button type="button" data-density-value="spacious" data-density-target="button" data-action="click->density#select"
span Spacious

.settings-section
h2 Mention Settings
p.settings-hint Control who can @mention you in notes.
Expand Down