Add Live Activities as configurable bar items (#30)

* Add Live Activities as configurable bar items

* Fix activity owner monitoring and Morph list interactions

* Keep activity rows stable during updates and tighten their layout

* Use subtle theme tint for activity cards

* Tighten activity title and progress spacing

* Use theme accent for active progress rings

* Fit compact activities to measured titles and badge

* Expose Live Activities display controls in Settings

* Open activity terminals and streamline the Morph header

* Give Morph continuous icons and prioritize workspace navigation

* Show activity progress inside its ring

* Inset activity progress rings and strengthen their stroke

* Fix activity lifecycle, command output handling and list navigation

* Reduce activity update work and harden publisher lifetimes

* Set up Live Activities for the detected user shell during installation

* Document Activities setup, daily use and troubleshooting

* Preserve Morph idle width across empty activity updates

* Fix dimming flicker, hide inactive music tab and consolidate Activities docs

* Fix panel clearance across styles and match previews to theme settings

* Prevent panel blur from repainting neighboring islands

---------

Co-authored-by: Samuel Onoja <[email protected]>
This commit is contained in:
Samuel OnojaandSamuel Onoja authored and GitHub committed 2026-10-12 22:52:25 +01:00
1 parent 7a7df0106c
commit 6b0d903ad0
107 files changed
+9340 -291

No files matched your search

+24
View File
@@ -238,3 +238,27 @@ fn item_options_are_strict_and_metadata_is_explicit() {
.is_err()
);
}
#[test]
fn activities_are_first_class_items_in_every_zone_and_keep_overflow_settings() {
for style in ["flat", "floating", "morph", "adaptive"] {
for zone in ["start", "center", "end"] {
let source = format!(
"panel main {{ style {style}; {zone} {{ group tasks {{ item builds kind=activities priority=20 overflow=always; }}; }}; }}"
);
let mut doc = ferese_config::Document::parse(&source).unwrap();
let panels: Vec<Panel> = serde_json::from_value(doc.get("panels").unwrap().clone()).unwrap();
ferese_panel::validate(&panels).unwrap();
let parsed = match zone {
"start" => &panels[0].start,
"center" => &panels[0].center,
_ => &panels[0].end,
};
assert_eq!(parsed.groups[0].items[0].kind, ferese_panel::ItemKind::Activities);
assert_eq!(parsed.groups[0].items[0].overflow, ferese_panel::OverflowPolicy::Always);
doc.set("panels", serde_json::to_value(&panels).unwrap()).unwrap();
let restored = ferese_config::Document::parse(&doc.to_string()).unwrap();
assert_eq!(restored.get("panels"), doc.get("panels"));
}
}
}