74 lines
3.5 KiB
Swift
74 lines
3.5 KiB
Swift
import Foundation
|
|
import UIKit
|
|
|
|
@MainActor
|
|
final class GitCallbackHandler {
|
|
|
|
private let store: GitStore
|
|
init(store: GitStore) { self.store = store }
|
|
|
|
func handle(url: URL) {
|
|
guard url.scheme == "padxcode", url.host == "git-callback" else { return }
|
|
let params = parseQuery(url)
|
|
store.pendingOperation = nil
|
|
switch params["action"] ?? "" {
|
|
case "repos": handleRepos(params)
|
|
case "status": handleStatus(params)
|
|
case "log": handleLog(params)
|
|
case "branches": handleBranches(params)
|
|
case "checkout": NotificationCenter.default.post(name: .gitCheckoutCompleted, object: nil)
|
|
case "commit": store.fileStatuses = []; NotificationCenter.default.post(name: .gitCommitCompleted, object: nil)
|
|
case "push": NotificationCenter.default.post(name: .gitPushCompleted, object: nil)
|
|
case "pull","fetch": NotificationCenter.default.post(name: .gitSyncCompleted, object: nil)
|
|
case "merge": NotificationCenter.default.post(name: .gitMergeCompleted, object: nil)
|
|
case "write": NotificationCenter.default.post(name: .gitWriteCompleted, object: nil)
|
|
case "read": handleRead(params)
|
|
case "error":
|
|
let msg = params["errorMessage"] ?? "Working Copy error."
|
|
store.lastError = msg
|
|
NotificationCenter.default.post(name: .gitOperationFailed, object: nil,
|
|
userInfo: ["message": msg])
|
|
default: break
|
|
}
|
|
}
|
|
|
|
private func handleRepos(_ p: [String: String]) {
|
|
guard let json = extractJSON(p),
|
|
let repos = try? JSONDecoder().decode([GitRepository].self, from: json) else { return }
|
|
store.repositories = repos
|
|
}
|
|
private func handleStatus(_ p: [String: String]) {
|
|
guard let json = extractJSON(p),
|
|
let statuses = try? JSONDecoder().decode([GitFileStatus].self, from: json) else { return }
|
|
store.fileStatuses = statuses.filter { $0.status != "unchanged" }
|
|
}
|
|
private func handleLog(_ p: [String: String]) {
|
|
guard let json = extractJSON(p),
|
|
let commits = try? JSONDecoder().decode([GitCommit].self, from: json) else { return }
|
|
store.commitLog = commits
|
|
}
|
|
private func handleBranches(_ p: [String: String]) {
|
|
guard let json = extractJSON(p),
|
|
let branches = try? JSONDecoder().decode([GitBranch].self, from: json) else { return }
|
|
store.branches = branches
|
|
if let current = branches.first(where: { !$0.isRemote }) { store.currentBranch = current.name }
|
|
}
|
|
private func handleRead(_ p: [String: String]) {
|
|
guard let repo = p["repo"], let path = p["path"], let text = p["text"] else { return }
|
|
let decoded = text.removingPercentEncoding ?? text
|
|
NotificationCenter.default.post(name: .gitReadCompleted, object: nil,
|
|
userInfo: ["repo": repo, "path": path, "content": decoded])
|
|
}
|
|
|
|
private func extractJSON(_ params: [String: String]) -> Data? {
|
|
let raw = params[""] ?? params["text"] ?? ""
|
|
return (raw.removingPercentEncoding ?? raw).data(using: .utf8)
|
|
}
|
|
private func parseQuery(_ url: URL) -> [String: String] {
|
|
guard let items = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
|
|
else { return [:] }
|
|
var result: [String: String] = [:]
|
|
for item in items { result[item.name] = item.value ?? "" }
|
|
return result
|
|
}
|
|
}
|