// // 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() 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) -> 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) { // // 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!]! // } // }