diff --git a/VoiceInk/Views/Components/InfoTip.swift b/VoiceInk/Views/Components/InfoTip.swift new file mode 100644 index 0000000..c2571d9 --- /dev/null +++ b/VoiceInk/Views/Components/InfoTip.swift @@ -0,0 +1,67 @@ +import SwiftUI + +/// A reusable info tip component that displays helpful information in a popover +struct InfoTip: View { + // Content configuration + var title: String + var message: String + var learnMoreLink: URL? + var learnMoreText: String = "Learn More" + + // Appearance customization + var iconName: String = "info.circle.fill" + var iconSize: Image.Scale = .medium + var iconColor: Color = .primary + var width: CGFloat = 300 + + // State + @State private var isShowingTip: Bool = false + + var body: some View { + Image(systemName: iconName) + .imageScale(iconSize) + .foregroundColor(iconColor) + .fontWeight(.semibold) + .padding(5) + .contentShape(Rectangle()) + .popover(isPresented: $isShowingTip) { + VStack(alignment: .leading, spacing: 10) { + Text(title) + .font(.headline) + + Text(message) + .frame(width: width) + .padding(.bottom, learnMoreLink != nil ? 5 : 0) + + if let url = learnMoreLink { + Button(learnMoreText) { + NSWorkspace.shared.open(url) + } + .foregroundColor(.blue) + } + } + .padding() + } + .onTapGesture { + isShowingTip.toggle() + } + } +} + +// MARK: - Convenience initializers + +extension InfoTip { + /// Creates an InfoTip with just title and message + init(title: String, message: String) { + self.title = title + self.message = message + self.learnMoreLink = nil + } + + /// Creates an InfoTip with a learn more link + init(title: String, message: String, learnMoreURL: String) { + self.title = title + self.message = message + self.learnMoreLink = URL(string: learnMoreURL) + } +} diff --git a/VoiceInk/Views/PromptCustomizationView.swift b/VoiceInk/Views/PromptCustomizationView.swift index 8ceb6e9..c854a29 100644 --- a/VoiceInk/Views/PromptCustomizationView.swift +++ b/VoiceInk/Views/PromptCustomizationView.swift @@ -12,6 +12,12 @@ struct PromptCustomizationView: View { Text("Output Format") .font(.headline) + InfoTip( + title: "Output Format Guide", + message: "Unlike GPT, Whisper follows the style of your prompt rather than instructions. Use examples of your desired output format instead of commands.", + learnMoreURL: "https://cookbook.openai.com/examples/whisper_prompting_guide#comparison-with-gpt-prompting" + ) + Spacer() Button(action: {