DFWatchFaceEntryView.swift 3.37 KB
//
//  DFWatchFaceEntryView.swift
//  hippo-watch-extension
//

import WidgetKit
import SwiftUI

struct DFWatchFaceEntryView: View {
    @Environment(\.widgetFamily) private var family
    let entry: DFWatchFaceEntry

    var body: some View {
        Group {
            switch family {
            case .accessoryInline:
                inlineView
            case .accessoryCircular, .accessoryCorner:
                circularView
            default:
                rectangularView
            }
        }
        .containerBackground(DFWatchFaceColor.background, for: .widget)
    }

    @ViewBuilder
    private var rectangularView: some View {
        switch entry.face {
        case .defaultHome:
            DFDefaultHomeFaceView(entry: entry)
        case .singleStress:
            DFSingleStressFaceView(entry: entry)
        case .coupleStress:
            DFCoupleStressFaceView(entry: entry)
        }
    }

    private var circularView: some View {
        let status = statusForCompactView
        return ZStack {
            DFWatchFaceColor.background
            Circle()
                .trim(from: 0.08, to: 0.86)
                .stroke(status.color.opacity(0.28), style: StrokeStyle(lineWidth: 5, lineCap: .round))
                .rotationEffect(.degrees(110))
            Circle()
                .trim(from: 0.08, to: compactProgress)
                .stroke(status.color, style: StrokeStyle(lineWidth: 5, lineCap: .round))
                .rotationEffect(.degrees(110))
            VStack(spacing: 0) {
                Image(systemName: compactIcon)
                    .font(.system(size: 13, weight: .semibold))
                    .foregroundStyle(status.color)
                Text(compactValue)
                    .font(.system(size: 12, weight: .bold, design: .rounded))
                    .foregroundStyle(.white)
                    .minimumScaleFactor(0.7)
            }
        }
    }

    private var inlineView: some View {
        Text("\(inlineTitle) \(compactValue)")
    }

    private var statusForCompactView: DFStressStatus {
        switch entry.face {
        case .defaultHome, .singleStress:
            return entry.data.myStatus
        case .coupleStress:
            return entry.data.myStatus
        }
    }

    private var compactIcon: String {
        switch entry.face {
        case .defaultHome:
            return "waveform.path.ecg"
        case .singleStress:
            return "heart.text.square.fill"
        case .coupleStress:
            return "person.2.fill"
        }
    }

    private var compactValue: String {
        switch entry.face {
        case .defaultHome, .singleStress:
            return entry.data.hasData ? "\(entry.data.hrvValue)ms" : "--"
        case .coupleStress:
            return entry.data.hasData ? "\(entry.data.partnerHRV)/\(entry.data.myHRV)" : "--"
        }
    }

    private var compactProgress: CGFloat {
        switch entry.face {
        case .defaultHome, .singleStress:
            return 0.08 + min(CGFloat(entry.data.hrvValue) / 100, 0.78)
        case .coupleStress:
            return 0.08 + min(CGFloat(entry.data.myHRV) / 100, 0.78)
        }
    }

    private var inlineTitle: String {
        switch entry.face {
        case .defaultHome:
            return "HRV"
        case .singleStress:
            return entry.data.myStatus.title
        case .coupleStress:
            return "双人状态"
        }
    }
}