214 lines
9.5 KiB
Swift
214 lines
9.5 KiB
Swift
//
|
|
// Fenestra.swift
|
|
// gloss
|
|
//
|
|
// Created by Saint on 5/20/24.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
import WrappingHStack
|
|
|
|
struct SegRow: View {
|
|
var seg: SegDenorm
|
|
var ribbonId: Int64
|
|
@State var highlights = Set<Int>()
|
|
|
|
var body: some View {
|
|
var segSplit = seg.body.components(separatedBy: ";;")
|
|
let decoder = JSONDecoder()
|
|
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
|
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
|
|
|
let verse = try! decoder.decode(Verse.self, from: segSplit[segIndex].data(using: .utf8)!)
|
|
let arrayOfText = verse.body.components(separatedBy: " ")
|
|
|
|
let lineHeight = CGFloat(30)
|
|
let fontSize = CGFloat(20)
|
|
let highlightColor = "470000"
|
|
ForEach(0 ..< arrayOfText.count, id: \.self) { index in
|
|
HStack(spacing: 0) {
|
|
if index == 0 {
|
|
Text("")
|
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
|
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
|
|
VStack(spacing: 0) {
|
|
ZStack {
|
|
Text(" ")
|
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
|
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
Text(String(verse.verse))
|
|
.font(Font.custom("AveriaSerifLibre-Regular", size: 10))
|
|
.padding(.horizontal, 0)
|
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
}
|
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
}
|
|
}
|
|
|
|
Text(arrayOfText[index])
|
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
|
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
|
.padding(.horizontal, 1.5) // intra word spacing
|
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
.foregroundColor(Color.white)
|
|
.onTapGesture {
|
|
Print(arrayOfText[index])
|
|
Print(verse.verse)
|
|
if self.highlights.contains(verse.verse) {
|
|
self.highlights.remove(verse.verse)
|
|
} else {
|
|
self.highlights.insert(verse.verse)
|
|
}
|
|
}
|
|
}
|
|
.frame(height: 16) // intra line spacing
|
|
.padding(.vertical, 0)
|
|
}
|
|
}
|
|
}
|
|
return retView
|
|
}
|
|
}
|
|
|
|
|
|
// struct Pane: View {
|
|
// @State var paneConnector = PaneConnector()
|
|
|
|
// @State var segs: [SegDenorm]
|
|
// @State var selectedRibbon: [Ribbon]
|
|
|
|
// @State var dragOffset = CGFloat()
|
|
|
|
// @State var refresh: Bool = false
|
|
|
|
|
|
// // var handleVisibilityChanged: (String, VisibilityChange, VisibilityTracker<String>) -> Void
|
|
|
|
// var body: some View {
|
|
// ScrollViewReader { proxy in
|
|
// VisibilityTrackingScrollView(action: handleVisibilityChanged) {
|
|
// LazyVStack {
|
|
// ForEach(segs) { seg in
|
|
// SegRow(seg: seg,
|
|
// ribbonId: selectedRibbon[0].id!)
|
|
// .id("\(seg.id)")
|
|
// .offset(x: -dragOffset)
|
|
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
|
|
// .trackVisibility(id: "\(seg.id)")
|
|
// }
|
|
// }
|
|
// .background(Color(red: 0.18, green: 0.18, blue: 0.18))
|
|
// }
|
|
|
|
// .onAppear {
|
|
// goToRibbon(selectedRibbon: selectedRibbon[0],
|
|
// destRibbon: selectedRibbon[0],
|
|
// scrollId: $scrollId,
|
|
// scrollOffset: $scrollOffset,
|
|
// refresh: $refresh,
|
|
// showOverlay: $showOverlay,
|
|
// appDatabase: appDatabase,
|
|
// paneConnector: $paneConnector,
|
|
// loading: true)
|
|
// }
|
|
// .onChange(of: paneConnector.refresh) { _ in
|
|
|
|
// Task {
|
|
// DispatchQueue.main.async {
|
|
// let gTracker = paneConnector.visibilityTracker!
|
|
|
|
// Print("scroll Id target: \(paneConnector.scrollId)")
|
|
// proxy.scrollTo(paneConnector.scrollId, anchor: .top)
|
|
|
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
// Print(" scroll id target", paneConnector.scrollId)
|
|
// Print(" current id ", paneConnector.currentId)
|
|
// Print(gTracker.sortedViewIDs)
|
|
// if paneConnector.currentId != paneConnector.scrollId {
|
|
// Print("NO MATCH")
|
|
// }
|
|
|
|
// Print(" current offset ", gTracker.visibleViews[paneConnector.scrollId])
|
|
// var curOffset = gTracker.visibleViews[paneConnector.scrollId]
|
|
// Print(" stats", gTracker.visibleViews)
|
|
// if curOffset != nil {
|
|
// paneConnector.setScrollOffset = CGFloat(Int(paneConnector.scrollOffset) - Int(curOffset!))
|
|
// // setScrollOffset = CGFloat(Int(paneConnector.scrollOffset) - Int(curOffset!))
|
|
// // setScrollOffset = CGFloat(Int(paneConnector.scrollOffset) - Int(curOffset!))
|
|
// Print("applying scroll offset \(setScrollOffset)")
|
|
// Print("applying scroll offset \(paneConnector.setScrollOffset)")
|
|
|
|
// // paneConnector = paneConnector.copy() as! PaneConnector
|
|
// self.refresh.toggle()
|
|
// } else {
|
|
// var adjust = (Int(paneConnector.scrollId)! - Int(paneConnector.currentId)!) * 200
|
|
// Print("adjusting \(adjust)")
|
|
|
|
// setScrollOffset = CGFloat(adjust)
|
|
// refresh.toggle()
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// .introspect(.scrollView, on: .iOS(.v13, .v14, .v15, .v16, .v17)) { scrollView in
|
|
// Print("introspect")
|
|
|
|
// // Weird hack for reactivity
|
|
// if self.refresh {
|
|
// let reactive = self.refresh
|
|
// }
|
|
|
|
// // if self.paneConnector != nil {
|
|
// // let reactive = self.paneConnector
|
|
// // }
|
|
|
|
// if paneConnector.setScrollOffset != nil {
|
|
// DispatchQueue.main.async {
|
|
// scrollView.contentOffset.y = scrollView.contentOffset.y + paneConnector.setScrollOffset!
|
|
// paneConnector.setScrollOffset = nil
|
|
|
|
// withAnimation(.easeIn(duration: 0.2)) {
|
|
// paneConnector.showOverlay = false
|
|
// self.refresh.toggle()
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// Print("end introspect")
|
|
// }
|
|
// .listStyle(PlainListStyle())
|
|
// }
|
|
// .zIndex(1)
|
|
// .background(Color(red: 0.2, green: 0.2, blue: 0.2))
|
|
// .frame(width: geometry.size.width - 50, height: geometry.size.height / 2 - vertSep)
|
|
// }
|
|
|
|
// func handleVisibilityChanged(_: String, change _: VisibilityChange, tracker: VisibilityTracker<String>) {
|
|
// // var printRate: Int64 = 10
|
|
// // gTracker = tracker
|
|
// self.paneConnector.visibilityTracker = tracker
|
|
|
|
|
|
// let visibleViews2 = Array(tracker.visibleViews.keys)
|
|
// if visibleViews2.count == 0 {
|
|
// return
|
|
// }
|
|
|
|
// // currentId = tracker.sortedViewIDs[tracker.sortedViewIDs.count - 1]
|
|
// currentId = tracker.sortedViewIDs[0]
|
|
// currentOffset = tracker.visibleViews[currentId!]!
|
|
|
|
// self.paneConnector.currentId = tracker.sortedViewIDs[0]
|
|
// self.paneConnector.currentOffset = tracker.visibleViews[currentId!]!
|
|
// }
|
|
|
|
|
|
// }
|
|
|