Refactor CreateQRCodeView to support multiple QR code types with dynamic input handling; introduced new fields for WiFi, contact, location, calendar, social media, and phone inputs. Enhanced initial focus setup and input validation for improved user experience and modularity.

main
v504 10 months ago
parent 4e57ba1abd
commit 972774adb1

@ -102,7 +102,8 @@ struct InputComponentFactory {
eventDescription: eventDescription, eventDescription: eventDescription,
startDate: startDate, startDate: startDate,
endDate: endDate, endDate: endDate,
location: location location: location,
focusedField: focusedCalendarField
) )
) )
@ -150,7 +151,7 @@ struct InputComponentFactory {
} }
// //
private static func getPlaceholderText(for qrCodeType: QRCodeType) -> String { static func getPlaceholderText(for qrCodeType: QRCodeType) -> String {
switch qrCodeType { switch qrCodeType {
case .text: case .text:
return "输入任意文本内容..." return "输入任意文本内容..."

@ -10,11 +10,8 @@ struct CreateQRCodeView: View {
// //
let selectedQRCodeType: QRCodeType let selectedQRCodeType: QRCodeType
//
@State private var content = "" @State private var content = ""
@State private var showingAlert = false
@State private var alertMessage = ""
//
@FocusState private var isContentFieldFocused: Bool @FocusState private var isContentFieldFocused: Bool
// Email // Email
@ -23,12 +20,56 @@ struct CreateQRCodeView: View {
@State private var emailBody = "" @State private var emailBody = ""
@State private var emailCc = "" @State private var emailCc = ""
@State private var emailBcc = "" @State private var emailBcc = ""
@FocusState private var focusedEmailField: EmailField? @FocusState private var focusedEmailField: EmailInputView.EmailField?
// Email // WiFi
private enum EmailField: Hashable { @State private var wifiSSID = ""
case address, subject, body, cc, bcc @State private var wifiPassword = ""
} @State private var wifiEncryptionType: WiFiInputView.WiFiEncryptionType = .wpa2
@FocusState private var focusedWiFiField: WiFiInputView.WiFiField?
//
@State private var contactFirstName = ""
@State private var contactLastName = ""
@State private var contactPhone = ""
@State private var contactEmail = ""
@State private var contactCompany = ""
@State private var contactTitle = ""
@State private var contactAddress = ""
@State private var contactWebsite = ""
@FocusState private var focusedContactField: ContactInputView.ContactField?
//
@State private var locationLatitude = ""
@State private var locationLongitude = ""
@State private var locationName = ""
@FocusState private var focusedLocationField: LocationInputView.LocationField?
//
@State private var eventTitle = ""
@State private var eventDescription = ""
@State private var eventLocation = ""
@State private var startDate = Date()
@State private var endDate = Date().addingTimeInterval(3600)
@FocusState private var focusedCalendarField: CalendarInputView.CalendarField?
//
@State private var socialUsername = ""
@State private var socialMessage = ""
@FocusState private var focusedSocialField: SocialInputView.SocialField?
//
@State private var phoneNumber = ""
@State private var phoneMessage = ""
@FocusState private var focusedPhoneField: PhoneInputView.PhoneField?
// URL
@State private var urlString = ""
@FocusState private var isURLFieldFocused: Bool
//
@State private var showingAlert = false
@State private var alertMessage = ""
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
@ -47,346 +88,93 @@ struct CreateQRCodeView: View {
Button("确定") { } Button("确定") { }
} message: { Text(alertMessage) } } message: { Text(alertMessage) }
.onAppear { .onAppear {
// setupInitialFocus()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if selectedQRCodeType == .mail {
focusedEmailField = .address
} else {
isContentFieldFocused = true
}
}
} }
.onTapGesture { .onTapGesture {
// hideKeyboard()
if selectedQRCodeType == .mail {
focusedEmailField = nil
} else {
isContentFieldFocused = false
}
} }
} }
// MARK: - UI Components // MARK: - UI Components
private var emailInputSection: some View {
VStack(spacing: 16) {
// Email ()
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("邮箱地址")
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
TextField("user@example.com", text: $emailAddress)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
.focused($focusedEmailField, equals: .address)
}
// ()
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("主题")
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
TextField("邮件主题", text: $emailSubject)
.textFieldStyle(RoundedBorderTextFieldStyle())
.focused($focusedEmailField, equals: .subject)
}
// ()
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("正文")
.font(.subheadline)
.foregroundColor(.primary)
Text("*")
.foregroundColor(.red)
Spacer()
}
ZStack {
TextEditor(text: $emailBody)
.frame(minHeight: 120)
.padding(8)
.background(Color(.systemBackground))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(focusedEmailField == .body ? Color.blue : Color(.systemGray4), lineWidth: 1)
)
.focused($focusedEmailField, equals: .body)
.onChange(of: emailBody) { newValue in
// 1200
if newValue.count > 1200 {
emailBody = String(newValue.prefix(1200))
}
}
//
if emailBody.isEmpty && focusedEmailField != .body {
VStack {
HStack {
Text("输入邮件正文内容...")
.foregroundColor(.secondary)
.font(.body)
Spacer()
}
Spacer()
}
.padding(16)
.allowsHitTesting(false)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
}
//
HStack {
Spacer()
Text("\(emailBody.count)/1200")
.font(.caption)
.foregroundColor(emailBody.count >= 1200 ? .orange : .secondary)
}
}
// CC ()
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("抄送地址")
.font(.subheadline)
.foregroundColor(.primary)
Spacer()
}
TextField("cc@example.com", text: $emailCc)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
.focused($focusedEmailField, equals: .cc)
}
// BCC ()
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("密送地址")
.font(.subheadline)
.foregroundColor(.primary)
Spacer()
}
TextField("bcc@example.com", text: $emailBcc)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.emailAddress)
.autocapitalization(.none)
.focused($focusedEmailField, equals: .bcc)
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("完成") {
focusedEmailField = nil
}
.foregroundColor(.blue)
.font(.system(size: 16, weight: .medium))
}
}
}
private var inputAndPreviewSection: some View { private var inputAndPreviewSection: some View {
ScrollView { ScrollView {
VStack(spacing: 24) { VStack(spacing: 24) {
// //
VStack(spacing: 12) { InputHintView.info(
HStack { hint: getContentHint()
Image(systemName: "info.circle")
.font(.caption)
.foregroundColor(.blue)
Text(getContentHint())
.font(.caption)
.foregroundColor(.secondary)
.lineLimit(nil)
Spacer()
}
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color.blue.opacity(0.1))
) )
}
.padding(.horizontal, 20) .padding(.horizontal, 20)
// //
VStack(spacing: 16) { VStack(spacing: 16) {
HStack { InputTitleView.required(
Text(selectedQRCodeType == .mail ? "邮件信息" : "输入内容") selectedQRCodeType == .mail ? "邮件信息" : "输入内容",
.font(.headline) icon: getInputIcon()
.foregroundColor(.primary)
Spacer()
}
if selectedQRCodeType == .mail {
// Email
emailInputSection
} else {
//
VStack(spacing: 8) {
ZStack {
//
TextEditor(text: $content)
.frame(minHeight: 120)
.padding(8)
.background(Color(.systemBackground))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(isContentFieldFocused ? Color.blue : Color(.systemGray4), lineWidth: 1)
) )
.focused($isContentFieldFocused) .padding(.horizontal, 20)
.onChange(of: content) { newValue in
// 150
if newValue.count > 150 {
content = String(newValue.prefix(150))
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("完成") {
isContentFieldFocused = false
}
.foregroundColor(.blue)
.font(.system(size: 16, weight: .medium))
}
}
// -
if content.isEmpty && !isContentFieldFocused {
VStack {
HStack {
Text(getPlaceholderText())
.foregroundColor(.secondary)
.font(.body)
Spacer()
}
Spacer()
}
.padding(16)
.allowsHitTesting(false)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
}
// -
HStack {
Spacer() // Pushes content to the right
VStack(alignment: .trailing, spacing: 4) {
//
if content.count >= 150 {
HStack(spacing: 4) {
Image(systemName: "exclamationmark.triangle")
.font(.caption)
.foregroundColor(.orange)
Text("已达到最大字符数")
.font(.caption)
.foregroundColor(.orange)
}
} else if content.count >= 140 {
HStack(spacing: 4) {
Image(systemName: "info.circle")
.font(.caption)
.foregroundColor(.blue)
Text("接近字符限制")
.font(.caption)
.foregroundColor(.blue)
}
}
// // 使InputComponentFactory
Text("\(content.count)/150") InputComponentFactory.createInputComponent(
.font(.caption) for: selectedQRCodeType,
.foregroundColor(getCharacterCountColor()) content: $content,
} emailAddress: $emailAddress,
} emailSubject: $emailSubject,
} emailBody: $emailBody,
} emailCc: $emailCc,
} emailBcc: $emailBcc,
focusedEmailField: _focusedEmailField,
isContentFieldFocused: _isContentFieldFocused,
ssid: $wifiSSID,
password: $wifiPassword,
encryptionType: $wifiEncryptionType,
focusedWiFiField: _focusedWiFiField,
firstName: $contactFirstName,
lastName: $contactLastName,
phone: $contactPhone,
email: $contactEmail,
company: $contactCompany,
title: $contactTitle,
address: $contactAddress,
website: $contactWebsite,
focusedContactField: _focusedContactField,
latitude: $locationLatitude,
longitude: $locationLongitude,
locationName: $locationName,
focusedLocationField: _focusedLocationField,
eventTitle: $eventTitle,
eventDescription: $eventDescription,
startDate: $startDate,
endDate: $endDate,
location: $eventLocation,
focusedCalendarField: _focusedCalendarField,
username: $socialUsername,
message: $socialMessage,
focusedSocialField: _focusedSocialField,
phoneNumber: $phoneNumber,
phoneMessage: $phoneMessage,
focusedPhoneField: _focusedPhoneField,
url: $urlString,
isUrlFieldFocused: _isURLFieldFocused
)
.padding(.horizontal, 20) .padding(.horizontal, 20)
}
// //
if selectedQRCodeType == .mail ? (!emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty) : !content.isEmpty { if canCreateQRCode() {
VStack(spacing: 16) { VStack(spacing: 16) {
HStack { InputTitleView.required("预览", icon: "eye")
Text("预览") .padding(.horizontal, 20)
.font(.headline)
.foregroundColor(.primary)
Spacer()
}
// // 使QRCodePreviewView
VStack(spacing: 16) { QRCodePreviewView(
// qrCodeImage: generateQRCodeImage(),
if let qrImage = generateQRCodeImage() { formattedContent: formatContentForQRCodeType(),
Image(uiImage: qrImage) qrCodeType: selectedQRCodeType
.interpolation(.none) )
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
.background(Color.white)
.cornerRadius(12)
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)
}
//
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("内容")
.font(.caption)
.foregroundColor(.secondary)
Spacer()
Text(selectedQRCodeType.displayName)
.font(.caption)
.padding(.horizontal, 6)
.padding(.vertical, 2)
.background(Color.orange.opacity(0.1))
.foregroundColor(.orange)
.cornerRadius(4)
}
Text(formatContentForQRCodeType())
.font(.body)
.foregroundColor(.primary)
.textSelection(.enabled)
}
.padding()
.background(Color(.systemGray6))
.cornerRadius(8)
}
.padding()
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(color: .black.opacity(0.05), radius: 4, x: 0, y: 2)
}
.padding(.horizontal, 20) .padding(.horizontal, 20)
} }
}
Spacer(minLength: 100) Spacer(minLength: 100)
} }
@ -397,133 +185,106 @@ struct CreateQRCodeView: View {
// MARK: - Helper Methods // MARK: - Helper Methods
private func canCreateQRCode() -> Bool { private func setupInitialFocus() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
switch selectedQRCodeType { switch selectedQRCodeType {
case .mail: case .mail:
// Email focusedEmailField = .address
return !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty case .wifi:
focusedWiFiField = .ssid
case .vcard, .mecard:
focusedContactField = .firstName
case .location:
focusedLocationField = .latitude
case .calendar:
focusedCalendarField = .title
case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok:
focusedSocialField = .username
case .phone, .sms:
focusedPhoneField = .phoneNumber
case .url:
isURLFieldFocused = true
default: default:
// isContentFieldFocused = true
return !content.isEmpty
}
} }
private func getCharacterCountColor() -> Color {
if content.count >= 150 {
return .orange
} else if content.count >= 140 {
return .blue
} else {
return .secondary
} }
} }
private func getContentHint() -> String { private func hideKeyboard() {
switch selectedQRCodeType { switch selectedQRCodeType {
case .text:
return "输入任意文本内容"
case .url:
return "输入网址https://www.example.com"
case .mail: case .mail:
return "填写邮件信息,邮箱地址、主题、正文为必填项" focusedEmailField = nil
case .phone:
return "输入电话号码,如:+86 138 0013 8000"
case .sms:
return "输入短信内容Hello World"
case .wifi: case .wifi:
return "输入WiFi信息SSID:MyWiFi,Password:12345678" focusedWiFiField = nil
case .vcard: case .vcard, .mecard:
return "输入联系人信息" focusedContactField = nil
case .mecard:
return "输入联系人信息(简化版)"
case .location: case .location:
return "输入地理位置40.7128,-74.0060" focusedLocationField = nil
case .calendar: case .calendar:
return "输入日历事件信息" focusedCalendarField = nil
case .instagram: case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok:
return "输入Instagram用户名或链接" focusedSocialField = nil
case .facebook: case .phone, .sms:
return "输入Facebook用户名或链接" focusedPhoneField = nil
case .spotify: case .url:
return "输入Spotify歌曲或播放列表链接" isURLFieldFocused = false
case .twitter: default:
return "输入Twitter用户名或链接" isContentFieldFocused = false
case .whatsapp:
return "输入WhatsApp消息内容"
case .viber:
return "输入Viber消息内容"
case .snapchat:
return "输入Snapchat用户名"
case .tiktok:
return "输入TikTok用户名或链接"
} }
} }
private func getPlaceholderText() -> String { private func getInputIcon() -> String {
switch selectedQRCodeType {
case .mail: return "envelope"
case .wifi: return "wifi"
case .vcard, .mecard: return "person"
case .location: return "location"
case .calendar: return "calendar"
case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: return "globe"
case .phone, .sms: return "phone"
case .url: return "link"
default: return "textformat"
}
}
private func canCreateQRCode() -> Bool {
switch selectedQRCodeType { switch selectedQRCodeType {
case .text:
return "输入任意文本内容..."
case .url:
return "输入网址..."
case .mail: case .mail:
return "输入邮件内容..." return !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty
case .phone:
return "输入电话号码..."
case .sms:
return "输入短信内容..."
case .wifi: case .wifi:
return "输入WiFi信息..." return !wifiSSID.isEmpty
case .vcard: case .vcard, .mecard:
return "输入联系人信息..." return !contactFirstName.isEmpty || !contactLastName.isEmpty
case .mecard:
return "输入联系人信息..."
case .location: case .location:
return "输入地理位置..." return !locationLatitude.isEmpty && !locationLongitude.isEmpty
case .calendar: case .calendar:
return "输入日历事件信息..." return !eventTitle.isEmpty
case .instagram: case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok:
return "输入Instagram信息..." return !socialUsername.isEmpty
case .facebook: case .phone, .sms:
return "输入Facebook信息..." return !phoneNumber.isEmpty
case .spotify: case .url:
return "输入Spotify信息..." return !urlString.isEmpty
case .twitter: default:
return "输入Twitter信息..." return !content.isEmpty
case .whatsapp:
return "输入WhatsApp信息..."
case .viber:
return "输入Viber信息..."
case .snapchat:
return "输入Snapchat信息..."
case .tiktok:
return "输入TikTok信息..."
} }
} }
private func generateQRCodeImage() -> UIImage? { private func getContentHint() -> String {
// InputComponentFactory.getPlaceholderText(for: selectedQRCodeType)
let hasContent: Bool
switch selectedQRCodeType {
case .mail:
hasContent = !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty
default:
hasContent = !content.isEmpty
} }
guard hasContent else { return nil } private func generateQRCodeImage() -> UIImage? {
guard canCreateQRCode() else { return nil }
//
let formattedContent = formatContentForQRCodeType() let formattedContent = formatContentForQRCodeType()
//
let data = formattedContent.data(using: .utf8) let data = formattedContent.data(using: .utf8)
let qrFilter = CIFilter.qrCodeGenerator() let qrFilter = CIFilter.qrCodeGenerator()
qrFilter.setValue(data, forKey: "inputMessage") qrFilter.setValue(data, forKey: "inputMessage")
qrFilter.setValue("H", forKey: "inputCorrectionLevel") // qrFilter.setValue("H", forKey: "inputCorrectionLevel")
guard let outputImage = qrFilter.outputImage else { return nil } guard let outputImage = qrFilter.outputImage else { return nil }
// UIImage
let context = CIContext() let context = CIContext()
guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil } guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil }
@ -535,7 +296,7 @@ struct CreateQRCodeView: View {
case .text: case .text:
return content return content
case .url: case .url:
return content.hasPrefix("http") ? content : "https://\(content)" return urlString.hasPrefix("http") ? urlString : "https://\(urlString)"
case .mail: case .mail:
var mailtoURL = "mailto:\(emailAddress)" var mailtoURL = "mailto:\(emailAddress)"
var queryParams: [String] = [] var queryParams: [String] = []
@ -562,35 +323,97 @@ struct CreateQRCodeView: View {
return mailtoURL return mailtoURL
case .phone: case .phone:
return "tel:\(content)" return "tel:\(phoneNumber)"
case .sms: case .sms:
return "sms:\(content)" let smsContent = phoneMessage.isEmpty ? "Hello" : phoneMessage
return "sms:\(phoneNumber):\(smsContent)"
case .wifi: case .wifi:
return "WIFI:T:WPA;S:\(content);P:password;;" return "WIFI:T:\(wifiEncryptionType.rawValue);S:\(wifiSSID);P:\(wifiPassword);;"
case .vcard: case .vcard:
return "BEGIN:VCARD\nVERSION:3.0\nFN:\(content)\nEND:VCARD" var vcard = "BEGIN:VCARD\nVERSION:3.0\n"
if !contactFirstName.isEmpty || !contactLastName.isEmpty {
vcard += "FN:\(contactFirstName) \(contactLastName)\n"
}
if !contactPhone.isEmpty {
vcard += "TEL:\(contactPhone)\n"
}
if !contactEmail.isEmpty {
vcard += "EMAIL:\(contactEmail)\n"
}
if !contactCompany.isEmpty {
vcard += "ORG:\(contactCompany)\n"
}
if !contactTitle.isEmpty {
vcard += "TITLE:\(contactTitle)\n"
}
if !contactAddress.isEmpty {
vcard += "ADR:\(contactAddress)\n"
}
if !contactWebsite.isEmpty {
vcard += "URL:\(contactWebsite)\n"
}
vcard += "END:VCARD"
return vcard
case .mecard: case .mecard:
return "MECARD:N:\(content);;" var mecard = "MECARD:"
if !contactFirstName.isEmpty || !contactLastName.isEmpty {
mecard += "N:\(contactLastName),\(contactFirstName);"
}
if !contactPhone.isEmpty {
mecard += "TEL:\(contactPhone);"
}
if !contactEmail.isEmpty {
mecard += "EMAIL:\(contactEmail);"
}
if !contactCompany.isEmpty {
mecard += "ORG:\(contactCompany);"
}
if !contactAddress.isEmpty {
mecard += "ADR:\(contactAddress);"
}
if !contactWebsite.isEmpty {
mecard += "URL:\(contactWebsite);"
}
mecard += ";"
return mecard
case .location: case .location:
return "geo:\(content)" let coords = "\(locationLatitude),\(locationLongitude)"
return locationName.isEmpty ? "geo:\(coords)" : "geo:\(coords)?q=\(locationName)"
case .calendar: case .calendar:
return "BEGIN:VEVENT\nSUMMARY:\(content)\nEND:VEVENT" let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd'T'HHmmss'Z'"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
var ical = "BEGIN:VEVENT\n"
ical += "SUMMARY:\(eventTitle)\n"
if !eventDescription.isEmpty {
ical += "DESCRIPTION:\(eventDescription)\n"
}
if !eventLocation.isEmpty {
ical += "LOCATION:\(eventLocation)\n"
}
ical += "DTSTART:\(dateFormatter.string(from: startDate))\n"
ical += "DTEND:\(dateFormatter.string(from: endDate))\n"
ical += "END:VEVENT"
return ical
case .instagram: case .instagram:
return "https://instagram.com/\(content)" return "https://instagram.com/\(socialUsername)"
case .facebook: case .facebook:
return "https://facebook.com/\(content)" return "https://facebook.com/\(socialUsername)"
case .spotify: case .spotify:
return content.hasPrefix("http") ? content : "https://open.spotify.com/track/\(content)" return socialUsername.hasPrefix("http") ? socialUsername : "https://open.spotify.com/track/\(socialUsername)"
case .twitter: case .twitter:
return "https://twitter.com/\(content)" return "https://twitter.com/\(socialUsername)"
case .whatsapp: case .whatsapp:
return "https://wa.me/\(content)" let message = socialMessage.isEmpty ? "Hello" : socialMessage
return "https://wa.me/\(socialUsername)?text=\(message.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? message)"
case .viber: case .viber:
return "viber://chat?number=\(content)" let message = socialMessage.isEmpty ? "Hello" : socialMessage
return "viber://chat?number=\(socialUsername)&text=\(message.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? message)"
case .snapchat: case .snapchat:
return "https://snapchat.com/add/\(content)" return "https://snapchat.com/add/\(socialUsername)"
case .tiktok: case .tiktok:
return "https://tiktok.com/@\(content)" return "https://tiktok.com/@\(socialUsername)"
} }
} }
@ -615,6 +438,20 @@ struct CreateQRCodeView: View {
mailContent += "\n密送: \(emailBcc)" mailContent += "\n密送: \(emailBcc)"
} }
historyItem.content = mailContent historyItem.content = mailContent
case .wifi:
historyItem.content = "WiFi: \(wifiSSID) (\(wifiEncryptionType.displayName))"
case .vcard, .mecard:
historyItem.content = "联系人: \(contactFirstName) \(contactLastName)"
case .location:
historyItem.content = "位置: \(locationLatitude), \(locationLongitude)"
case .calendar:
historyItem.content = "事件: \(eventTitle)"
case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok:
historyItem.content = "\(selectedQRCodeType.displayName): \(socialUsername)"
case .phone, .sms:
historyItem.content = "电话: \(phoneNumber)"
case .url:
historyItem.content = "URL: \(urlString)"
default: default:
historyItem.content = content historyItem.content = content
} }

@ -169,7 +169,6 @@ struct QRCodeDetailView: View {
// MARK: - // MARK: -
private var originalContentSection: some View { private var originalContentSection: some View {
#if DEBUG
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
HStack { HStack {
Image(systemName: "doc.text") Image(systemName: "doc.text")
@ -200,9 +199,6 @@ struct QRCodeDetailView: View {
.background(Color(.systemBackground)) .background(Color(.systemBackground))
.cornerRadius(12) .cornerRadius(12)
.shadow(radius: 2) .shadow(radius: 2)
#else
EmptyView()
#endif
} }
// MARK: - // MARK: -

Loading…
Cancel
Save