Files
Pulse/Sources/PulseUI/Features/Console/ConsoleNetworkRequestViewModel.swift
T
2021-11-08 16:45:55 -05:00

107 lines
2.8 KiB
Swift
Raw 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) 20202021 Alexander Grebenyuk (github.com/kean).
import SwiftUI
import PulseCore
import Combine
import CoreData
@available(iOS 13.0, tvOS 14.0, watchOS 7.0, *)
final class ConsoleNetworkRequestViewModel {
let badgeColor: Color
let status: String
let title: String
let text: String
let showInConsole: (() -> Void)?
private let message: LoggerMessageEntity
private let request: LoggerNetworkRequestEntity
private let context: AppContext
static let timeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
}()
init(message: LoggerMessageEntity, request: LoggerNetworkRequestEntity, context: AppContext, showInConsole: (() -> Void)? = nil) {
let isSuccess: Bool
if request.errorCode != 0 {
isSuccess = false
} else if request.statusCode != 0, !(200..<400).contains(request.statusCode) {
isSuccess = false
} else {
isSuccess = true
}
let time = ConsoleMessageViewModel.timeFormatter.string(from: request.createdAt)
let prefix: String
if request.statusCode != 0 {
prefix = StatusCodeFormatter.string(for: Int(request.statusCode))
} else if request.errorCode != 0 {
prefix = "\(request.errorCode) (\(descriptionForURLErrorCode(Int(request.errorCode))))"
} else {
prefix = "Success"
}
self.status = prefix
var title = "\(time)"
if request.duration > 0 {
title += " · \(DurationFormatter.string(from: request.duration))"
}
self.title = title
let method = request.httpMethod ?? "GET"
self.text = method + " " + (request.url ?? "")
self.badgeColor = isSuccess ? .green : .red
self.request = request
self.message = message
self.context = context
self.showInConsole = showInConsole
}
// MARK: Pins
var isPinnedPublisher: AnyPublisher<Bool, Never> {
message.publisher(for: \.isPinned).eraseToAnyPublisher()
}
var isPinned: Bool {
message.isPinned
}
func togglePin() {
context.store.togglePin(for: message)
}
// MARK: Context Menu
var containsResponseData: Bool {
request.responseBodyKey != nil
}
// WARNING: This call is relatively expensive.
var responseString: String? {
request.responseBodyKey
.flatMap(context.store.getData)
.flatMap { String(data: $0, encoding: .utf8) }
}
var url: String? {
request.url
}
var host: String? {
request.host
}
var cURLDescription: String {
NetworkLoggerSummary(request: request, store: context.store).cURLDescription()
}
}