IOS updates
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import Foundation
|
||||
|
||||
enum WorkspaceKind: String, Codable, CaseIterable, Sendable {
|
||||
case personal
|
||||
case team
|
||||
}
|
||||
|
||||
enum WorkspaceRole: String, Codable, CaseIterable, Sendable {
|
||||
case owner
|
||||
case admin
|
||||
case developer
|
||||
case viewer
|
||||
}
|
||||
|
||||
struct SonarWorkspace: Codable, Identifiable, Hashable, Sendable {
|
||||
var id: UUID
|
||||
var name: String
|
||||
var kind: WorkspaceKind
|
||||
var role: WorkspaceRole
|
||||
var serverIDs: [UUID]
|
||||
var createdAt: Date
|
||||
var updatedAt: Date
|
||||
|
||||
init(id: UUID = UUID(), name: String, kind: WorkspaceKind, role: WorkspaceRole,
|
||||
serverIDs: [UUID] = [], createdAt: Date = Date(), updatedAt: Date = Date()) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.kind = kind
|
||||
self.role = role
|
||||
self.serverIDs = serverIDs
|
||||
self.createdAt = createdAt
|
||||
self.updatedAt = updatedAt
|
||||
}
|
||||
|
||||
static let personal = SonarWorkspace(
|
||||
id: UUID(uuidString: "00000000-0000-0000-0000-000000000001")!,
|
||||
name: "Personal",
|
||||
kind: .personal,
|
||||
role: .owner
|
||||
)
|
||||
}
|
||||
|
||||
struct WorkspaceMember: Codable, Identifiable, Hashable, Sendable {
|
||||
var id: UUID
|
||||
var workspaceID: UUID
|
||||
var displayName: String
|
||||
var role: WorkspaceRole
|
||||
var joinedAt: Date
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
final class WorkspaceStore: ObservableObject {
|
||||
@Published private(set) var workspaces: [SonarWorkspace] = [.personal]
|
||||
@Published var selectedWorkspaceID: UUID = SonarWorkspace.personal.id
|
||||
|
||||
private let driveStore = ICloudDriveStore.shared
|
||||
private let fileName = "workspaces.json"
|
||||
|
||||
var selectedWorkspace: SonarWorkspace {
|
||||
workspaces.first(where: { $0.id == selectedWorkspaceID }) ?? .personal
|
||||
}
|
||||
|
||||
init() {
|
||||
load()
|
||||
}
|
||||
|
||||
func load() {
|
||||
do {
|
||||
guard let saved = try driveStore.read([SonarWorkspace].self, fileName: fileName), !saved.isEmpty else {
|
||||
persist()
|
||||
return
|
||||
}
|
||||
workspaces = saved
|
||||
if !workspaces.contains(where: { $0.id == selectedWorkspaceID }) {
|
||||
selectedWorkspaceID = workspaces.first?.id ?? SonarWorkspace.personal.id
|
||||
}
|
||||
} catch {
|
||||
// Keep Personal usable if iCloud is temporarily unavailable.
|
||||
workspaces = [.personal]
|
||||
}
|
||||
}
|
||||
|
||||
func createTeam(name: String) {
|
||||
let clean = name.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !clean.isEmpty else { return }
|
||||
let team = SonarWorkspace(name: clean, kind: .team, role: .owner)
|
||||
workspaces.append(team)
|
||||
selectedWorkspaceID = team.id
|
||||
persist()
|
||||
}
|
||||
|
||||
func select(_ workspace: SonarWorkspace) {
|
||||
selectedWorkspaceID = workspace.id
|
||||
}
|
||||
|
||||
private func persist() {
|
||||
try? driveStore.write(workspaces, fileName: fileName)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user