From 83ec862aaf0c79bf3e3911e8c08c94b8f2495e0b Mon Sep 17 00:00:00 2001 From: Shx Guo Date: Wed, 31 May 2023 11:37:55 +0800 Subject: [PATCH 1/5] Fix that codeium cancellation error is presented to UI --- .../SuggestionPresenter/PresentInWindowSuggestionPresenter.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/Sources/Service/SuggestionPresenter/PresentInWindowSuggestionPresenter.swift b/Core/Sources/Service/SuggestionPresenter/PresentInWindowSuggestionPresenter.swift index 904172b8..4e09de2b 100644 --- a/Core/Sources/Service/SuggestionPresenter/PresentInWindowSuggestionPresenter.swift +++ b/Core/Sources/Service/SuggestionPresenter/PresentInWindowSuggestionPresenter.swift @@ -28,6 +28,7 @@ struct PresentInWindowSuggestionPresenter { func presentError(_ error: Error) { if error is CancellationError { return } + if let urlError = error as? URLError, urlError.code == URLError.cancelled { return } Task { @MainActor in let controller = GraphicalUserInterfaceController.shared.suggestionWidget controller.presentError(error.localizedDescription) From bd3100a0d7e76a37811c121f1177b4707926a454 Mon Sep 17 00:00:00 2001 From: Shx Guo Date: Wed, 31 May 2023 12:08:55 +0800 Subject: [PATCH 2/5] Tweak widget processing indicator --- .../SuggestionWidgetController.swift | 20 +++++++----- .../Sources/SuggestionWidget/WidgetView.swift | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift b/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift index 74fe11c0..3d395bca 100644 --- a/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift +++ b/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift @@ -275,7 +275,7 @@ public final class SuggestionWidgetController: NSObject { public extension SuggestionWidgetController { func suggestCode(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { if let suggestion = await dataSource?.suggestionForFile(at: fileURL) { suggestionPanelViewModel.content = .suggestion(suggestion) @@ -285,24 +285,28 @@ public extension SuggestionWidgetController { } func discardSuggestion(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } } func markAsProcessing(_ isProcessing: Bool) { - widgetViewModel.isProcessing = isProcessing + if isProcessing { + widgetViewModel.markIsProcessing() + } else { + widgetViewModel.endIsProcessing() + } } func presentError(_ errorDescription: String) { suggestionPanelViewModel.content = .error(errorDescription) suggestionPanelViewModel.isPanelDisplayed = true - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() } func presentChatRoom(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { if let chat = await dataSource?.chatForFile(at: fileURL) { chatWindowViewModel.chat = chat @@ -343,14 +347,14 @@ public extension SuggestionWidgetController { } func closeChatRoom(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } } func presentPromptToCode(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { if let provider = await dataSource?.promptToCodeForFile(at: fileURL) { suggestionPanelViewModel.content = .promptToCode(provider) @@ -367,7 +371,7 @@ public extension SuggestionWidgetController { } func discardPromptToCode(fileURL: URL) { - widgetViewModel.isProcessing = false + widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } diff --git a/Core/Sources/SuggestionWidget/WidgetView.swift b/Core/Sources/SuggestionWidget/WidgetView.swift index 50bfae00..9ce240c2 100644 --- a/Core/Sources/SuggestionWidget/WidgetView.swift +++ b/Core/Sources/SuggestionWidget/WidgetView.swift @@ -6,9 +6,40 @@ import SwiftUI @MainActor final class WidgetViewModel: ObservableObject { + struct IsProcessingCounter { + var expirationDate: TimeInterval + } + + private var isProcessingCounters = [IsProcessingCounter]() + private var cleanupIsProcessingCounterTask: Task? @Published var isProcessing: Bool @Published var currentFileURL: URL? + func markIsProcessing(date: Date = Date()) { + let deadline = date.timeIntervalSince1970 + 20 + isProcessingCounters.append(IsProcessingCounter(expirationDate: deadline)) + isProcessing = true + + cleanupIsProcessingCounterTask?.cancel() + cleanupIsProcessingCounterTask = Task { [weak self] in + try await Task.sleep(nanoseconds: 20 * 1_000_000_000) + try Task.checkCancellation() + Task { @MainActor [weak self] in + guard let self else { return } + isProcessingCounters.removeAll() + isProcessing = false + } + } + } + + func endIsProcessing(date: Date = Date()) { + if !isProcessingCounters.isEmpty { + isProcessingCounters.removeFirst() + } + isProcessingCounters.removeAll(where: { $0.expirationDate < date.timeIntervalSince1970 }) + isProcessing = !isProcessingCounters.isEmpty + } + init(isProcessing: Bool = false) { self.isProcessing = isProcessing } From fefa78683c59a7f7ef9e4934a3ddb3ed2c69a443 Mon Sep 17 00:00:00 2001 From: Shx Guo Date: Wed, 31 May 2023 12:10:49 +0800 Subject: [PATCH 3/5] Bump version 0.17.0 --- Version.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Version.xcconfig b/Version.xcconfig index ce111d9e..f45a2716 100644 --- a/Version.xcconfig +++ b/Version.xcconfig @@ -1,2 +1,2 @@ -APP_VERSION = 0.17.0 -APP_BUILD = 170 +APP_VERSION = 0.17.1 +APP_BUILD = 171 From 2f408663ee53b517b0a44f964e3e01056892b04e Mon Sep 17 00:00:00 2001 From: Shx Guo Date: Wed, 31 May 2023 12:25:51 +0800 Subject: [PATCH 4/5] Update widget animation --- .../SuggestionWidgetController.swift | 13 ++++++------- Core/Sources/SuggestionWidget/WidgetView.swift | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift b/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift index 3d395bca..88087ec9 100644 --- a/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift +++ b/Core/Sources/SuggestionWidget/SuggestionWidgetController.swift @@ -275,8 +275,9 @@ public final class SuggestionWidgetController: NSObject { public extension SuggestionWidgetController { func suggestCode(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { + markAsProcessing(true) + defer { markAsProcessing(false) } if let suggestion = await dataSource?.suggestionForFile(at: fileURL) { suggestionPanelViewModel.content = .suggestion(suggestion) suggestionPanelViewModel.isPanelDisplayed = true @@ -285,7 +286,6 @@ public extension SuggestionWidgetController { } func discardSuggestion(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } @@ -302,12 +302,12 @@ public extension SuggestionWidgetController { func presentError(_ errorDescription: String) { suggestionPanelViewModel.content = .error(errorDescription) suggestionPanelViewModel.isPanelDisplayed = true - widgetViewModel.endIsProcessing() } func presentChatRoom(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { + markAsProcessing(true) + defer { markAsProcessing(false) } if let chat = await dataSource?.chatForFile(at: fileURL) { chatWindowViewModel.chat = chat chatWindowViewModel.isPanelDisplayed = true @@ -347,15 +347,15 @@ public extension SuggestionWidgetController { } func closeChatRoom(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } } func presentPromptToCode(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { + markAsProcessing(true) + defer { markAsProcessing(false) } if let provider = await dataSource?.promptToCodeForFile(at: fileURL) { suggestionPanelViewModel.content = .promptToCode(provider) suggestionPanelViewModel.isPanelDisplayed = true @@ -371,7 +371,6 @@ public extension SuggestionWidgetController { } func discardPromptToCode(fileURL: URL) { - widgetViewModel.endIsProcessing() Task { await updateContentForActiveEditor(fileURL: fileURL) } diff --git a/Core/Sources/SuggestionWidget/WidgetView.swift b/Core/Sources/SuggestionWidget/WidgetView.swift index 9ce240c2..305214b0 100644 --- a/Core/Sources/SuggestionWidget/WidgetView.swift +++ b/Core/Sources/SuggestionWidget/WidgetView.swift @@ -12,7 +12,7 @@ final class WidgetViewModel: ObservableObject { private var isProcessingCounters = [IsProcessingCounter]() private var cleanupIsProcessingCounterTask: Task? - @Published var isProcessing: Bool + @Published private(set) var isProcessing: Bool @Published var currentFileURL: URL? func markIsProcessing(date: Date = Date()) { From 468ad8423eacba80d60e5dce221a94748be11644 Mon Sep 17 00:00:00 2001 From: Shx Guo Date: Wed, 31 May 2023 12:34:38 +0800 Subject: [PATCH 5/5] Update appcast.xml --- appcast.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/appcast.xml b/appcast.xml index 1f42d684..41bb3495 100644 --- a/appcast.xml +++ b/appcast.xml @@ -3,6 +3,18 @@ Copilot for Xcode + + 0.17.1 + Wed, 31 May 2023 12:30:21 +0800 + 171 + 0.17.1 + 12.0 + + https://github.com/intitni/CopilotForXcode/releases/tag/0.17.1 + + + + 0.17.0 Sat, 27 May 2023 15:33:25 +0800