Skip to content

Commit 75e352f

Browse files
author
devpossible
committed
chore: remove empty code change entries from changelog
1 parent 30942bc commit 75e352f

46 files changed

Lines changed: 6738 additions & 124 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,16 @@ try {
266266
}
267267
}
268268

269+
# Copy html_assets folder (needed for HTML panel rendering - CSS, JS, etc.)
270+
$buildAssetsDir = Join-Path $buildOutputDir 'html_assets'
271+
$publishAssetsDir = Join-Path $outputDir 'html_assets'
272+
if (Test-Path $buildAssetsDir) {
273+
Copy-Item -Path $buildAssetsDir -Destination $publishAssetsDir -Recurse -Force
274+
Write-Host " Copied html_assets for panel rendering" -ForegroundColor Gray
275+
} else {
276+
Write-Host " [WARN] html_assets directory not found: $buildAssetsDir" -ForegroundColor Yellow
277+
}
278+
269279
# Rename executable to lowercase for Linux/macOS (case-sensitive filesystems)
270280
if ($runtime -notlike 'win-*') {
271281
$exePath = Join-Path $outputDir 'LCDPossible'

src/LCDPossible.Core/Configuration/DisplayProfile.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ public sealed class DisplayProfile
4949
[YamlMember(Alias = "default_transition_duration")]
5050
public int DefaultTransitionDurationMs { get; set; } = 1500;
5151

52+
/// <summary>
53+
/// Default page effect for panels.
54+
/// Options: none, glow-on-change, flip-digits, slide-numbers, typewriter, particle-burst,
55+
/// gentle-float, tilt-3d, shake-on-warning, bounce-in, wave, scanlines, matrix-rain,
56+
/// particle-field, grid-pulse, hologram, vanna-white, pixel-mascot, robot-assistant,
57+
/// warning-flash, spotlight, neon-trails, glitch, random.
58+
/// Default is "none".
59+
/// </summary>
60+
[YamlMember(Alias = "default_page_effect")]
61+
public string DefaultPageEffect { get; set; } = "none";
62+
5263
/// <summary>
5364
/// Color scheme for panel rendering.
5465
/// </summary>
@@ -87,7 +98,8 @@ public List<SlideshowItem> ToSlideshowItems()
8798
UpdateIntervalSeconds = slide.UpdateInterval ?? DefaultUpdateIntervalSeconds,
8899
BackgroundImage = slide.Background,
89100
Transition = transitionType,
90-
TransitionDurationMs = transitionDuration
101+
TransitionDurationMs = transitionDuration,
102+
PageEffect = slide.PageEffect ?? DefaultPageEffect
91103
});
92104
}
93105

@@ -217,4 +229,14 @@ public sealed class SlideDefinition
217229
/// </summary>
218230
[YamlMember(Alias = "transition_duration")]
219231
public int? TransitionDurationMs { get; set; }
232+
233+
/// <summary>
234+
/// Page effect for this slide (overrides profile default).
235+
/// Options: none, glow-on-change, flip-digits, slide-numbers, typewriter, particle-burst,
236+
/// gentle-float, tilt-3d, shake-on-warning, bounce-in, wave, scanlines, matrix-rain,
237+
/// particle-field, grid-pulse, hologram, vanna-white, pixel-mascot, robot-assistant,
238+
/// warning-flash, spotlight, neon-trails, glitch, random.
239+
/// </summary>
240+
[YamlMember(Alias = "page_effect")]
241+
public string? PageEffect { get; set; }
220242
}

src/LCDPossible.Core/Configuration/LcdPossibleOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,16 @@ public sealed class SlideshowItem
218218
/// Available themes: cyberpunk, rgb-gaming, executive, clean.
219219
/// </summary>
220220
public string? Theme { get; set; }
221+
222+
/// <summary>
223+
/// Page effect for this specific slide.
224+
/// Options: none, glow-on-change, flip-digits, slide-numbers, typewriter, particle-burst,
225+
/// gentle-float, tilt-3d, shake-on-warning, bounce-in, wave, scanlines, matrix-rain,
226+
/// particle-field, grid-pulse, hologram, vanna-white, pixel-mascot, robot-assistant,
227+
/// warning-flash, spotlight, neon-trails, glitch, random.
228+
/// Default is "none".
229+
/// </summary>
230+
public string PageEffect { get; set; } = "none";
221231
}
222232

223233
/// <summary>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
namespace LCDPossible.Core.Configuration;
2+
3+
/// <summary>
4+
/// Defines a page effect that can be applied to any widget panel.
5+
/// Page effects are JS scripts that add visual enhancements like
6+
/// animations, transitions, and interactive elements.
7+
/// </summary>
8+
public class PageEffect
9+
{
10+
/// <summary>
11+
/// Unique identifier for this effect (e.g., "glow-on-change", "matrix-rain").
12+
/// </summary>
13+
public string Id { get; set; } = "";
14+
15+
/// <summary>
16+
/// Human-readable display name.
17+
/// </summary>
18+
public string DisplayName { get; set; } = "";
19+
20+
/// <summary>
21+
/// Brief description of what the effect does.
22+
/// </summary>
23+
public string Description { get; set; } = "";
24+
25+
/// <summary>
26+
/// Category for grouping effects in UI.
27+
/// </summary>
28+
public PageEffectCategory Category { get; set; } = PageEffectCategory.Other;
29+
30+
/// <summary>
31+
/// The JavaScript content for this effect.
32+
/// </summary>
33+
public string? ScriptContent { get; set; }
34+
35+
/// <summary>
36+
/// Whether this effect requires live mode (continuous rendering).
37+
/// Most effects with animations require live mode.
38+
/// </summary>
39+
public bool RequiresLiveMode { get; set; } = true;
40+
41+
/// <summary>
42+
/// Default options for this effect (can be overridden per-panel).
43+
/// </summary>
44+
public Dictionary<string, object> DefaultOptions { get; set; } = new();
45+
}
46+
47+
/// <summary>
48+
/// Categories for organizing page effects.
49+
/// </summary>
50+
public enum PageEffectCategory
51+
{
52+
/// <summary>Effects that trigger on value changes.</summary>
53+
ValueChange,
54+
55+
/// <summary>Effects that animate containers/widgets.</summary>
56+
ContainerAnimation,
57+
58+
/// <summary>Effects that draw backgrounds or overlays.</summary>
59+
BackgroundOverlay,
60+
61+
/// <summary>Effects featuring animated characters or mascots.</summary>
62+
CharacterMascot,
63+
64+
/// <summary>Effects for alerts and status indicators.</summary>
65+
AlertStatus,
66+
67+
/// <summary>Other/miscellaneous effects.</summary>
68+
Other
69+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
namespace LCDPossible.Core.Configuration;
2+
3+
/// <summary>
4+
/// Manages page effects - loads built-in effects and provides access to them.
5+
/// </summary>
6+
public class PageEffectManager
7+
{
8+
private static readonly Lazy<PageEffectManager> _instance = new(() => new PageEffectManager());
9+
private readonly Dictionary<string, PageEffect> _effects = new(StringComparer.OrdinalIgnoreCase);
10+
11+
/// <summary>
12+
/// Gets the singleton instance.
13+
/// </summary>
14+
public static PageEffectManager Instance => _instance.Value;
15+
16+
private PageEffectManager()
17+
{
18+
RegisterBuiltInEffects();
19+
}
20+
21+
/// <summary>
22+
/// Gets all registered effects.
23+
/// </summary>
24+
public IReadOnlyDictionary<string, PageEffect> Effects => _effects;
25+
26+
/// <summary>
27+
/// Gets an effect by ID, or null if not found.
28+
/// Use "random" to get a random effect.
29+
/// </summary>
30+
public PageEffect? GetEffect(string? id)
31+
{
32+
if (string.IsNullOrEmpty(id) || id == "none")
33+
return null;
34+
35+
if (id.Equals("random", StringComparison.OrdinalIgnoreCase))
36+
return GetRandomEffect();
37+
38+
return _effects.TryGetValue(id, out var effect) ? effect : null;
39+
}
40+
41+
/// <summary>
42+
/// Gets a random effect from all registered effects.
43+
/// </summary>
44+
public PageEffect GetRandomEffect()
45+
{
46+
var effects = _effects.Values.ToList();
47+
return effects[Random.Shared.Next(effects.Count)];
48+
}
49+
50+
/// <summary>
51+
/// Gets a random effect from a specific category.
52+
/// </summary>
53+
public PageEffect? GetRandomEffectFromCategory(PageEffectCategory category)
54+
{
55+
var effects = _effects.Values.Where(e => e.Category == category).ToList();
56+
if (effects.Count == 0) return null;
57+
return effects[Random.Shared.Next(effects.Count)];
58+
}
59+
60+
/// <summary>
61+
/// Gets all effects in a category.
62+
/// </summary>
63+
public IEnumerable<PageEffect> GetEffectsByCategory(PageEffectCategory category)
64+
{
65+
return _effects.Values.Where(e => e.Category == category);
66+
}
67+
68+
/// <summary>
69+
/// Registers a custom effect.
70+
/// </summary>
71+
public void RegisterEffect(PageEffect effect)
72+
{
73+
_effects[effect.Id] = effect;
74+
}
75+
76+
private void RegisterBuiltInEffects()
77+
{
78+
// Value Change Effects
79+
Register("glow-on-change", "Glow on Change",
80+
"Values that changed since last frame emit a brief glow/pulse",
81+
PageEffectCategory.ValueChange);
82+
83+
Register("flip-digits", "Flip Digits",
84+
"Numbers flip like an airport departure board when changing",
85+
PageEffectCategory.ValueChange);
86+
87+
Register("slide-numbers", "Slide Numbers",
88+
"Digits slide up/down like a slot machine when values change",
89+
PageEffectCategory.ValueChange);
90+
91+
Register("typewriter", "Typewriter",
92+
"Text types out character by character on change",
93+
PageEffectCategory.ValueChange);
94+
95+
Register("particle-burst", "Particle Burst",
96+
"Particles burst from widgets when values change significantly",
97+
PageEffectCategory.ValueChange);
98+
99+
// Container Animation Effects
100+
Register("gentle-float", "Gentle Float",
101+
"Containers float up/down subtly (breathing effect)",
102+
PageEffectCategory.ContainerAnimation);
103+
104+
Register("tilt-3d", "3D Tilt",
105+
"Containers have slight 3D tilt/perspective that shifts",
106+
PageEffectCategory.ContainerAnimation);
107+
108+
Register("shake-on-warning", "Shake on Warning",
109+
"Containers shake when values hit warning/critical thresholds",
110+
PageEffectCategory.ContainerAnimation);
111+
112+
Register("bounce-in", "Bounce In",
113+
"Widgets bounce in when panel first loads",
114+
PageEffectCategory.ContainerAnimation);
115+
116+
Register("wave", "Wave",
117+
"Widgets wave in a sine pattern across the grid",
118+
PageEffectCategory.ContainerAnimation);
119+
120+
// Background/Overlay Effects
121+
Register("scanlines", "Scanlines",
122+
"CRT/retro scanline overlay",
123+
PageEffectCategory.BackgroundOverlay);
124+
125+
Register("matrix-rain", "Matrix Rain",
126+
"Digital rain falling behind widgets",
127+
PageEffectCategory.BackgroundOverlay);
128+
129+
Register("particle-field", "Particle Field",
130+
"Floating particles in the background",
131+
PageEffectCategory.BackgroundOverlay);
132+
133+
Register("grid-pulse", "Grid Pulse",
134+
"Grid lines pulse outward from center",
135+
PageEffectCategory.BackgroundOverlay);
136+
137+
Register("hologram", "Hologram",
138+
"Holographic shimmer/interference pattern",
139+
PageEffectCategory.BackgroundOverlay);
140+
141+
// Character/Mascot Effects
142+
Register("vanna-white", "Vanna White",
143+
"Character walks up to tiles and gestures at them",
144+
PageEffectCategory.CharacterMascot);
145+
146+
Register("pixel-mascot", "Pixel Mascot",
147+
"Retro pixel character reacts to values",
148+
PageEffectCategory.CharacterMascot);
149+
150+
Register("robot-assistant", "Robot Assistant",
151+
"Cute robot points at important metrics",
152+
PageEffectCategory.CharacterMascot);
153+
154+
// Alert/Status Effects
155+
Register("warning-flash", "Warning Flash",
156+
"Panel border flashes when any value is critical",
157+
PageEffectCategory.AlertStatus);
158+
159+
Register("spotlight", "Spotlight",
160+
"Roaming spotlight illuminates different widgets",
161+
PageEffectCategory.AlertStatus);
162+
163+
Register("neon-trails", "Neon Trails",
164+
"Neon light trails follow value changes",
165+
PageEffectCategory.AlertStatus);
166+
167+
Register("glitch", "Glitch",
168+
"Random digital glitch effects on high values",
169+
PageEffectCategory.AlertStatus);
170+
171+
// Debug/Test Effects
172+
Register("red-man", "Red Man",
173+
"Debug overlay - full panel red at 55% opacity",
174+
PageEffectCategory.Other);
175+
}
176+
177+
private void Register(string id, string displayName, string description, PageEffectCategory category)
178+
{
179+
_effects[id] = new PageEffect
180+
{
181+
Id = id,
182+
DisplayName = displayName,
183+
Description = description,
184+
Category = category,
185+
RequiresLiveMode = true
186+
};
187+
}
188+
}

src/LCDPossible.Core/Configuration/ProfileManager.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,8 @@ public void SetDefaults(
355355
int? defaultDuration = null,
356356
int? defaultUpdateInterval = null,
357357
string? defaultTransition = null,
358-
int? defaultTransitionDuration = null)
358+
int? defaultTransitionDuration = null,
359+
string? defaultPageEffect = null)
359360
{
360361
var profile = LoadProfile(profileName);
361362

@@ -389,6 +390,11 @@ public void SetDefaults(
389390
profile.DefaultTransitionDurationMs = defaultTransitionDuration.Value;
390391
}
391392

393+
if (!string.IsNullOrEmpty(defaultPageEffect))
394+
{
395+
profile.DefaultPageEffect = defaultPageEffect;
396+
}
397+
392398
SaveProfile(profile, profileName);
393399
}
394400

0 commit comments

Comments
 (0)