137 lines
No EOL
3.6 KiB
Swift
137 lines
No EOL
3.6 KiB
Swift
import Foundation
|
|
|
|
// Credentials for connecting to the PDS
|
|
struct PDSCredentials: Sendable {
|
|
var serverURL: String
|
|
var username: String
|
|
var password: String
|
|
|
|
init?(serverURL: String, username: String, password: String) {
|
|
// Validate inputs
|
|
guard !serverURL.isEmpty, !username.isEmpty, !password.isEmpty else {
|
|
return nil
|
|
}
|
|
|
|
self.serverURL = serverURL
|
|
self.username = username
|
|
self.password = password
|
|
}
|
|
}
|
|
|
|
// Shared date formatters to improve performance
|
|
extension ISO8601DateFormatter {
|
|
static let shared = ISO8601DateFormatter()
|
|
}
|
|
|
|
// Invite code model
|
|
struct InviteCode: Identifiable, Sendable {
|
|
var id: String
|
|
var code: String { id } // For compatibility with the view
|
|
var uses: [CodeUse]?
|
|
var createdAt: Date
|
|
var disabled: Bool
|
|
var isDisabled: Bool { disabled } // For backwards compatibility
|
|
|
|
// Returns a formatted date string for display
|
|
var formattedDate: String {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .short
|
|
return formatter.string(from: createdAt)
|
|
}
|
|
|
|
// Returns the number of available uses
|
|
var availableUses: Int {
|
|
let usedCount = uses?.count ?? 0
|
|
return max(0, 1 - usedCount) // Assuming default of 1 use per code
|
|
}
|
|
}
|
|
|
|
// Invite use model
|
|
struct CodeUse: Codable, Identifiable, Sendable {
|
|
var id: String { usedBy }
|
|
var usedBy: String
|
|
var usedAt: String
|
|
|
|
// Parsed date for the usedAt string
|
|
var date: Date? {
|
|
ISO8601DateFormatter.shared.date(from: usedAt)
|
|
}
|
|
|
|
// Formatted date for display
|
|
var formattedDate: String {
|
|
guard let date = date else { return "Unknown date" }
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .short
|
|
return formatter.string(from: date)
|
|
}
|
|
}
|
|
|
|
// User model
|
|
class PDSUser: Identifiable, Hashable, Sendable, ObservableObject {
|
|
let id: String // DID
|
|
let joinedAt: Date
|
|
let avatar: URL?
|
|
|
|
@Published var handle: String
|
|
@Published var displayName: String
|
|
@Published var description: String
|
|
@Published var isActive: Bool = true
|
|
|
|
// Formatted date for display
|
|
var formattedJoinDate: String {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .none
|
|
return formatter.string(from: joinedAt)
|
|
}
|
|
|
|
init(id: String, handle: String, displayName: String, description: String, joinedAt: Date, avatar: URL?, isActive: Bool = true) {
|
|
self.id = id
|
|
self.handle = handle
|
|
self.displayName = displayName
|
|
self.description = description
|
|
self.joinedAt = joinedAt
|
|
self.avatar = avatar
|
|
self.isActive = isActive
|
|
}
|
|
|
|
// Add Hashable conformance
|
|
func hash(into hasher: inout Hasher) {
|
|
hasher.combine(id)
|
|
}
|
|
|
|
static func == (lhs: PDSUser, rhs: PDSUser) -> Bool {
|
|
lhs.id == rhs.id
|
|
}
|
|
}
|
|
|
|
// Shared DateFormatter for consistent date formatting across the app
|
|
extension DateFormatter {
|
|
static let shared: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .short
|
|
return formatter
|
|
}()
|
|
|
|
static let dateOnly: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium
|
|
formatter.timeStyle = .none
|
|
return formatter
|
|
}()
|
|
}
|
|
|
|
// Auth state
|
|
enum AuthState: Sendable {
|
|
case loggedOut
|
|
case loggedIn
|
|
}
|
|
|
|
// View state
|
|
enum ViewTab: Sendable {
|
|
case inviteCodes
|
|
case userList
|
|
} |