import Foundation import SwiftUI import UIKit struct GitRepository: Identifiable, Codable { var id: String { name } let name: String; let branch: String; let head: String let status: String; let remotes: [GitRemote] } struct GitRemote: Codable { let name: String; let url: String; let fetch: Bool; let push: Bool } struct GitFileStatus: Identifiable, Codable { var id: String { path } let name: String; let path: String; let status: String; let kind: String var statusIcon: String { switch status { case "modified": return "pencil.circle.fill" case "added": return "plus.circle.fill" case "deleted": return "minus.circle.fill" case "untracked": return "questionmark.circle.fill" default: return "circle" } } var statusSwiftUIColor: Color { switch status { case "modified": return .orange case "added": return .green case "deleted": return .red case "untracked": return .secondary default: return .primary } } } struct GitCommit: Identifiable, Codable { var id: String { commitId } let summary: String; let commitId: String; let author: String let timestamp: String; let description: String var shortId: String { String(commitId.prefix(7)) } var formattedDate: String { let iso = ISO8601DateFormatter() iso.formatOptions = [.withInternetDateTime, .withFractionalSeconds] guard let d = iso.date(from: timestamp) else { return timestamp } let f = RelativeDateTimeFormatter(); f.unitsStyle = .abbreviated return f.localizedString(for: d, relativeTo: Date()) } enum CodingKeys: String, CodingKey { case summary, author, timestamp, description; case commitId = "id" } } struct GitBranch: Identifiable, Codable { var id: String { name } let name: String; let head: String; let latest: String var isRemote: Bool { name.hasPrefix("origin/") } var localName: String { name.replacingOccurrences(of: "origin/", with: "") } } @MainActor final class GitStore: ObservableObject { @Published var repositories: [GitRepository] = [] @Published var activeRepo: String = "" @Published var currentBranch: String = "main" @Published var fileStatuses: [GitFileStatus] = [] @Published var commitLog: [GitCommit] = [] @Published var branches: [GitBranch] = [] @Published var isWorkingCopyInstalled = false @Published var pendingOperation: String? @Published var lastError: String? func checkInstallation() { isWorkingCopyInstalled = UIApplication.shared.canOpenURL( URL(string: "working-copy://")! ) } }