mirror of
https://github.com/block/buzz.git
synced 2026-11-02 15:31:27 +00:00
## Summary - Simplify agent profiles with Message/Bestie actions, relay-authored published instructions (unavailable without a config channel), management details, public-key copying, and a separate final Delete section. - Sort the Agents directory by name and mark the selected Bestie with a muted filled star. - Place Model and Thinking together below Name. Use native iOS Liquid Glass menus and preserve selection callbacks as controls become enabled. Related: #8685. ## Validation Full mobile checks passed. Regression coverage includes relay-author filtering, unavailable instructions, metadata retry, resizing native pickers, accurate deletion state, selection after loading, and Bestie switching. Real iOS simulator taps verified both pickers; the user confirmed the earlier iPhone build works. Review fixes were checked with widget journeys and the native UIKit resize/selection probe. <details> <summary>Previews</summary> Synthetic fixture renders: | Profile | Create agent | Bestie card | | --- | --- | --- | |  |  |  | Native iOS simulator interaction with a synthetic catalog:  </details> --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
65 lines
2.6 KiB
Swift
65 lines
2.6 KiB
Swift
import Flutter
|
|
import UIKit
|
|
|
|
private final class SettingMenuMessenger: NSObject, FlutterBinaryMessenger {
|
|
var selections: [Int] = []
|
|
func send(onChannel channel: String, message: Data?) {
|
|
guard let message else { return }
|
|
let call = FlutterStandardMethodCodec.sharedInstance().decodeMethodCall(message)
|
|
if call.method == "menuAction", let index = call.arguments as? Int {
|
|
selections.append(index)
|
|
}
|
|
}
|
|
func send(onChannel channel: String, message: Data?, binaryReply callback: FlutterBinaryReply?) {
|
|
send(onChannel: channel, message: message)
|
|
callback?(nil)
|
|
}
|
|
func setMessageHandlerOnChannel(
|
|
_ channel: String, binaryMessageHandler handler: FlutterBinaryMessageHandler?
|
|
) -> FlutterBinaryMessengerConnection { 1 }
|
|
func cleanUpConnection(_ connection: FlutterBinaryMessengerConnection) {}
|
|
}
|
|
|
|
@main
|
|
struct SettingMenuSelectionTests {
|
|
@MainActor static func main() {
|
|
for deferred in [false, true] {
|
|
let messenger = SettingMenuMessenger()
|
|
let view = NavigationGlassButtonPlatformView(
|
|
frame: CGRect(x: 0, y: 0, width: 340, height: 56),
|
|
viewIdentifier: 1,
|
|
arguments: [
|
|
"fillWidth": true, "plain": true, "label": "", "enabled": true,
|
|
"deferMenuActions": deferred,
|
|
"menu": [
|
|
["id": 0, "label": "Low", "enabled": true, "checked": false],
|
|
["id": 1, "label": "High", "enabled": true, "checked": true],
|
|
],
|
|
],
|
|
messenger: messenger
|
|
)
|
|
let button = view.view().subviews.compactMap { $0 as? NavigationGlassButton }.first!
|
|
view.view().layoutIfNeeded()
|
|
view.view().frame.size.width = 600
|
|
view.view().layoutIfNeeded()
|
|
precondition(button.bounds.width == 600)
|
|
precondition(button.point(inside: CGPoint(x: 570, y: 28), with: nil))
|
|
let group = button.menu!.children.first as! UIMenu
|
|
let choices = group.children.compactMap { $0 as? UIAction }
|
|
precondition(choices[0].state == .off && choices[1].state == .on)
|
|
// Invoke the actual menu UIAction through UIKit, without synthesizing a
|
|
// Flutter method-channel message or depending on dismissal callback order.
|
|
let selection = UIButton(primaryAction: choices[0])
|
|
selection.sendActions(for: .touchUpInside)
|
|
precondition(messenger.selections == (deferred ? [] : [0]))
|
|
if deferred {
|
|
precondition(button.pendingMenuAction != nil)
|
|
button.pendingMenuAction?()
|
|
button.pendingMenuAction = nil
|
|
precondition(messenger.selections == [0])
|
|
}
|
|
}
|
|
print("Native setting menu selection checks passed")
|
|
}
|
|
}
|