Compare commits

...
1 Commits
Author SHA1 Message Date
lzstealth a9d1d45d78 Release v2.2.2 2026-08-01 22:32:28 +01:00
7 changed files with 272 additions and 9 deletions
+7
View File
@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file.
## 2.2.2 - 2026-08-01
### Fixed
- The theme bootstrap now resolves saved `auto` to an actual dark or light value on first paint, so explicit dark mode no longer flashes white while the page loads.
- The shared app header is now sticky so the top navigation stays visible while scrolling.
## 2.2.1 - 2026-08-01
### Fixed
+254 -3
View File
@@ -101,6 +101,11 @@ Primary keys are `id` unless noted otherwise. Timestamps are stored as `created_
- `d_screens` - screen records and playlist/player assignment.
- `d_onboarding_devices` - device-to-screen bindings and onboarded client names.
## Announcements
- `d_announcements` - announcement content and display metadata.
- `d_announcement_screens` - announcement-to-screen assignments.
### `d_players`
- `device_id`, `public_base_url`, `internal_base_url`, `last_seen_at`, `created_at`, `modified_at`
@@ -123,6 +128,19 @@ Primary keys are `id` unless noted otherwise. Timestamps are stored as `created_
- Foreign key:
- `screen_id` -> `d_screens.id` with `ON DELETE SET NULL`
### `d_announcements`
- `id`, `message`, `short_label`, `announcement_type`, `color_key`, `icon_key`, `duration_seconds`, `expires_at`, `created_at`, `created_by`, `modified_at`, `modified_by`
- `announcement_type` defaults to `lower-third`.
### `d_announcement_screens`
- `announcement_id`, `screen_id`, `created_at`, `created_by`, `modified_at`, `modified_by`
- Foreign keys:
- `announcement_id` -> `d_announcements.id` with `ON DELETE CASCADE`
- `screen_id` -> `d_screens.id` with `ON DELETE CASCADE`
- Composite primary key: `(announcement_id, screen_id)`
## Onboarding
- The onboarding flow uses `d_onboarding_devices` to bind a device to a screen and persist the client name.
@@ -166,6 +184,240 @@ Primary keys are `id` unless noted otherwise. Timestamps are stored as `created_
```mermaid
erDiagram
A_USERS {
INT id
VARCHAR name
VARCHAR username
CHAR password_hash
VARCHAR password_salt
INT password_iterations
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
A_ROLES {
INT id
VARCHAR role_key
VARCHAR name
TEXT description
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
A_PERMISSIONS {
INT id
VARCHAR permission_key
VARCHAR name
VARCHAR section_name
TEXT description
TIMESTAMP created_at
TIMESTAMP modified_at
}
A_ROLE_PERMISSIONS {
INT role_id
INT permission_id
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
A_USER_ROLES {
INT user_id
INT role_id
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
A_SESSIONS {
CHAR session_hash
INT user_id
DATETIME expires_at
TIMESTAMP created_at
INT created_by
TIMESTAMP last_used_at
INT modified_by
}
C_CANVAS_SIZES {
INT id
VARCHAR name
INT width
INT height
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
C_PLAYLISTS {
INT id
VARCHAR name
TINYINT fade_between_slides
TINYINT skip_unavailable_rtmp
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
C_TEMPLATES {
INT id
VARCHAR name
INT canvas_size_id
VARCHAR background_image_path
VARCHAR background_color
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
C_TEMPLATE_REGIONS {
INT id
INT template_id
VARCHAR region_key
VARCHAR region_type
VARCHAR label
VARCHAR font_family
VARCHAR lock_ratio
INT x
INT y
INT width
INT height
INT z_index
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
C_SLIDES {
INT id
VARCHAR title
INT template_id
JSON content_json
VARCHAR thumbnail_path
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
C_PLAYLIST_SLIDES {
INT id
INT playlist_id
INT slide_id
INT position
DECIMAL duration_seconds
TINYINT use_video_duration
VARCHAR schedule_mode
DATETIME schedule_start_datetime
DATETIME schedule_end_datetime
TIME schedule_start_time
TIME schedule_end_time
JSON schedule_days_json
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
D_PLAYERS {
INT device_id
VARCHAR public_base_url
VARCHAR internal_base_url
TIMESTAMP last_seen_at
TIMESTAMP created_at
TIMESTAMP modified_at
}
D_SCREENS {
INT id
VARCHAR name
VARCHAR slug
INT playlist_id
INT player_id
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
D_ONBOARDING_DEVICES {
VARCHAR device_id
VARCHAR client_name
INT screen_id
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
D_ANNOUNCEMENTS {
INT id
TEXT message
VARCHAR short_label
VARCHAR announcement_type
VARCHAR color_key
VARCHAR icon_key
INT duration_seconds
TIMESTAMP expires_at
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
D_ANNOUNCEMENT_SCREENS {
INT announcement_id
INT screen_id
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
I_RSS_FEEDS {
INT id
VARCHAR name
VARCHAR feed_url
INT update_interval_value
VARCHAR update_interval_unit
INT item_limit
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
I_RSS_FEED_ITEMS {
INT id
INT rss_feed_id
INT position
MEDIUMTEXT item_json
TIMESTAMP created_at
INT created_by
TIMESTAMP modified_at
INT modified_by
}
I_API_SOURCES {
INT id
VARCHAR name
VARCHAR api_url
INT update_interval_value
VARCHAR update_interval_unit
TIMESTAMP last_pulled_at
MEDIUMTEXT last_pull_error
INT last_response_status
VARCHAR last_response_content_type
MEDIUMTEXT last_response_json
}
O_BACKGROUND_TASKS {
BIGINT id
VARCHAR task_key
VARCHAR task_type
VARCHAR title
VARCHAR category
VARCHAR status
MEDIUMTEXT payload_json
MEDIUMTEXT metadata_json
INT attempts
TIMESTAMP created_at
TIMESTAMP started_at
TIMESTAMP finished_at
MEDIUMTEXT error_message
}
A_USERS ||--o{ A_USER_ROLES : has
A_ROLES ||--o{ A_USER_ROLES : assigned_to
A_ROLES ||--o{ A_ROLE_PERMISSIONS : has
@@ -181,9 +433,8 @@ erDiagram
D_PLAYERS ||--o{ D_SCREENS : assigned_to
C_PLAYLISTS ||--o{ D_SCREENS : uses
D_SCREENS ||--o{ D_ONBOARDING_DEVICES : binds
D_ANNOUNCEMENTS ||--o{ D_ANNOUNCEMENT_SCREENS : targets
D_SCREENS ||--o{ D_ANNOUNCEMENT_SCREENS : receives
I_RSS_FEEDS ||--o{ I_RSS_FEED_ITEMS : caches
O_BACKGROUND_TASKS {
BIGINT id
}
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pulse-signage",
"version": "2.2.1",
"version": "2.2.2",
"private": false,
"description": "Pulse Signage application with MySQL and media storage",
"repository": {
+5
View File
@@ -123,6 +123,11 @@
--bs-navbar-nav-link-padding-x: 10px;
}
.app-header {
top: 0;
z-index: 1030;
}
.app-sidebar {
display: flex;
flex-direction: column;
+3 -3
View File
@@ -2,7 +2,7 @@
(function () {
var storageKey = 'lte-theme';
var theme = 'auto';
var theme = 'dark';
function getPreferredTheme() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
@@ -15,10 +15,10 @@
try {
var storedTheme = window.localStorage.getItem(storageKey);
if (storedTheme === 'dark' || storedTheme === 'light' || storedTheme === 'auto') {
theme = storedTheme;
theme = storedTheme === 'auto' ? getPreferredTheme() : storedTheme;
}
} catch (error) {
theme = 'auto';
theme = 'dark';
}
document.documentElement.dataset.bsTheme = theme;
+1 -1
View File
@@ -22,7 +22,7 @@
<div class="app-wrapper">
<div class="sidebar-overlay" aria-hidden="true"></div>
{{#unless hideFrameHeader}}
<nav class="app-header navbar navbar-expand bg-body">
<nav class="app-header sticky-top navbar navbar-expand bg-body">
<div class="container-fluid">
<span class="navbar-text fw-semibold">
{{title}}
+1 -1
View File
@@ -58,7 +58,7 @@
</div>
<div class="app-wrapper">
<div class="sidebar-overlay" aria-hidden="true"></div>
<nav class="app-header navbar navbar-expand bg-body">
<nav class="app-header sticky-top navbar navbar-expand bg-body">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">