217 lines
9.5 KiB
Swift
217 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 Fenestra: View {
|
|
// @State var segs: [SegDenorm]
|
|
// @State var selectedRibbon: [Ribbon]
|
|
|
|
// @State var dragOffset = CGFloat()
|
|
|
|
// @State var refresh: Bool = false
|
|
// @State var refresh2: 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 {
|
|
// Print("APPEAR")
|
|
// goToRibbon(selectedRibbon: selectedRibbon[0],
|
|
// destRibbon: selectedRibbon[0],
|
|
// scrollId: $scrollId,
|
|
// scrollOffset: $scrollOffset,
|
|
// refresh: $refresh,
|
|
// showOverlay: $showOverlay,
|
|
// appDatabase: appDatabase,
|
|
// loading: true)
|
|
// }
|
|
// .onChange(of: refresh) { _ in
|
|
// Task {
|
|
// DispatchQueue.main.async {
|
|
// Print("scroll Id target: \(scrollId)")
|
|
// proxy.scrollTo(scrollId!, anchor: .top)
|
|
|
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
// Print(" scroll id target", scrollId)
|
|
// Print(" current id ", currentId)
|
|
// Print(gTracker!.sortedViewIDs)
|
|
// if currentId! != scrollId! {
|
|
// Print("NO MATCH")
|
|
// }
|
|
|
|
// Print(" current offset ", gTracker!.visibleViews[scrollId!])
|
|
// var curOffset = gTracker!.visibleViews[scrollId!]
|
|
// Print(" stats", gTracker!.visibleViews)
|
|
// if curOffset != nil {
|
|
// setScrollOffset = CGFloat(Int(scrollOffset!) - Int(curOffset!))
|
|
// Print("applying scroll offset \(setScrollOffset)")
|
|
// refresh2.toggle()
|
|
// } else {
|
|
// var adjust = (Int(scrollId!)! - Int(currentId!)!) * 200
|
|
// Print("adjusting \(adjust)")
|
|
// setScrollOffset = CGFloat(adjust)
|
|
// refresh.toggle()
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// .introspect(.scrollView, on: .iOS(.v13, .v14, .v15, .v16, .v17)) { scrollView in Print("introspect")
|
|
// if setScrollOffset != nil {
|
|
// DispatchQueue.main.async {
|
|
// scrollView.contentOffset.y = scrollView.contentOffset.y + setScrollOffset!
|
|
// setScrollOffset = nil
|
|
// withAnimation {
|
|
// showOverlay = false
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// .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)
|
|
// .offset(x: 30, y: 0)
|
|
// .offset(x: pulledOut.width)
|
|
// .offset(x: viewState.width, y: viewState.height)
|
|
// .gesture(
|
|
// DragGesture()
|
|
// .onChanged { gesture in
|
|
|
|
// if endedDrag {
|
|
// endedDrag = false
|
|
// scrollOffset = readOffset.y - 20
|
|
// }
|
|
// Print(viewState.width)
|
|
// if abs(gesture.translation.width) > 20 {
|
|
// viewState.width = gesture.translation.width
|
|
// if gesture.translation.width < -50, pulledOut.width == CGFloat(0) {
|
|
// dragOffset = gesture.translation.width + 50
|
|
// }
|
|
// }
|
|
// }
|
|
// .onEnded { _ in
|
|
// endedDrag = true
|
|
// var pulledOutWidth = CGFloat(0)
|
|
// if viewState.width < 0 {
|
|
// pulledOutWidth = CGFloat(0)
|
|
// } else if abs(viewState.width + pulledOut.width) > 30 {
|
|
// pulledOutWidth = CGFloat(200)
|
|
// }
|
|
|
|
// withAnimation(.spring(response: 0.2)) {
|
|
// pulledOut.width = pulledOutWidth
|
|
// viewState = .zero
|
|
// dragOffset = .zero
|
|
// }
|
|
// }
|
|
// )
|
|
// }
|
|
|
|
// func handleVisibilityChanged(_: String, change _: VisibilityChange, tracker: VisibilityTracker<String>) {
|
|
// // var printRate: Int64 = 10
|
|
// gTracker = 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!]!
|
|
// }
|
|
|
|
// }
|
|
|