RTSDA-iOS/Views/Components/ScriptureComponents.swift
RTSDA 00679f927c docs: Update README for v2.0 release and fix git remote URL
- Comprehensive README update documenting v2.0 architectural changes
- Updated git remote to ssh://rockvilleav@git.rockvilletollandsda.church:10443/RTSDA/RTSDA-iOS.git
- Documented unified ChurchService and 60% code reduction
- Added new features: Home Feed, responsive reading, enhanced UI
- Corrected license information (GPL v3 with church content copyright)
- Updated build instructions and technical stack details
2025-08-16 18:41:51 -04:00

213 lines
8 KiB
Swift

import SwiftUI
// MARK: - Scripture Sheet Components
struct ScriptureSheet: View {
@Binding var scriptureText: String
@Environment(\.dismiss) private var dismiss
init(scriptureText: Binding<String>) {
self._scriptureText = scriptureText
}
var body: some View {
NavigationStack {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
if scriptureText.isEmpty {
Text("No scripture text available")
.foregroundStyle(.secondary)
.padding()
} else {
let sections = formatScriptureText(scriptureText)
ForEach(Array(sections.enumerated()), id: \.offset) { index, section in
VStack(alignment: .leading, spacing: 8) {
// Verse text
Text(section.verse)
.font(.body)
.lineSpacing(4)
#if os(iOS)
.textSelection(.enabled)
#endif
// Reference
if !section.reference.isEmpty {
Text(section.reference)
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.padding(.top, 4)
}
}
.padding(.horizontal)
// Add divider between sections (except last)
if index < sections.count - 1 {
Divider()
.padding(.horizontal)
}
}
Spacer(minLength: 20)
}
}
.padding(.vertical)
}
.navigationTitle("Scripture Reading")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Done") {
dismiss()
}
}
}
}
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
}
private func formatScriptureText(_ text: String) -> [ScriptureSection] {
// Use the Rust implementation for consistent formatting across platforms
let jsonString = formatScriptureTextJson(scriptureText: text)
guard let data = jsonString.data(using: .utf8),
let sections = try? JSONDecoder().decode([ScriptureSection].self, from: data) else {
// Fallback if JSON parsing fails
return [ScriptureSection(verse: text, reference: "")]
}
return sections
}
}
// MARK: - Scripture Sheet with Sermon ID (loads data automatically)
struct ScriptureSheetForSermon: View {
let sermonId: String
@Environment(\.dismiss) private var dismiss
@State private var scriptureText: String = ""
@State private var isLoading = true
var body: some View {
NavigationStack {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
if isLoading {
ProgressView("Loading scripture...")
.padding()
} else if scriptureText.isEmpty {
Text("No scripture text available for this sermon")
.foregroundStyle(.secondary)
.padding()
} else {
let sections = formatScriptureText(scriptureText)
ForEach(Array(sections.enumerated()), id: \.offset) { index, section in
VStack(alignment: .leading, spacing: 8) {
// Verse text
Text(section.verse)
.font(.body)
.lineSpacing(4)
#if os(iOS)
.textSelection(.enabled)
#endif
// Reference
if !section.reference.isEmpty {
Text(section.reference)
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.padding(.top, 4)
}
}
.padding(.horizontal)
// Add divider between sections (except last)
if index < sections.count - 1 {
Divider()
.padding(.horizontal)
}
}
Spacer(minLength: 20)
}
}
.padding(.vertical)
}
.navigationTitle("Scripture Reading")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Done") {
dismiss()
}
}
}
}
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
.task {
isLoading = true
scriptureText = fetchScriptureVersesForSermonJson(sermonId: sermonId)
isLoading = false
}
}
private func formatScriptureText(_ text: String) -> [ScriptureSection] {
// Use the Rust implementation for consistent formatting across platforms
let jsonString = formatScriptureTextJson(scriptureText: text)
guard let data = jsonString.data(using: .utf8),
let sections = try? JSONDecoder().decode([ScriptureSection].self, from: data) else {
// Fallback if JSON parsing fails
return [ScriptureSection(verse: text, reference: "")]
}
return sections
}
}
struct ScriptureSection: Codable {
let verse: String
let reference: String
}
// MARK: - Scripture Utilities
func extractScriptureReferences(from text: String) -> String {
// Use the Rust implementation for consistent parsing across platforms
return extractScriptureReferencesString(scriptureText: text)
}
// MARK: - Share Utilities
func createShareItems(for sermon: Sermon) -> [Any] {
// Use the Rust implementation for consistent share text across platforms
let jsonString = createSermonShareItemsJson(
title: sermon.title,
speaker: sermon.speaker,
videoUrl: sermon.videoUrl,
audioUrl: sermon.audioUrl
)
guard let data = jsonString.data(using: .utf8),
let shareStrings = try? JSONDecoder().decode([String].self, from: data) else {
// Fallback
return ["Check out this sermon: \"\(sermon.title)\" by \(sermon.speaker)"]
}
var items: [Any] = []
for shareString in shareStrings {
if let url = URL(string: shareString), shareString.hasPrefix("http") {
items.append(url)
} else {
items.append(shareString)
}
}
return items
}