fix: ControlSchema tolerate missing options field (Filler etc)

This commit is contained in:
yumoqing 2026-06-21 23:18:53 +08:00
parent 5ba2ae163b
commit c72a018764
5 changed files with 57 additions and 35 deletions

View File

@ -80,11 +80,13 @@ struct MenuControl: View {
}
@ViewBuilder
private func menuItemView(_ item: MenuItemSchema, depth: Int) -> some View {
private func menuItemView(_ item: MenuItemSchema, depth: Int) -> AnyView {
let hasChildren = !(item.submenu?.isEmpty ?? true)
let isExpanded = expandedItems.contains(item.name)
let isSelected = selectedItem == item.name
return AnyView(
VStack(alignment: .leading, spacing: 0) {
Button(action: { handleMenuClick(item, hasChildren: hasChildren) }) {
HStack(spacing: 8) {
if let icon = item.icon {
@ -118,6 +120,8 @@ struct MenuControl: View {
}
}
}
)
}
private func handleMenuClick(_ item: MenuItemSchema, hasChildren: Bool) {
if hasChildren {
@ -173,7 +177,11 @@ struct PopupWindowControl: View {
.padding(12)
}
}
#if os(iOS)
.background(Color(.systemBackground))
#else
.background(Color(nsColor: .windowBackgroundColor))
#endif
.cornerRadius(12)
.shadow(radius: 8)
}

View File

@ -140,7 +140,7 @@ public final class BricksEngine: ObservableObject {
}
/// bind
public func handleBind(_ bind: BindSchema, sourceId: String, eventData: EventData = [:]) async {
public func handleBind(_ bind: BindSchema, sourceId: String, eventData: EventData = EventData()) async {
guard let actionType = ActionType(rawValue: bind.actiontype) else {
print("[SwiftBricks] Invalid actiontype: \(bind.actiontype)")
return
@ -306,7 +306,7 @@ public final class BricksEngine: ObservableObject {
// MARK: -
/// widget
public func triggerEvent(widgetId: String, event: String, data: EventData = [:]) async {
public func triggerEvent(widgetId: String, event: String, data: EventData = EventData()) async {
await eventBus.dispatch("\(widgetId).\(event)", data: data)
}

View File

@ -34,7 +34,7 @@ public final class BricksEventBus: ObservableObject {
// MARK: -
///
public func dispatch(_ eventName: String, data: EventData = [:]) async {
public func dispatch(_ eventName: String, data: EventData = EventData()) async {
//
eventLog.append((name: eventName, data: data, timestamp: Date()))
if eventLog.count > maxLogSize {
@ -50,7 +50,7 @@ public final class BricksEventBus: ObservableObject {
}
/// UI
public func dispatchSync(_ eventName: String, data: EventData = [:]) {
public func dispatchSync(_ eventName: String, data: EventData = EventData()) {
Task { @MainActor in
await dispatch(eventName, data: data)
}

View File

@ -131,7 +131,7 @@ public final class BricksRPC: ObservableObject {
throw BricksRPCError.invalidResponse
}
let responseHeaders = Dictionary(
let responseHeaders: [String: String] = Dictionary(
uniqueKeysWithValues: httpResponse.allHeaderFields.compactMap { key, value in
guard let keyStr = key as? String, let valStr = value as? String else { return nil }
return (keyStr, valStr)

View File

@ -30,6 +30,20 @@ public struct ControlSchema: Codable, Identifiable, Sendable {
self.binds = binds
self.subwidgets = subwidgets
}
/// optionsFilleroptionswidget
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decodeIfPresent(String.self, forKey: .id)
self.widgettype = try container.decode(String.self, forKey: .widgettype)
self.options = try container.decodeIfPresent(ControlOptions.self, forKey: .options) ?? ControlOptions()
self.binds = try container.decodeIfPresent([BindSchema].self, forKey: .binds)
self.subwidgets = try container.decodeIfPresent([ControlSchema].self, forKey: .subwidgets)
}
private enum CodingKeys: String, CodingKey {
case id, widgettype, options, binds, subwidgets
}
}
/// 使+Codable