装饰
This commit is contained in:
@@ -38,6 +38,12 @@ pub struct OverlaySettings {
|
||||
pub font_family: FontFamilyId,
|
||||
#[serde(default = "default_font_brightness")]
|
||||
pub font_brightness: u16,
|
||||
/// Optional per-component overrides. `None` keeps the selected theme's
|
||||
/// palette, which makes future theme changes immediately visible.
|
||||
#[serde(default)]
|
||||
pub viewer_color: Option<String>,
|
||||
#[serde(default)]
|
||||
pub danmaku_color: Option<String>,
|
||||
#[serde(default = "default_font_scale")]
|
||||
pub font_scale: u16,
|
||||
pub show_danmaku: bool,
|
||||
@@ -68,6 +74,8 @@ impl Default for OverlaySettings {
|
||||
theme_id: OverlayThemeId::default(),
|
||||
font_family: FontFamilyId::default(),
|
||||
font_brightness: default_font_brightness(),
|
||||
viewer_color: None,
|
||||
danmaku_color: None,
|
||||
font_scale: default_font_scale(),
|
||||
show_danmaku: true,
|
||||
show_enter: true,
|
||||
@@ -93,6 +101,8 @@ impl OverlaySettings {
|
||||
pub fn sanitize(mut self) -> Self {
|
||||
self.max_visible = self.max_visible.clamp(1, 12);
|
||||
self.font_brightness = sanitize_font_brightness(self.font_brightness);
|
||||
self.viewer_color = sanitize_optional_hex_color(self.viewer_color);
|
||||
self.danmaku_color = sanitize_optional_hex_color(self.danmaku_color);
|
||||
self.font_scale = self.font_scale.clamp(50, 300);
|
||||
self.collapse_after_seconds = self.collapse_after_seconds.clamp(2, 120);
|
||||
self.unfold_duration_ms = self.unfold_duration_ms.clamp(200, 5_000);
|
||||
@@ -106,6 +116,14 @@ impl OverlaySettings {
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_optional_hex_color(value: Option<String>) -> Option<String> {
|
||||
let value = value?.trim().to_ascii_uppercase();
|
||||
(value.len() == 7
|
||||
&& value.starts_with('#')
|
||||
&& value[1..].bytes().all(|byte| byte.is_ascii_hexdigit()))
|
||||
.then_some(value)
|
||||
}
|
||||
|
||||
fn default_font_scale() -> u16 {
|
||||
140
|
||||
}
|
||||
@@ -557,6 +575,8 @@ mod tests {
|
||||
let settings = OverlaySettings {
|
||||
font_scale: 999,
|
||||
font_brightness: 1,
|
||||
viewer_color: Some(" #a1b2c3 ".into()),
|
||||
danmaku_color: Some("not-css".into()),
|
||||
max_visible: 99,
|
||||
collapse_after_seconds: 1,
|
||||
unfold_duration_ms: 9_000,
|
||||
@@ -570,6 +590,8 @@ mod tests {
|
||||
.sanitize();
|
||||
assert_eq!(settings.font_scale, 300);
|
||||
assert_eq!(settings.font_brightness, 70);
|
||||
assert_eq!(settings.viewer_color.as_deref(), Some("#A1B2C3"));
|
||||
assert_eq!(settings.danmaku_color, None);
|
||||
assert_eq!(settings.max_visible, 12);
|
||||
assert_eq!(settings.collapse_after_seconds, 2);
|
||||
assert_eq!(settings.unfold_duration_ms, 5_000);
|
||||
@@ -594,6 +616,8 @@ mod tests {
|
||||
object.remove("fontScale");
|
||||
object.remove("fontFamily");
|
||||
object.remove("fontBrightness");
|
||||
object.remove("viewerColor");
|
||||
object.remove("danmakuColor");
|
||||
object.remove("unfoldDurationMs");
|
||||
object.remove("particleCount");
|
||||
object.remove("particleSpeed");
|
||||
@@ -602,6 +626,8 @@ mod tests {
|
||||
assert_eq!(settings.theme_id, OverlayThemeId::JadeScroll);
|
||||
assert_eq!(settings.font_family, FontFamilyId::FangSong);
|
||||
assert_eq!(settings.font_brightness, 130);
|
||||
assert_eq!(settings.viewer_color, None);
|
||||
assert_eq!(settings.danmaku_color, None);
|
||||
assert_eq!(settings.font_scale, 140);
|
||||
assert_eq!(settings.unfold_duration_ms, 1_000);
|
||||
assert_eq!(settings.particle_count, 8);
|
||||
|
||||
Reference in New Issue
Block a user