Files
Pulse/Sources/PulseUI/Extensions/Pulse+Extensions.swift
2023-04-16 12:57:46 -04:00

131 lines
3.4 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The MIT License (MIT)
//
// Copyright (c) 2020–2023 Alexander Grebenyuk (github.com/kean).
import Foundation
import Pulse
import SwiftUI
import CoreData
enum LoggerEntity {
/// Regular log, not task attached.
case message(LoggerMessageEntity)
/// Either a log with an attached task, or a task itself.
case task(NetworkTaskEntity)
init(_ entity: NSManagedObject) {
if let message = entity as? LoggerMessageEntity {
if let task = message.task {
self = .task(task)
} else {
self = .message(message)
}
} else if let task = entity as? NetworkTaskEntity {
self = .task(task)
} else {
fatalError("Unsupported entity: \(entity)")
}
}
var task: NetworkTaskEntity? {
if case .task(let task) = self { return task }
return nil
}
}
extension LoggerMessageEntity: Identifiable {
public var id: NSManagedObjectID { objectID }
}
extension NetworkTaskEntity: Identifiable {
public var id: NSManagedObjectID { objectID }
}
extension NetworkTaskEntity {
var requestFileViewerContext: FileViewerViewModel.Context {
FileViewerViewModel.Context(
contentType: originalRequest?.contentType,
originalSize: requestBodySize,
metadata: metadata,
isResponse: false,
error: nil
)
}
var responseFileViewerContext: FileViewerViewModel.Context {
FileViewerViewModel.Context(
contentType: response?.contentType,
originalSize: responseBodySize,
metadata: metadata,
isResponse: true,
error: decodingError
)
}
}
extension LoggerMessageEntity {
var logLevel: LoggerStore.Level {
LoggerStore.Level(rawValue: level) ?? .debug
}
}
extension NetworkTaskEntity.State {
var tintColor: Color {
switch self {
case .pending: return .orange
case .success: return .green
case .failure: return .red
}
}
var iconSystemName: String {
switch self {
case .pending: return "clock.fill"
case .success: return "checkmark.circle.fill"
case .failure: return "exclamationmark.octagon.fill"
}
}
}
extension LoggerSessionEntity {
var formattedDate: String {
formattedDate(isCompact: false)
}
var searchTags: [String] {
possibleFormatters.map { $0.string(from: createdAt) }
}
func formattedDate(isCompact: Bool = false) -> String {
if isCompact {
return compactDateFormatter.string(from: createdAt)
} else {
return fullDateFormatter.string(from: createdAt)
}
}
var fullVersion: String? {
guard let version = version else {
return nil
}
if let build = build {
return version + " (\(build))"
}
return version
}
}
private let compactDateFormatter = DateFormatter(dateStyle: .none, timeStyle: .medium)
#if os(watchOS)
private let fullDateFormatter = DateFormatter(dateStyle: .short, timeStyle: .short, isRelative: true)
#else
private let fullDateFormatter = DateFormatter(dateStyle: .medium, timeStyle: .medium, isRelative: true)
#endif
private let possibleFormatters: [DateFormatter] = [
fullDateFormatter,
DateFormatter(dateStyle: .long, timeStyle: .none),
DateFormatter(dateStyle: .short, timeStyle: .none)
]