theme color and style fix

This commit is contained in:
lelo 2025-03-19 21:41:03 +01:00
parent b7c4360560
commit ed1608847f
8 changed files with 63 additions and 65 deletions

38
app.py
View File

@ -9,6 +9,7 @@ from datetime import datetime, date, timedelta
import diskcache import diskcache
import json import json
import geoip2.database import geoip2.database
from functools import lru_cache
from urllib.parse import urlparse, unquote from urllib.parse import urlparse, unquote
from werkzeug.middleware.proxy_fix import ProxyFix from werkzeug.middleware.proxy_fix import ProxyFix
cache = diskcache.Cache('./filecache', size_limit= 48 * 1024**3) # 32 GB limit cache = diskcache.Cache('./filecache', size_limit= 48 * 1024**3) # 32 GB limit
@ -37,16 +38,12 @@ def require_secret(f):
today = date.today() today = date.today()
def is_valid(secret_data): def is_valid(secret_data):
print("is_valid:", secret_data)
expiry_date = secret_data.get('expiry') expiry_date = secret_data.get('expiry')
is_valid = expiry_date and today <= expiry_date is_valid = expiry_date and today <= expiry_date
print("is_valid", is_valid)
return is_valid return is_valid
# Check if a secret was provided via GET parameter # Check if a secret was provided via GET parameter
get_secret = request.args.get('secret') get_secret = request.args.get('secret')
print("request.args:", request.args)
print("get_secret:", get_secret)
if get_secret is not None: if get_secret is not None:
secret_data = allowed_secrets.get(get_secret) secret_data = allowed_secrets.get(get_secret)
if secret_data: if secret_data:
@ -65,7 +62,6 @@ def require_secret(f):
# If no secret provided via GET, check the session # If no secret provided via GET, check the session
session_secret = session.get('secret') session_secret = session.get('secret')
print("session_secret", session_secret)
if session_secret is not None: if session_secret is not None:
secret_data = allowed_secrets.get(session_secret) secret_data = allowed_secrets.get(session_secret)
if secret_data: if secret_data:
@ -82,32 +78,33 @@ def require_secret(f):
return decorated_function return decorated_function
@app.route('/static/icons/<string:size>.png') @lru_cache(maxsize=10)
def serve_resized_icon(size): def get_cached_image(size):
dimensions = tuple(map(int, size.split('-')[1].split('x'))) dimensions = tuple(map(int, size.split('-')[1].split('x')))
original_logo_path = os.path.join(app.root_path, 'static', 'logo.png') original_logo_path = os.path.join(app.root_path, 'static', 'logo.png')
with Image.open(original_logo_path) as img: with Image.open(original_logo_path) as img:
img = img.convert("RGBA") img = img.convert("RGBA")
# Original image dimensions
orig_width, orig_height = img.size orig_width, orig_height = img.size
# Check if requested dimensions exceed original dimensions
if dimensions[0] >= orig_width and dimensions[1] >= orig_height: if dimensions[0] >= orig_width and dimensions[1] >= orig_height:
# Requested size is larger or equal; return original image resized_img = img
return send_file(original_logo_path, mimetype='image/png') else:
resized_img = img.copy()
resized_img.thumbnail(dimensions, Image.LANCZOS)
# Otherwise, resize img_byte_arr = io.BytesIO()
resized_img = img.copy() resized_img.save(img_byte_arr, format='PNG')
resized_img.thumbnail(dimensions, Image.LANCZOS) return img_byte_arr.getvalue()
# Save resized image to bytes @app.route('/static/icons/<string:size>.png')
resized_bytes = io.BytesIO() def serve_resized_icon(size):
resized_img.save(resized_bytes, format='PNG') cached_image_bytes = get_cached_image(size)
resized_bytes.seek(0) return send_file(
io.BytesIO(cached_image_bytes),
return send_file(resized_bytes, mimetype='image/png') mimetype='image/png'
)
@app.route('/sw.js') @app.route('/sw.js')
def serve_sw(): def serve_sw():
@ -194,7 +191,6 @@ def generate_breadcrumbs(subpath):
@app.route('/api/path/<path:subpath>') @app.route('/api/path/<path:subpath>')
@require_secret @require_secret
def api_browse(subpath): def api_browse(subpath):
print("subpath:", subpath)
file_root = app.config['FILE_ROOT'] file_root = app.config['FILE_ROOT']
directory = os.path.join(file_root, subpath.replace('/', os.sep)) directory = os.path.join(file_root, subpath.replace('/', os.sep))

View File

@ -14,20 +14,21 @@ function encodeSubpath(subpath) {
// Global variable for gallery images (updated from current folder) // Global variable for gallery images (updated from current folder)
let currentGalleryImages = []; let currentGalleryImages = [];
// Render breadcrumbs, directories (grid view when appropriate), and files.
function renderContent(data) { function renderContent(data) {
// Render breadcrumbs, directories (grid view when appropriate), and files.
let breadcrumbHTML = ''; let breadcrumbHTML = '';
data.breadcrumbs.forEach((crumb, index) => { data.breadcrumbs.forEach((crumb, index) => {
breadcrumbHTML += `<a href="#" class="breadcrumb-link" data-path="${crumb.path}">${crumb.name}</a>`; breadcrumbHTML += `<a href="#" data-path="${crumb.path}">${crumb.name}</a>`;
if (index < data.breadcrumbs.length - 1) { if (index < data.breadcrumbs.length - 1) {
breadcrumbHTML += `<span>&gt;</span>`; breadcrumbHTML += `<span>&gt;</span>`;
} }
}); });
document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML; document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML;
let contentHTML = '';
// Render directories. // Render directories.
let contentHTML = '';
if (data.directories.length > 0) { if (data.directories.length > 0) {
contentHTML += '<ul>'; contentHTML += '<ul>';
// Check if every directory name is short (≤15 characters) // Check if every directory name is short (≤15 characters)

View File

@ -98,7 +98,7 @@
/* Style the time info (positioned right below the slider) */ /* Style the time info (positioned right below the slider) */
.now-playing-info { .now-playing-info {
text-align: center; text-align: center;
font-size: 0.8em; font-size: 1em;
margin-top: 0.25em; margin-top: 0.25em;
} }

View File

@ -47,7 +47,6 @@
margin: 0; margin: 0;
} }
/* Loader for gallery */ /* Loader for gallery */
#gallery-loader { #gallery-loader {
display: none; /* Hidden by default */ display: none; /* Hidden by default */

BIN
static/logoW.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@ -4,7 +4,7 @@
"start_url": "/", "start_url": "/",
"display": "fullscreen", "display": "fullscreen",
"background_color": "#ffffff", "background_color": "#ffffff",
"theme_color": "#3367D6", "theme_color": "#34495e",
"icons": [ "icons": [
{ {
"src": "/static/icons/logo-192x192.png", "src": "/static/icons/logo-192x192.png",

View File

@ -11,6 +11,25 @@ body {
padding: 0; padding: 0;
color: #333; color: #333;
} }
/* Header styles */
.site-header {
display: flex;
align-items: center;
padding: 10px 20px;
background-color: #34495e; /* Using the theme color */
color: #eee;
}
.site-header img.logo {
height: 50px;
margin-right: 15px;
}
.site-header h1 {
font-size: 1.5em;
margin: 0;
}
.container {
padding: 20px;
}
.wrapper { .wrapper {
display: grid; display: grid;
grid-template-rows: auto 1fr auto; grid-template-rows: auto 1fr auto;
@ -29,16 +48,16 @@ body {
/* Breadcrumb Styles */ /* Breadcrumb Styles */
.breadcrumb { .breadcrumb {
margin-bottom: 20px; margin-bottom: 15px;
font-size: 18px; font-size: 18px;
} }
.breadcrumb a { .breadcrumb a {
text-decoration: none; text-decoration: none;
color: #3498db; color: #34495e;
margin-right: 5px; margin-right: 5px;
} }
.breadcrumb span { .breadcrumb span {
color: #7f8c8d; color: #c2c2c2;
margin-right: 5px; margin-right: 5px;
} }
@ -90,26 +109,26 @@ li {
/* Link Styles */ /* Link Styles */
a.directory-link, a.directory-link,
a.play-file { a.play-file {
color: #2c3e50; color: #34495e;
text-decoration: none; text-decoration: none;
word-break: break-all; word-break: break-all;
} }
a.directory-link:hover, a.directory-link:hover,
a.play-file:hover { a.play-file:hover {
color: #2980b9; color: #34495e;
} }
a.show-transcript { a.show-transcript {
text-decoration: none; text-decoration: none;
color: #e67e22; color: #34495e;
font-size: 20px; font-size: 20px;
margin-left: 10px; margin-left: 10px;
} }
a.show-transcript:hover { a.show-transcript:hover {
color: #d35400; color: rgb(113, 146, 167);
} }
.currently-playing { .currently-playing {
background-color: #a6bedf; /* Adjust to your preferred color */ background-color: #bfd0df; /* Adjust to your preferred color */
} }
/* Footer Player Styles */ /* Footer Player Styles */

View File

@ -17,7 +17,7 @@
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}"> <link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
<!-- Android Theme Color --> <!-- Android Theme Color -->
<meta name="theme-color" content="#3367D6"> <meta name="theme-color" content="#34495e">
<!-- Apple-specific tags --> <!-- Apple-specific tags -->
<link rel="touch-icon" href="{{ url_for('static', filename='icons/icon-192x192.png') }}"> <link rel="touch-icon" href="{{ url_for('static', filename='icons/icon-192x192.png') }}">
@ -30,31 +30,12 @@
<link rel="stylesheet" href="{{ url_for('static', filename='gallery.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='gallery.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='audioplayer.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='audioplayer.css') }}">
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
/* Header styles */
.site-header {
display: flex;
align-items: center;
padding: 10px 20px;
background-color: #9bbbff; /* Using the theme color */
color: #000000;
}
.site-header img.logo {
height: 50px;
margin-right: 15px;
}
.site-header h1 {
font-size: 1.5em;
margin: 0;
}
.container {
padding: 20px;
}
</style>
</head> </head>
<body> <body>
<header class="site-header"> <header class="site-header">
<img src="https://app.bethaus-speyer.de/static/icons/logo-300x300.png" alt="Logo" class="logo"> <a href="#">
<img src="/static/logoW.png" alt="Logo" class="logo">
</a>
<h1>Gottesdienste Speyer und Schwegenheim</h1> <h1>Gottesdienste Speyer und Schwegenheim</h1>
</header> </header>
<div class="wrapper"> <div class="wrapper">
@ -63,8 +44,8 @@
<div id="content"></div> <div id="content"></div>
</div> </div>
<!-- Global Audio Player in Footer style="display: none;"--> <!-- Global Audio Player in Footer -->
<footer > <footer>
<div class="audio-player-container" id="audioPlayerContainer"> <div class="audio-player-container" id="audioPlayerContainer">
<div class="audio-player"> <div class="audio-player">
<audio id="globalAudio"> <audio id="globalAudio">
@ -92,7 +73,9 @@
</button> </button>
</div> </div>
</div> </div>
<div id="nowPlayingInfo" class="now-playing-info"></div> <div id="nowPlayingInfo" class="now-playing-info">
keine Datei ausgewählt...
</div>
</div> </div>
</footer> </footer>
</div> </div>