diff --git a/pytorrent/services/frontend_assets.py b/pytorrent/services/frontend_assets.py index ff66927..778721a 100644 --- a/pytorrent/services/frontend_assets.py +++ b/pytorrent/services/frontend_assets.py @@ -40,18 +40,72 @@ def google_fonts_css_url() -> str: return f"https://fonts.googleapis.com/css2?{families}&display=swap" -BOOTSTRAP_THEMES = ( - "default", - "flatly", - "litera", - "lumen", - "minty", - "sketchy", - "solar", - "spacelab", - "united", - "zephyr", -) +DEVEXPRESS_BOOTSTRAP_THEMES = { + "blazing-berry": "Blazing Berry", + "office-white": "Office White", + "purple": "Purple", +} + +PYTORRENT_APP_THEMES = { + "adaptive": "pyTorrent Adaptive", + "ocean": "pyTorrent Ocean", + "graphite": "pyTorrent Graphite", + "forest": "pyTorrent Forest", + "amber": "pyTorrent Amber", + "nord": "pyTorrent Nord", + "crimson": "pyTorrent Crimson", + "sky": "pyTorrent Sky", +} + + +BOOTSTRAP_THEME_DEFINITIONS = { + "default": { + "label": "Default Bootstrap", + "local": f"{LIBS_STATIC_DIR}/bootstrap/{BOOTSTRAP_VERSION}/css/bootstrap.min.css", + "cdn": f"https://cdn.jsdelivr.net/npm/bootstrap@{BOOTSTRAP_VERSION}/dist/css/bootstrap.min.css", + }, + # Bootswatch themes. + "flatly": {"label": "Bootswatch: Flatly", "provider": "bootswatch"}, + "litera": {"label": "Bootswatch: Litera", "provider": "bootswatch"}, + "lumen": {"label": "Bootswatch: Lumen", "provider": "bootswatch"}, + "minty": {"label": "Bootswatch: Minty", "provider": "bootswatch"}, + "sketchy": {"label": "Bootswatch: Sketchy", "provider": "bootswatch"}, + "spacelab": {"label": "Bootswatch: Spacelab", "provider": "bootswatch"}, + "united": {"label": "Bootswatch: United", "provider": "bootswatch"}, + "zephyr": {"label": "Bootswatch: Zephyr", "provider": "bootswatch"}, + # Complete DevExpress Bootstrap v5 dist.v5 set. + **{ + f"dx-{theme}": { + "label": f"DevExpress: {label}", + "provider": "devexpress", + "local": f"{LIBS_STATIC_DIR}/devexpress-bootstrap-themes/dist.v5/{theme}/bootstrap.min.css", + "cdn": f"https://cdn.jsdelivr.net/gh/DevExpress/bootstrap-themes@master/dist.v5/{theme}/bootstrap.min.css", + } + for theme, label in DEVEXPRESS_BOOTSTRAP_THEMES.items() + }, + # App-specific Bootstrap variable overrides. These sit on top of default Bootstrap. + **{ + f"pytorrent-{theme}": { + "label": f"Custom: {label}", + "provider": "pytorrent", + "local": f"{LIBS_STATIC_DIR}/pytorrent-themes/{theme}/bootstrap.min.css", + "cdn": f"/static/{LIBS_STATIC_DIR}/pytorrent-themes/{theme}/bootstrap.min.css", + } + for theme, label in PYTORRENT_APP_THEMES.items() + }, +} + +def _theme_definition(theme: str | None) -> dict[str, str]: + theme = theme if theme in BOOTSTRAP_THEME_DEFINITIONS else "default" + item = dict(BOOTSTRAP_THEME_DEFINITIONS[theme]) + if item.get("provider") == "bootswatch": + item["local"] = f"{LIBS_STATIC_DIR}/bootswatch/{BOOTSWATCH_VERSION}/{theme}/bootstrap.min.css" + item["cdn"] = f"https://cdn.jsdelivr.net/npm/bootswatch@{BOOTSWATCH_VERSION}/dist/{theme}/bootstrap.min.css" + return item + + +BOOTSTRAP_THEMES = tuple(BOOTSTRAP_THEME_DEFINITIONS.keys()) +BOOTSTRAP_THEME_LABELS = {key: value["label"] for key, value in BOOTSTRAP_THEME_DEFINITIONS.items()} STATIC_ASSETS = { "bootstrap_js": { @@ -86,16 +140,8 @@ STATIC_ASSETS = { def bootstrap_css_asset(theme: str | None = None) -> dict[str, str]: - theme = theme if theme in BOOTSTRAP_THEMES else "default" - if theme == "default": - return { - "local": f"{LIBS_STATIC_DIR}/bootstrap/{BOOTSTRAP_VERSION}/css/bootstrap.min.css", - "cdn": f"https://cdn.jsdelivr.net/npm/bootstrap@{BOOTSTRAP_VERSION}/dist/css/bootstrap.min.css", - } - return { - "local": f"{LIBS_STATIC_DIR}/bootswatch/{BOOTSWATCH_VERSION}/{theme}/bootstrap.min.css", - "cdn": f"https://cdn.jsdelivr.net/npm/bootswatch@{BOOTSWATCH_VERSION}/dist/{theme}/bootstrap.min.css", - } + item = _theme_definition(theme) + return {"local": item["local"], "cdn": item["cdn"]} def asset_path(key: str) -> str: diff --git a/pytorrent/services/preferences.py b/pytorrent/services/preferences.py index 81abe6e..2399fba 100644 --- a/pytorrent/services/preferences.py +++ b/pytorrent/services/preferences.py @@ -4,19 +4,9 @@ import json from ..db import connect, utcnow, default_user_id from . import auth +from .frontend_assets import BOOTSTRAP_THEME_LABELS -BOOTSTRAP_THEMES = { - "default": "Default Bootstrap", - "flatly": "Flatly", - "litera": "Litera", - "lumen": "Lumen", - "minty": "Minty", - "sketchy": "Sketchy", - "solar": "Solar", - "spacelab": "Spacelab", - "united": "United", - "zephyr": "Zephyr", -} +BOOTSTRAP_THEMES = BOOTSTRAP_THEME_LABELS FONT_FAMILIES = { "default": "Theme default", diff --git a/pytorrent/static/styles.css b/pytorrent/static/styles.css index b9dc43a..1b3800e 100644 --- a/pytorrent/static/styles.css +++ b/pytorrent/static/styles.css @@ -7,6 +7,8 @@ --mobile-filterbar-height: 132px; --sidebar: calc(270px * var(--ui-scale)); --torrent-progress-complete: #198754; + --pytorrent-page-bg: var(--bs-body-bg); + --pytorrent-shell-shadow: 0 12px 45px rgba(0, 0, 0, 0.38); } [data-bs-theme="dark"] { --bs-body-bg: #05070a; @@ -20,6 +22,7 @@ --bs-primary-bg-subtle: #0d2238; --bs-primary-text-emphasis: #9ecbff; --torrent-progress-complete: #2f9e75; + --pytorrent-page-bg: var(--bs-body-bg); } html[data-app-font="adwaita-mono"] { @@ -109,7 +112,7 @@ body { min-height: 100vh; min-height: 100dvh; padding: calc(8px * var(--ui-scale)); - background: #05070a; + background: var(--pytorrent-page-bg, var(--bs-body-bg)); font-family: var(--app-font-family); } .app-shell { @@ -121,7 +124,7 @@ body { border: 1px solid var(--bs-border-color); border-radius: 12px; overflow: hidden; - box-shadow: 0 12px 45px rgba(0, 0, 0, 0.38); + box-shadow: var(--pytorrent-shell-shadow, 0 12px 45px rgba(0, 0, 0, 0.38)); } .topbar { display: flex; diff --git a/pytorrent/templates/index.html b/pytorrent/templates/index.html index 74cbd08..d3bbe07 100644 --- a/pytorrent/templates/index.html +++ b/pytorrent/templates/index.html @@ -6,6 +6,7 @@