276d2bb6-619d-4888-ba11-8a6.../Sources/ui/SourcePreview.swift
徐翔宇 4e22618364 v0.1.0: initial 划词侠 — AI Text Actions plugin for MioIsland
Quick AI actions on clipboard or selected text. Four actions:
- 翻译 (中/英/日)
- 总结 (3-bullet Chinese)
- 改语气 (正式/口语/友好/严谨)
- 邮件回复

Powered by DeepSeek with Server-Sent Events streaming for
typewriter feedback (~600ms first byte). Two source modes:
clipboard (no permission) and selected-text via NSAccessibility
(graceful fallback to clipboard + permission banner if denied).

Five-state UI machine: idle → input → loading (cancellable) →
result → missing-config. Last 20 actions persisted to UserDefaults.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:21:17 +08:00

50 lines
1.6 KiB
Swift

//
// SourcePreview.swift
// plugin
//
// Compact card showing the current source text 3 lines, soft border,
// monospace fallback for long URLs/code.
//
import SwiftUI
struct SourcePreview: View {
let text: String
var body: some View {
VStack(alignment: .leading, spacing: 6) {
HStack(spacing: 6) {
Image(systemName: "text.alignleft")
.font(.system(size: 10, weight: .semibold))
.foregroundColor(ClipperTheme.fg45)
Text("待处理文本")
.font(.system(size: 10.5, weight: .semibold))
.foregroundColor(ClipperTheme.fg45)
Spacer()
Text("\(text.count)")
.font(.system(size: 10, weight: .medium))
.foregroundColor(ClipperTheme.fg40)
.monospacedDigit()
}
Text(text)
.font(.system(size: 12))
.foregroundColor(ClipperTheme.fg85)
.lineLimit(3)
.truncationMode(.tail)
.multilineTextAlignment(.leading)
.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.horizontal, 12)
.padding(.vertical, 10)
.frame(maxWidth: .infinity, alignment: .leading)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(ClipperTheme.overlay04)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(ClipperTheme.overlay08, lineWidth: 0.5)
)
)
}
}