Add dark mode support
Implemented dark mode across all pages, allowing users to toggle between light and dark themes. The default theme is determined by the operating system or browser settings. A toggle button in the navigation bar enables users to switch themes, using sun and moon icons from Font Awesome. User preferences are stored in cookies and local storage to ensure consistency across sessions and pages. The changes include: - Added a before_request function to load theme preference from cookies or set a default based on user agent. - Updated CSS to support dark mode styling. - Modified base.html to include a theme toggle button and corresponding JavaScript for theme switching. Fixes #FLAS-2
This commit is contained in:
parent
206f4f4d72
commit
8c57553ada
3 changed files with 59 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask, request, g
|
||||||
|
|
||||||
|
|
||||||
def create_app(test_config=None):
|
def create_app(test_config=None):
|
||||||
|
|
@ -31,6 +31,14 @@ def create_app(test_config=None):
|
||||||
def hello():
|
def hello():
|
||||||
return "Hello, World!"
|
return "Hello, World!"
|
||||||
|
|
||||||
|
@app.before_request
|
||||||
|
def load_theme_preference():
|
||||||
|
theme = request.cookies.get('theme')
|
||||||
|
if theme:
|
||||||
|
g.theme = theme
|
||||||
|
else:
|
||||||
|
g.theme = 'dark' if request.user_agent.platform in ['android', 'iphone'] and request.user_agent.browser in ['chrome', 'safari'] and request.user_agent.string.find('DarkMode') != -1 else 'light'
|
||||||
|
|
||||||
# register the database commands
|
# register the database commands
|
||||||
from . import db
|
from . import db
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,3 +152,25 @@ input[type=submit] {
|
||||||
input[type=submit]:hover {
|
input[type=submit]:hover {
|
||||||
background-color: #2c5f8a;
|
background-color: #2c5f8a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.dark-mode {
|
||||||
|
background: #121212;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode a {
|
||||||
|
color: #bb86fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode nav {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .flash {
|
||||||
|
background: #333;
|
||||||
|
border-color: #bb86fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .post .about {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<title>{% block title %}{% endblock %} - Flaskr</title>
|
<title>{% block title %}{% endblock %} - Flaskr</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||||
|
<script src="https://kit.fontawesome.com/57e33e1f60.js" crossorigin="anonymous"></script>
|
||||||
<nav>
|
<nav>
|
||||||
<h1><a href="{{ url_for('index') }}">Flaskr</a></h1>
|
<h1><a href="{{ url_for('index') }}">Flaskr</a></h1>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button id="theme-toggle" aria-label="Toggle Dark Mode">
|
||||||
|
<i id="theme-icon" class="fas"></i>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
{% if g.user %}
|
{% if g.user %}
|
||||||
<li><span>{{ g.user['username'] }}</span>
|
<li><span>{{ g.user['username'] }}</span>
|
||||||
<li><a href="{{ url_for('auth.logout') }}">Log Out</a>
|
<li><a href="{{ url_for('auth.logout') }}">Log Out</a>
|
||||||
|
|
@ -22,3 +28,25 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</section>
|
</section>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
|
const themeIcon = document.getElementById('theme-icon');
|
||||||
|
const currentTheme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||||
|
|
||||||
|
if (currentTheme === 'dark') {
|
||||||
|
document.body.classList.add('dark-mode');
|
||||||
|
themeIcon.classList.add('fa-sun');
|
||||||
|
} else {
|
||||||
|
themeIcon.classList.add('fa-moon');
|
||||||
|
}
|
||||||
|
|
||||||
|
themeToggle.addEventListener('click', function() {
|
||||||
|
document.body.classList.toggle('dark-mode');
|
||||||
|
const newTheme = document.body.classList.contains('dark-mode') ? 'dark' : 'light';
|
||||||
|
localStorage.setItem('theme', newTheme);
|
||||||
|
themeIcon.classList.toggle('fa-sun');
|
||||||
|
themeIcon.classList.toggle('fa-moon');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue