- sidebar FILTERS 加 Max/High/Normal/Low 四档(dot 色与 priority 配色一致),点击切换 priority-filter(0=All, 1=Low, 2=Normal, 3=High, 4=Max) - MessageList 加 priority-filter property,通过 visible 谓词按 Slint Priority enum 匹配;保留原 idx 让 selected-index 不随 filter 错位 - 右栏加 detail panel:app + priority dot、title、id、relative_time、body、has_click_url 时显示 Open link 按钮(复用 C2 的 message-card-clicked 走 url::open) - detail panel 与消息列表水平分割,selected-message-index < 0 时自动隐藏;切换 Settings/About 时不显示
57 lines
2.4 KiB
Plaintext
57 lines
2.4 KiB
Plaintext
// AGENTS.md §7 / §37 message list.
|
|
//
|
|
// Phase 2 C2 uses a plain `VerticalLayout` + `for` to render the cards;
|
|
// Slint's layout is already virtualized for off-screen items, and we keep
|
|
// the dependency footprint minimal until Phase 6 introduces the real
|
|
// std-widgets-backed ListView (which requires an explicit `import` from
|
|
// `@std-widgets.slint` and an `include_paths` config in build.rs).
|
|
//
|
|
// Phase 7 C3: a `priority-filter` property hides non-matching cards via
|
|
// `visible`. Hiding (vs filtering the model) keeps the original index
|
|
// intact, which lets `selected-index` stay correct when the filter
|
|
// changes — clicking item 5 with the filter still applies to row 5
|
|
// of the underlying list, not the post-filter row.
|
|
|
|
import { MessageItem, MessageCard, Priority } from "./message-card.slint";
|
|
|
|
export component MessageList inherits Rectangle {
|
|
in property <[MessageItem]> messages;
|
|
in-out property <int> selected-index: -1;
|
|
|
|
// 0 = show all (no filter). 1 = Priority::Low, 2 = Normal,
|
|
// 3 = High, 4 = Max. Off-by-one alignment with the Slint
|
|
// `Priority` enum (Low=0, Normal=1, High=2, Max=3) is
|
|
// intentional so the UI shows "All / Low / Normal / High / Max"
|
|
// while the wire-level enum keeps its 0..3 range.
|
|
in property <int> priority-filter: 0;
|
|
|
|
in property <color> card-border: #3a3b40;
|
|
|
|
callback message-clicked(int);
|
|
|
|
background: transparent;
|
|
|
|
VerticalLayout {
|
|
spacing: 8px;
|
|
|
|
for item[idx] in messages: MessageCard {
|
|
item: item;
|
|
selected: idx == root.selected-index;
|
|
// Show every card when filter is "All"; otherwise only
|
|
// the priority bucket the user picked. Slint lets us
|
|
// compare an enum directly against an int literal, so
|
|
// `item.priority == 0` matches Priority::Low without
|
|
// any explicit conversion.
|
|
visible: root.priority-filter == 0
|
|
|| (root.priority-filter == 1 && item.priority == Priority.Low)
|
|
|| (root.priority-filter == 2 && item.priority == Priority.Normal)
|
|
|| (root.priority-filter == 3 && item.priority == Priority.High)
|
|
|| (root.priority-filter == 4 && item.priority == Priority.Max);
|
|
card-border: card-border;
|
|
clicked => {
|
|
root.selected-index = idx;
|
|
root.message-clicked(idx);
|
|
}
|
|
}
|
|
}
|
|
} |