mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
fix(mobile): keep saved Solo retries available outside discovery
Allow locked retries to return their saved agent to Flutter for authoritative ownership revalidation. Keep inventory membership required for new chats and cover both native button and submit gates across inventory refreshes. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ struct MeAgentAccessibilityTests {
|
||||
@MainActor static func main() {
|
||||
for locked in [false, true] {
|
||||
for empty in [false, true] {
|
||||
var submitted: [String: String]?
|
||||
let controller = NativeProfileTextEditorViewController(
|
||||
title: "New chat", initialValue: "Chat", placeholder: "Chat name",
|
||||
multiline: false, pageBackgroundColor: .systemGroupedBackground,
|
||||
@@ -14,8 +15,8 @@ struct MeAgentAccessibilityTests {
|
||||
channelDescription: nil, originalName: nil, originalDescription: nil,
|
||||
canEditDetails: true, canEditCanvas: false, canvasContent: "",
|
||||
canvasLoaded: false,
|
||||
chatOptions: ["presentationId": "test", "assistantsLoading": empty, "fieldsLocked": locked, "assistants": empty ? [] : [["id": "agent", "name": "Agent"]]],
|
||||
onCancel: {}, onSet: { _ in }
|
||||
chatOptions: ["selectedAssistant": "agent", "presentationId": "test", "assistantsLoading": empty, "fieldsLocked": locked, "assistants": empty ? [] : [["id": "agent", "name": "Agent"]]],
|
||||
onCancel: {}, onSet: { submitted = $0 as? [String: String] }
|
||||
)
|
||||
controller.loadViewIfNeeded()
|
||||
precondition(controller.numberOfSections(in: controller.tableView) == 3)
|
||||
@@ -31,6 +32,11 @@ struct MeAgentAccessibilityTests {
|
||||
precondition(cell.accessibilityTraits.contains(.notEnabled) == disabled)
|
||||
precondition(cell.accessibilityTraits.contains(.button) == !disabled)
|
||||
precondition((cell.selectionStyle == .none) == disabled)
|
||||
let canSubmit = locked || !empty
|
||||
precondition(controller.navigationItem.rightBarButtonItem?.isEnabled == canSubmit)
|
||||
// Invoke the action even when disabled to check its independent gate.
|
||||
_ = controller.perform(NSSelectorFromString("setTapped"))
|
||||
precondition(submitted?["assistant"] == (canSubmit ? "agent" : nil))
|
||||
if empty && !locked {
|
||||
controller.tableView.frame = CGRect(x: 0, y: 0, width: 390, height: 844)
|
||||
controller.tableView.reloadData()
|
||||
@@ -47,6 +53,14 @@ struct MeAgentAccessibilityTests {
|
||||
precondition(!updated.accessibilityTraits.contains(.notEnabled))
|
||||
precondition(controller.tableView(controller.tableView, titleForFooterInSection: 2) == nil)
|
||||
}
|
||||
submitted = nil
|
||||
controller.updateChatAssistants([
|
||||
"presentationId": "test",
|
||||
"assistants": empty ? [] : [["id": "agent", "name": "Agent"]],
|
||||
])
|
||||
precondition(controller.navigationItem.rightBarButtonItem?.isEnabled == canSubmit)
|
||||
_ = controller.perform(NSSelectorFromString("setTapped"))
|
||||
precondition(submitted?["assistant"] == (canSubmit ? "agent" : nil))
|
||||
}
|
||||
}
|
||||
avatarTests()
|
||||
|
||||
@@ -449,13 +449,20 @@ private final class NativeProfileTextEditorViewController:
|
||||
updateNavigation()
|
||||
}
|
||||
|
||||
// A durable retry keeps its saved recipient even if discovery hides it.
|
||||
// Flutter revalidates ownership before any creation writes.
|
||||
private var canSubmitAssistant: Bool {
|
||||
guard let selectedAssistant else { return false }
|
||||
return fieldsLocked || assistants.contains { $0["id"] == selectedAssistant }
|
||||
}
|
||||
|
||||
private func updateNavigation() {
|
||||
navigationItem.rightBarButtonItem?.isEnabled = canEditDetails && hasUnsavedChanges
|
||||
&& (!isChannelEditor || !canonicalChannelName.isEmpty)
|
||||
&& (!isChatEditor || (
|
||||
!currentValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||
&& currentValue.count <= 120
|
||||
&& (isProjectEditor || assistants.contains { $0["id"] == selectedAssistant })
|
||||
&& (isProjectEditor || canSubmitAssistant)
|
||||
))
|
||||
navigationController?.isModalInPresentation = hasUnsavedChanges
|
||||
placeholderLabel.isHidden = !textView.text.isEmpty
|
||||
@@ -497,7 +504,7 @@ private final class NativeProfileTextEditorViewController:
|
||||
onSet(name)
|
||||
} else if isChatEditor {
|
||||
guard let selectedAssistant,
|
||||
assistants.contains(where: { $0["id"] == selectedAssistant }),
|
||||
canSubmitAssistant,
|
||||
!currentValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
|
||||
currentValue.count <= 120 else { return }
|
||||
onSet(["name": currentValue, "assistant": selectedAssistant, "project": selectedProject ?? ""])
|
||||
|
||||
Reference in New Issue
Block a user