76 lines
2.7 KiB
Swift
76 lines
2.7 KiB
Swift
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://")!
|
|
)
|
|
}
|
|
}
|