diff --git a/sphinx/Scenes/Dashboard/Workspaces/Mocks/HiveFeatureMocks.swift b/sphinx/Scenes/Dashboard/Workspaces/Mocks/HiveFeatureMocks.swift index 39f7c4ae..7b9f8cd1 100644 --- a/sphinx/Scenes/Dashboard/Workspaces/Mocks/HiveFeatureMocks.swift +++ b/sphinx/Scenes/Dashboard/Workspaces/Mocks/HiveFeatureMocks.swift @@ -119,7 +119,18 @@ extension WorkspaceTask { "updatedAt": "2026-03-03T09:00:00Z" ] as [String: Any]) - return [json1, json2, json3, json4].compactMap { WorkspaceTask(json: $0) } + let json5 = JSON([ + "id": "task-halted-001", + "title": "Fix authentication token refresh", + "status": "IN_PROGRESS", + "priority": "HIGH", + "workflowStatus": "HALTED", + "chatMessageCount": 2, + "repository": ["name": "sphinx-ios-v2"], + "updatedAt": "2026-03-04T11:00:00Z" + ] as [String: Any]) + + return [json1, json2, json3, json4, json5].compactMap { WorkspaceTask(json: $0) } } } diff --git a/sphinx/Scenes/Dashboard/Workspaces/TaskChatViewController.swift b/sphinx/Scenes/Dashboard/Workspaces/TaskChatViewController.swift index 9a3e6780..266a0a53 100644 --- a/sphinx/Scenes/Dashboard/Workspaces/TaskChatViewController.swift +++ b/sphinx/Scenes/Dashboard/Workspaces/TaskChatViewController.swift @@ -381,7 +381,9 @@ class TaskChatViewController: UIViewController { workflowStatusView.onRetryTapped = { [weak self] in guard let self else { return } - API.sharedInstance.retryTaskWorkflowWithAuth(taskId: self.task.id, callback: {}, errorCallback: {}) + API.sharedInstance.retryTaskWorkflowWithAuth(taskId: self.task.id, callback: { [weak self] in + DispatchQueue.main.async { self?.applyWorkflowStatus(.IN_PROGRESS) } + }, errorCallback: {}) } chatTableView.keyboardDismissMode = .interactive @@ -869,7 +871,7 @@ class TaskChatViewController: UIViewController { private func applyWorkflowStatus(_ status: WorkflowStatus, animated: Bool = true) { workflowStatusView.status = status switch status { - case .IN_PROGRESS, .HALTED: + case .IN_PROGRESS: updateStatusViewHeight() workflowStatusView.show(animated: animated) if animated { @@ -878,6 +880,15 @@ class TaskChatViewController: UIViewController { self.view.layoutIfNeeded() } setInputEnabled(false) + case .HALTED: + updateStatusViewHeight() + workflowStatusView.show(animated: animated) + if animated { + UIView.animate(withDuration: 0.2) { self.view.layoutIfNeeded() } + } else { + self.view.layoutIfNeeded() + } + setInputEnabled(true) case .PENDING, .COMPLETED, .ERROR, .FAILED: workflowStatusView.setStepDetail(nil) workflowStatusHeightConstraint.constant = 0 diff --git a/sphinx/Scenes/Dashboard/Workspaces/WorkspaceTasksViewController.swift b/sphinx/Scenes/Dashboard/Workspaces/WorkspaceTasksViewController.swift index 752e793d..d494ccca 100644 --- a/sphinx/Scenes/Dashboard/Workspaces/WorkspaceTasksViewController.swift +++ b/sphinx/Scenes/Dashboard/Workspaces/WorkspaceTasksViewController.swift @@ -180,7 +180,13 @@ extension WorkspaceTasksViewController: UITableViewDataSource, UITableViewDelega cell.onRetryWorkflowTapped = { [weak self] in guard let self else { return } let task = self.tasks[indexPath.row] - API.sharedInstance.retryTaskWorkflowWithAuth(taskId: task.id, callback: {}, errorCallback: {}) + API.sharedInstance.retryTaskWorkflowWithAuth(taskId: task.id, callback: { [weak self] in + DispatchQueue.main.async { + guard let self else { return } + self.tasks[indexPath.row].workflowStatus = "IN_PROGRESS" + self.tableView.reloadRows(at: [indexPath], with: .none) + } + }, errorCallback: {}) } return cell }