Added ui changes to modals, pre-loader and some fixes for other ui elements and performance improvements all over.

This commit is contained in:
2026-08-31 23:23:37 +02:00
parent 99982b12d9
commit dadae8f60a
3 changed files with 597 additions and 215 deletions

View File

@@ -20,6 +20,8 @@ OFFICIAL_LOGO_URL = "https://pristontale.eu/public/img/pristontale/logo/logo_sma
BROADCAST_ENDPOINT = "http://5.135.35.188:90/broadcasts"
MAX_NEWS_BYTES = 2 * 1024 * 1024
MAX_NEWS_IMAGE_BYTES = 12 * 1024 * 1024
MAX_BROADCAST_AUTHOR_CHARACTERS = 100
MAX_BROADCAST_CONTENT_CHARACTERS = 2000
PNG_SIGNATURE = b"\x89PNG\r\n\x1a\n"
@@ -241,26 +243,41 @@ def _parse_latest_broadcast(payload: bytes) -> Broadcast:
value = json.loads(payload.decode("utf-8-sig"))
if not isinstance(value, list) or not value or not isinstance(value[0], dict):
raise NewsError("broadcast response does not contain a latest broadcast")
latest = value[0]
author = latest.get("author")
content = latest.get("content")
return _broadcast_from_mapping(value[0])
def _broadcast_from_mapping(latest: dict[object, object]) -> Broadcast:
author = _bounded_text(latest.get("author"), MAX_BROADCAST_AUTHOR_CHARACTERS)
content = _bounded_text(latest.get("content"), MAX_BROADCAST_CONTENT_CHARACTERS)
url = _broadcast_url(latest.get("url"))
if (
not isinstance(author, str)
or not author.strip()
or not isinstance(content, str)
or not content.strip()
author is None
or content is None
or url is None
):
raise NewsError("latest broadcast is incomplete")
published_at = (
_format_timestamp(latest.get("timestamp"))
if "timestamp" in latest
else _bounded_text(latest.get("published_at"), 64)
)
return Broadcast(
author=author.strip(),
content=content.strip(),
published_at=_format_timestamp(latest.get("timestamp")),
author=author,
content=content,
published_at=published_at,
url=url,
)
def _bounded_text(value: object, maximum_characters: int) -> str | None:
if not isinstance(value, str):
return None
text = value.strip()
if not text or len(text) > maximum_characters:
return None
return text
def _format_timestamp(value: object) -> str | None:
if isinstance(value, bool) or not isinstance(value, (int, float)):
return None
@@ -288,10 +305,16 @@ def _image_url(value: object) -> str | None:
def _broadcast_url(value: object) -> str | None:
if not isinstance(value, str) or not value.strip():
return None
parsed = urlparse(value)
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
url = value.strip()
parsed = urlparse(url)
if (
parsed.scheme.casefold() != "https"
or not parsed.netloc
or parsed.username is not None
or parsed.password is not None
):
return None
return value.strip()
return url
def _read_cache(path: Path) -> tuple[NewsArticle, ...]:
@@ -320,8 +343,8 @@ def _write_cache(path: Path, articles: tuple[NewsArticle, ...]) -> None:
def _read_broadcast_cache(path: Path) -> Broadcast | None:
try:
value = json.loads(path.read_text(encoding="utf-8"))
return Broadcast(**value) if isinstance(value, dict) else None
except (OSError, UnicodeError, TypeError, json.JSONDecodeError):
return _broadcast_from_mapping(value) if isinstance(value, dict) else None
except (OSError, UnicodeError, NewsError, json.JSONDecodeError):
return None

View File

@@ -304,6 +304,7 @@ def create_window_chrome(
*,
title: str,
subtitle: str,
window_icon: Any | None = None,
show_title_bar: bool = True,
show_close: bool = True,
show_minimize: bool = False,
@@ -347,17 +348,39 @@ def create_window_chrome(
title_bar.pack_propagate(False)
tk_accent = tk.Frame(title_bar, background="#d98927", width=3)
tk_accent.pack(side="left", fill="y")
mark = tk.Canvas(
title_bar,
width=22,
height=22,
background="#17100d",
borderwidth=0,
highlightthickness=0,
cursor="fleur",
)
mark.create_oval(3, 3, 19, 19, outline="#d98927", width=1)
mark.create_text(11, 11, text="PT", fill="#f5d18b", font=("Georgia", 6, "bold"))
title_icon: Any | None = None
if window_icon is not None:
try:
factor = icon_subsample_factor(
window_icon.width(),
window_icon.height(),
20,
)
title_icon = window_icon.subsample(factor, factor)
except (tk.TclError, ValueError):
title_icon = None
if title_icon is not None:
mark = tk.Label(
title_bar,
image=title_icon,
width=22,
height=22,
background="#17100d",
borderwidth=0,
highlightthickness=0,
cursor="fleur",
)
mark.image = title_icon
else:
mark = tk.Frame(
title_bar,
width=22,
height=22,
background="#17100d",
borderwidth=0,
highlightthickness=0,
cursor="fleur",
)
mark.pack(side="left", padx=(9, 7))
identity = tk.Frame(title_bar, background="#17100d", cursor="fleur")
identity.pack(side="left", fill="y")
@@ -440,6 +463,7 @@ def create_dashboard_chrome(
*,
title: str,
subtitle: str,
window_icon: Any | None = None,
) -> DashboardChrome:
"""Install the draggable frame and full controls used by the dashboard."""
@@ -447,6 +471,7 @@ def create_dashboard_chrome(
root,
title=title,
subtitle=subtitle,
window_icon=window_icon,
show_close=True,
show_minimize=True,
allow_close=True,

File diff suppressed because it is too large Load Diff