Better CSS support (#583)
* Remove banner hardcoding * Refactor "colors" to "stylesheet" * Remove logo hardcoding * Remove stylesheet hardcoding * Add very basic static CSS scanning and a new style * Respect environment settings * Check if selected stylesheet still exists * New theme and title formatting * Revert migration change * Code linting * More outlines for Matrix style * Change wording in settings * Forgot this wording * Add suggested changes
This commit is contained in:
parent
6bc0111d0a
commit
7133d6b441
|
@ -162,11 +162,11 @@ class Command(BaseCommand):
|
|||
for user in users:
|
||||
new_conf = UserConfig(user)
|
||||
|
||||
colors_key = f"{user}:colors"
|
||||
colors = redis.get_message(colors_key).get("status")
|
||||
if colors:
|
||||
new_conf.set_value("colors", colors)
|
||||
redis.del_message(colors_key)
|
||||
stylesheet_key = f"{user}:color"
|
||||
stylesheet = redis.get_message(stylesheet_key).get("status")
|
||||
if stylesheet:
|
||||
new_conf.set_value("stylesheet", stylesheet)
|
||||
redis.del_message(stylesheet_key)
|
||||
|
||||
sort_by_key = f"{user}:sort_by"
|
||||
sort_by = redis.get_message(sort_by_key).get("status")
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
- hold all form classes used in the views
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.forms.widgets import PasswordInput, TextInput
|
||||
from home.src.ta.helper import get_stylesheets
|
||||
|
||||
|
||||
class CustomAuthForm(AuthenticationForm):
|
||||
|
@ -29,14 +32,16 @@ class CustomAuthForm(AuthenticationForm):
|
|||
class UserSettingsForm(forms.Form):
|
||||
"""user configurations values"""
|
||||
|
||||
CHOICES = [
|
||||
("", "-- change color scheme --"),
|
||||
("dark", "Dark"),
|
||||
("light", "Light"),
|
||||
]
|
||||
STYLESHEET_CHOICES = [("", "-- change stylesheet --")]
|
||||
STYLESHEET_CHOICES.extend(
|
||||
[
|
||||
(stylesheet, os.path.splitext(stylesheet)[0].title())
|
||||
for stylesheet in get_stylesheets()
|
||||
]
|
||||
)
|
||||
|
||||
colors = forms.ChoiceField(
|
||||
widget=forms.Select, choices=CHOICES, required=False
|
||||
stylesheet = forms.ChoiceField(
|
||||
widget=forms.Select, choices=STYLESHEET_CHOICES, required=False
|
||||
)
|
||||
page_size = forms.IntegerField(required=False)
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ from datetime import datetime
|
|||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
from home.src.ta.settings import EnvironmentSettings
|
||||
|
||||
|
||||
def ignore_filelist(filelist: list[str]) -> list[str]:
|
||||
|
@ -203,3 +204,21 @@ def ta_host_parser(ta_host: str) -> tuple[list[str], list[str]]:
|
|||
csrf_trusted_origins.append(f"{parsed.scheme}://{parsed.hostname}")
|
||||
|
||||
return allowed_hosts, csrf_trusted_origins
|
||||
|
||||
|
||||
def get_stylesheets():
|
||||
"""Get all valid stylesheets from /static/css"""
|
||||
app_root = EnvironmentSettings.APP_DIR
|
||||
stylesheets = os.listdir(os.path.join(app_root, "static/css"))
|
||||
stylesheets.remove("style.css")
|
||||
stylesheets.sort()
|
||||
stylesheets = list(filter(lambda x: x.endswith(".css"), stylesheets))
|
||||
return stylesheets
|
||||
|
||||
|
||||
def check_stylesheet(stylesheet: str):
|
||||
"""Check if a stylesheet exists. Return dark.css as a fallback"""
|
||||
if stylesheet in get_stylesheets():
|
||||
return stylesheet
|
||||
|
||||
return "dark.css"
|
||||
|
|
|
@ -7,12 +7,13 @@ Functionality:
|
|||
from typing import TypedDict
|
||||
|
||||
from home.src.es.connect import ElasticWrap
|
||||
from home.src.ta.helper import get_stylesheets
|
||||
|
||||
|
||||
class UserConfigType(TypedDict, total=False):
|
||||
"""describes the user configuration"""
|
||||
|
||||
colors: str
|
||||
stylesheet: str
|
||||
page_size: int
|
||||
sort_by: str
|
||||
sort_order: str
|
||||
|
@ -31,7 +32,7 @@ class UserConfig:
|
|||
"""Handle settings for an individual user"""
|
||||
|
||||
_DEFAULT_USER_SETTINGS = UserConfigType(
|
||||
colors="dark",
|
||||
stylesheet="dark.css",
|
||||
page_size=12,
|
||||
sort_by="published",
|
||||
sort_order="desc",
|
||||
|
@ -46,7 +47,7 @@ class UserConfig:
|
|||
sponsorblock_id=None,
|
||||
)
|
||||
|
||||
VALID_COLORS = ["dark", "light"]
|
||||
VALID_STYLESHEETS = get_stylesheets()
|
||||
VALID_VIEW_STYLE = ["grid", "list"]
|
||||
VALID_SORT_ORDER = ["asc", "desc"]
|
||||
VALID_SORT_BY = ["published", "downloaded", "views", "likes"]
|
||||
|
@ -91,7 +92,7 @@ class UserConfig:
|
|||
)
|
||||
|
||||
valid_values = {
|
||||
"colors": self.VALID_COLORS,
|
||||
"stylesheet": self.VALID_STYLESHEETS,
|
||||
"sort_by": self.VALID_SORT_BY,
|
||||
"sort_order": self.VALID_SORT_ORDER,
|
||||
"view_style_home": self.VALID_VIEW_STYLE,
|
||||
|
|
|
@ -23,11 +23,7 @@
|
|||
{% else %}
|
||||
<title>TubeArchivist</title>
|
||||
{% endif %}
|
||||
{% if colors == "dark" %}
|
||||
<link rel="stylesheet" href="{% static 'css/dark.css' %}">
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="{% static 'css/light.css' %}">
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{% static 'css/' %}{{ stylesheet }}">
|
||||
<script type="text/javascript" src="{% static 'script.js' %}"></script>
|
||||
{% if cast %}
|
||||
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
|
@ -39,12 +35,7 @@
|
|||
<div class="boxed-content">
|
||||
<div class="top-banner">
|
||||
<a href="{% url 'home' %}">
|
||||
{% if colors == 'dark' %}
|
||||
<img src="{% static 'img/banner-tube-archivist-dark.png' %}" alt="tube-archivist-banner">
|
||||
{% endif %}
|
||||
{% if colors == 'light' %}
|
||||
<img src="{% static 'img/banner-tube-archivist-light.png' %}" alt="tube-archivist-banner">
|
||||
{% endif %}
|
||||
<img alt="tube-archivist-banner">
|
||||
</a>
|
||||
</div>
|
||||
<div class="top-nav">
|
||||
|
|
|
@ -18,20 +18,11 @@
|
|||
<meta name="msapplication-TileColor" content="#01202e">
|
||||
<meta name="msapplication-config" content="{% static 'favicon/browserconfig.xml' %}">
|
||||
<meta name="theme-color" content="#01202e">
|
||||
{% if colors == "dark" %}
|
||||
<link rel="stylesheet" href="{% static 'css/dark.css' %}">
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="{% static 'css/light.css' %}">
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="{% static 'css/' %}{{ stylesheet }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="boxed-content login-page">
|
||||
{% if colors == 'dark' %}
|
||||
<img src="{% static 'img/logo-tube-archivist-dark.png' %}" alt="tube-archivist-logo">
|
||||
{% endif %}
|
||||
{% if colors == 'light' %}
|
||||
<img src="{% static 'img/logo-tube-archivist-light.png' %}" alt="tube-archivist-banner">
|
||||
{% endif %}
|
||||
<img alt="tube-archivist-logo">
|
||||
<h1>Tube Archivist</h1>
|
||||
<h2>Your Self Hosted YouTube Media Server</h2>
|
||||
{% if form_error %}
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<form action="{% url 'settings_user' %}" method="POST" name="user-update">
|
||||
{% csrf_token %}
|
||||
<div class="settings-group">
|
||||
<h2>Color scheme</h2>
|
||||
<h2>Stylesheet</h2>
|
||||
<div class="settings-item">
|
||||
<p>Current color scheme: <span class="settings-current">{{ colors }}</span></p>
|
||||
<i>Select your preferred color scheme between dark and light mode.</i><br>
|
||||
{{ user_form.colors }}
|
||||
<p>Current stylesheet: <span class="settings-current">{{ stylesheet }}</span></p>
|
||||
<i>Select your preferred stylesheet.</i><br>
|
||||
{{ user_form.stylesheet }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-group">
|
||||
|
|
|
@ -39,7 +39,7 @@ from home.src.index.playlist import YoutubePlaylist
|
|||
from home.src.index.reindex import ReindexProgress
|
||||
from home.src.index.video_constants import VideoTypeEnum
|
||||
from home.src.ta.config import AppConfig, ReleaseVersion, ScheduleBuilder
|
||||
from home.src.ta.helper import time_parser
|
||||
from home.src.ta.helper import check_stylesheet, time_parser
|
||||
from home.src.ta.settings import EnvironmentSettings
|
||||
from home.src.ta.ta_redis import RedisArchivist
|
||||
from home.src.ta.users import UserConfig
|
||||
|
@ -73,7 +73,9 @@ class ArchivistViewConfig(View):
|
|||
self.user_conf = UserConfig(self.user_id)
|
||||
|
||||
self.context = {
|
||||
"colors": self.user_conf.get_value("colors"),
|
||||
"stylesheet": check_stylesheet(
|
||||
self.user_conf.get_value("stylesheet")
|
||||
),
|
||||
"cast": EnvironmentSettings.ENABLE_CAST,
|
||||
"sort_by": self.user_conf.get_value("sort_by"),
|
||||
"sort_order": self.user_conf.get_value("sort_order"),
|
||||
|
@ -220,7 +222,9 @@ class MinView(View):
|
|||
def get_min_context(request):
|
||||
"""build minimal vars for context"""
|
||||
return {
|
||||
"colors": UserConfig(request.user.id).get_value("colors"),
|
||||
"stylesheet": check_stylesheet(
|
||||
UserConfig(request.user.id).get_value("stylesheet")
|
||||
),
|
||||
"version": settings.TA_VERSION,
|
||||
"ta_update": ReleaseVersion().get_update(),
|
||||
}
|
||||
|
@ -977,9 +981,9 @@ class SettingsUserView(MinView):
|
|||
config_handler = UserConfig(request.user.id)
|
||||
if user_form.is_valid():
|
||||
user_form_post = user_form.cleaned_data
|
||||
if user_form_post.get("colors"):
|
||||
if user_form_post.get("stylesheet"):
|
||||
config_handler.set_value(
|
||||
"colors", user_form_post.get("colors")
|
||||
"stylesheet", user_form_post.get("stylesheet")
|
||||
)
|
||||
if user_form_post.get("page_size"):
|
||||
config_handler.set_value(
|
||||
|
|
|
@ -9,4 +9,6 @@
|
|||
--accent-font-light: #97d4c8;
|
||||
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
|
||||
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
|
||||
--banner: url("../img/banner-tube-archivist-dark.png");
|
||||
--logo: url("../img/logo-tube-archivist-dark.png");
|
||||
}
|
||||
|
|
|
@ -9,4 +9,6 @@
|
|||
--accent-font-light: #35b399;
|
||||
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
|
||||
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
|
||||
--banner: url("../img/banner-tube-archivist-light.png");
|
||||
--logo: url("../img/logo-tube-archivist-light.png");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
:root {
|
||||
--main-bg: #000000;
|
||||
--highlight-bg: #080808;
|
||||
--highlight-error: #880000;
|
||||
--highlight-error-light: #aa0000;
|
||||
--highlight-bg-transparent: #0c0c0caf;
|
||||
--main-font: #00aa00;
|
||||
--accent-font-dark: #007700;
|
||||
--accent-font-light: #00aa00;
|
||||
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
|
||||
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
|
||||
--banner: url("../img/banner-tube-archivist-dark.png");
|
||||
--logo: url("../img/logo-tube-archivist-dark.png");
|
||||
--outline: 1px solid green;
|
||||
--filter: hue-rotate(310deg);
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.info-box-item {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.footer {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.nav-icons {
|
||||
filter: var(--filter);
|
||||
}
|
||||
|
||||
.view-icons {
|
||||
filter: var(--filter);
|
||||
}
|
||||
|
||||
.top-banner {
|
||||
filter: var(--filter);
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.video-item {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.channel-banner {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.description-box {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.video-player {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
#notification {
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
textarea {
|
||||
background-color: var(--highlight-bg);
|
||||
outline: var(--outline);
|
||||
color: var(--main-font);
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: var(--highlight-bg);
|
||||
color: var(--main-font);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
:root {
|
||||
--main-bg: #000000;
|
||||
--highlight-bg: #0c0c0c;
|
||||
--highlight-error: #220000;
|
||||
--highlight-error-light: #330000;
|
||||
--highlight-bg-transparent: #0c0c0caf;
|
||||
--main-font: #888888;
|
||||
--accent-font-dark: #555555;
|
||||
--accent-font-light: #999999;
|
||||
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
|
||||
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
|
||||
--banner: url("../img/banner-tube-archivist-dark.png");
|
||||
--logo: url("../img/logo-tube-archivist-dark.png");
|
||||
}
|
|
@ -165,12 +165,13 @@ button:hover {
|
|||
.top-banner img {
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
content: var(--banner);
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: 0;
|
||||
padding: 20px 0;
|
||||
background-color: var(--accent-font-dark);
|
||||
background-color: var(--highlight-bg);
|
||||
grid-row-start: 2;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
@ -725,6 +726,7 @@ video:-webkit-full-screen {
|
|||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
margin-bottom: 40px;
|
||||
content: var(--logo);
|
||||
}
|
||||
|
||||
.login-page form {
|
||||
|
|
Loading…
Reference in New Issue