SPB Git

spb/zyquo-agent Public MIT

The autonomous agent that actually operates your Mac — plans, runs real commands, verifies its own work.

Swift 94.7% Shell 4.1% Python 0.7% Makefile 0.5%
3.2 KB · 102 lines swift
Raw Blame History
1//2//  CodeBlockView.swift3//  Zyquo Agent4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//8//  Fenced code block per the Phase 4 spec: surfaceSecondary card with medium9//  radius, uppercased language label top-left, hover copy button top-right10//  (with a brief checkmark confirmation), SF Mono content with syntax11//  highlighting, horizontal scrolling for long lines, and text selection.12//1314import SwiftUI1516struct CodeBlockView: View {17    let code: String18    let language: String?19    let fontSize: Double2021    @State private var hovering = false22    @State private var copied = false23    @State private var copyGeneration = 02425    /// How long the copy confirmation checkmark stays visible.26    private static let copyConfirmationSeconds: Double = 1.22728    var body: some View {29        VStack(alignment: .leading, spacing: 0) {30            header31            ScrollView(.horizontal) {32                SwiftUI.Text(highlighted)33                    .font(ZyquoFont.code(size: max(fontSize - 1, 1)))34                    .textSelection(.enabled)35                    .fixedSize(horizontal: false, vertical: true)36                    .padding(.horizontal, ZyquoSpacing.sm)37                    .padding(.top, ZyquoSpacing.xxs)38                    .padding(.bottom, ZyquoSpacing.xs)39            }40        }41        .background(42            RoundedRectangle(cornerRadius: ZyquoRadius.medium, style: .continuous)43                .fill(ZyquoColor.surfaceSecondary)44        )45        .onHover { inside in46            withAnimation(ZyquoMotion.hover) { hovering = inside }47        }48    }4950    // MARK: Header5152    private var header: some View {53        HStack(spacing: ZyquoSpacing.xs) {54            if let language, !language.isEmpty {55                SwiftUI.Text(language.uppercased())56                    .font(ZyquoFont.caption)57                    .foregroundStyle(ZyquoColor.textSecondary)58            }59            Spacer(minLength: ZyquoSpacing.xs)60            copyButton61                .opacity(hovering || copied ? 1 : 0)62        }63        .padding(.horizontal, ZyquoSpacing.sm)64        .padding(.top, ZyquoSpacing.xs)65    }6667    private var copyButton: some View {68        Button(action: copy) {69            Image(systemName: copied ? "checkmark" : "doc.on.doc")70                .font(ZyquoFont.caption)71                .foregroundStyle(copied ? ZyquoColor.success : ZyquoColor.textSecondary)72        }73        .buttonStyle(PressableButtonStyle())74        .accessibilityLabel("Copy code")75        .help("Copy code")76    }7778    // MARK: Highlighting7980    private var highlighted: AttributedString {81        SyntaxHighlighter.highlight(code, language: language, baseColor: ZyquoColor.textPrimary)82    }8384    // MARK: Copy8586    private func copy() {87        let pasteboard = NSPasteboard.general88        pasteboard.clearContents()89        pasteboard.setString(code, forType: .string)9091        copyGeneration += 192        let generation = copyGeneration93        withAnimation(ZyquoMotion.hover) { copied = true }94        Task {95            try? await Task.sleep(for: .seconds(Self.copyConfirmationSeconds))96            if generation == copyGeneration {97                withAnimation(ZyquoMotion.hover) { copied = false }98            }99        }100    }101}102