gloss-ios/gloss/ContentView.swift

963 lines
40 KiB
Swift
Raw Normal View History

//
// ContentView.swift
// gloss
//
// Created by Saint on 10/23/22.
//
import GRDB
import GRDBQuery
2024-05-15 08:57:41 -07:00
import SwiftUIIntrospect
import os
2024-05-15 08:57:41 -07:00
import SwiftUI
import WrappingHStack
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
2024-05-15 08:57:41 -07:00
var currentId: String?
var currentOffset: CGFloat?
2023-04-23 20:41:17 -07:00
var gTracker: VisibilityTracker<String>?
2023-06-01 12:45:36 -07:00
var printCount: Int64 = 0
2023-04-23 20:41:17 -07:00
2023-08-16 12:19:14 -07:00
var disableDrop = false
// var curBook = "John"
2024-05-15 08:57:41 -07:00
public extension UserDefaults {
func optionalInt(forKey defaultName: String) -> Int? {
2023-02-28 14:03:58 -08:00
let defaults = self
if let value = defaults.value(forKey: defaultName) {
return value as? Int
}
2024-05-15 08:57:41 -07:00
return nil
2023-02-28 14:03:58 -08:00
}
2024-05-15 08:57:41 -07:00
func optionalBool(forKey defaultName: String) -> Bool? {
2023-02-28 14:03:58 -08:00
let defaults = self
if let value = defaults.value(forKey: defaultName) {
return value as? Bool
}
return nil
}
}
2023-11-14 13:39:46 -08:00
func goToRibbon(selectedRibbon: Ribbon,
destRibbon: Ribbon,
2023-05-31 13:57:17 -07:00
scrollId: Binding<String?>,
scrollOffset: Binding<CGFloat?>,
refresh: Binding<Bool>,
2023-06-27 16:04:24 -07:00
showOverlay: Binding<Bool>,
2023-06-01 12:45:36 -07:00
appDatabase: AppDatabase,
2024-05-15 08:57:41 -07:00
loading: Bool)
2023-06-01 12:45:36 -07:00
{
Task {
2023-11-14 13:39:46 -08:00
// print("SELECTED RIBBON", selectedRibbon)
2023-05-31 13:57:17 -07:00
var scrollOffsetToSave = currentOffset
var scrollIdToSave = currentId
var updatedRibbon = selectedRibbon
2024-05-15 08:57:41 -07:00
if selectedRibbon.id != destRibbon.id! || loading {
print("switching ribbons")
2023-11-14 13:39:46 -08:00
2023-06-27 16:04:24 -07:00
// withAnimation(.spring(response: 0.05)) {
2024-05-15 08:57:41 -07:00
// showOverlay.wrappedValue = true
showOverlay.wrappedValue = true
2023-06-27 16:04:24 -07:00
// }
2023-05-31 13:57:17 -07:00
2024-05-15 08:57:41 -07:00
if loading {
2023-06-01 12:45:36 -07:00
currentId = destRibbon.scrollId
// currentOffset = CGFloat(destRibbon.scrollOffset)
}
2023-05-31 13:57:17 -07:00
scrollId.wrappedValue = destRibbon.scrollId
// print("setting scroll offset")
2023-05-31 13:57:17 -07:00
scrollOffset.wrappedValue = CGFloat(destRibbon.scrollOffset)
// print(scrollOffset.wrappedValue)
// print("end setting scroll offset")
2023-05-31 13:57:17 -07:00
refresh.wrappedValue.toggle()
var updateSelectRibbon = SelectedRibbon(id: Int64(1), ribbonId: destRibbon.id!)
// print("Saving selected ribbon")
// print(updateSelectRibbon)
2023-05-31 13:57:17 -07:00
do {
_ = try await appDatabase.saveSelectedRibbon(&updateSelectRibbon)
2024-05-15 08:57:41 -07:00
} catch {
2023-05-31 13:57:17 -07:00
// Print("something wrong")
}
}
2024-05-15 08:57:41 -07:00
if !loading {
2023-06-01 12:45:36 -07:00
print("not loading")
2023-06-27 16:04:24 -07:00
updatedRibbon.scrollOffset = Int(floor(scrollOffsetToSave!))
2023-06-01 12:45:36 -07:00
updatedRibbon.scrollId = scrollIdToSave!
2023-05-31 13:57:17 -07:00
2023-06-01 12:45:36 -07:00
_ = try await appDatabase.saveRibbon(&updatedRibbon)
// print("saved updatedRibbon", updatedRibbon)
2023-05-31 13:57:17 -07:00
2023-06-01 12:45:36 -07:00
// print("UPDATED")
// scrollOffsetToSave = userDefaults.object(forKey: "currentOffset") as? CGFloat
// scrollIdToSave = userDefaults.object(forKey: "currentId") as? String
} else {
print("loading")
}
2023-05-31 13:57:17 -07:00
// print("scrollOffsetToSave: ", scrollOffsetToSave)
// print("scrollIdToSave: ", scrollIdToSave)
2023-05-31 13:57:17 -07:00
}
}
2023-11-14 13:39:46 -08:00
2023-08-03 12:40:12 -07:00
extension View {
@ViewBuilder
func `if`<Transform: View>(_ condition: Bool, transform: (Self) -> Transform) -> some View {
if condition { transform(self) }
else { self }
}
}
2023-05-31 13:57:17 -07:00
2024-05-15 08:57:41 -07:00
struct RibbonCrown: View {
2023-03-01 10:47:34 -08:00
var ribbon: Ribbon
2024-05-15 08:57:41 -07:00
@Binding var scrollId: String?
@Binding var scrollOffset: CGFloat?
@Binding var showOverlay: Bool
@Binding var refresh: Bool
var draggedRibbon: Ribbon?
var isDragging: Bool
2023-02-28 14:03:58 -08:00
var height = CGFloat(45)
2023-07-21 17:19:30 -07:00
var xOffset = CGFloat(25)
var scale = 0.65
2023-02-28 14:03:58 -08:00
@Environment(\.appDatabase) private var appDatabase
2023-03-01 10:47:34 -08:00
@Query(SelectedRibbonRequest()) private var sr: [Ribbon]
2023-02-28 14:03:58 -08:00
@State var saveOffset = CGFloat()
var body: some View {
ZStack {
2023-11-14 13:39:46 -08:00
MyIcon().frame(
width: CGFloat(100 * 1.66 * scale),
height: CGFloat(100 * scale),
alignment: .center
2024-05-15 08:57:41 -07:00
).foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
2023-11-14 13:39:46 -08:00
.if(draggedRibbon != nil && draggedRibbon!.id == ribbon.id && isDragging) { $0.overlay(Color(red: 0.1, green: 0.1, blue: 0.1)) }
2024-05-15 08:57:41 -07:00
// .offset(x: 10)
2023-08-03 12:40:12 -07:00
2023-11-14 13:39:46 -08:00
Text(ribbon.title)
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
// .foregroundColor(.white))
// .foregroundColor(.black)
.frame(minWidth: CGFloat(70),
2024-05-15 08:57:41 -07:00
maxWidth: CGFloat(70),
minHeight: height,
maxHeight: height,
alignment: .center)
2023-08-03 12:40:12 -07:00
2023-11-14 13:39:46 -08:00
.if(draggedRibbon != nil && draggedRibbon!.id == ribbon.id && isDragging) { $0.overlay(Color(red: 0.1, green: 0.1, blue: 0.1)) }
2023-08-03 12:40:12 -07:00
2023-11-14 13:39:46 -08:00
// .if(!isDragging || draggedRibbon == nil || draggedRibbon!.id != ribbon.id) { $0.background(Color(red: 0.1, green: 0.1, blue: 0.1)) }
// .if(draggedRibbon != nil && draggedRibbon!.id == ribbon.id) { $0.background(.red) }
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
// .offset(x: 10)
// .background(Color(red: 0.1, green: 0.1, blue: 0.1))
// .background(.red)
// .background(.yellow)
.multilineTextAlignment(.center)
// .minimumScaleFactor(0.5)
// .padding([.top, .bottom], 10)
.font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10)))
}
2024-05-15 08:57:41 -07:00
.frame(width: CGFloat(100 * 1.66 * scale + 10), height: CGFloat(100 * scale + 5))
2023-03-01 10:47:34 -08:00
}
}
2023-02-28 14:03:58 -08:00
2023-03-11 20:31:48 -08:00
class Verse: NSObject, Codable {
var body: String
var verse: Int
}
func makeVerseView(seg: SegDenorm) -> some View {
var retView = Text("")
var segSplit = seg.body.components(separatedBy: ";;")
let decoder = JSONDecoder()
2024-05-15 08:57:41 -07:00
for (index, item) in segSplit.enumerated() {
2023-03-11 20:31:48 -08:00
let verse = try! decoder.decode(Verse.self, from: item.data(using: .utf8)!)
retView = retView + Text(String(verse.verse))
2024-05-15 08:57:41 -07:00
.font(Font.custom("AveriaSerifLibre-Regular", size: 6))
.baselineOffset(6.0)
.foregroundColor(Color.white)
2023-03-11 20:31:48 -08:00
retView = retView + Text(verse.body)
2024-05-15 08:57:41 -07:00
.foregroundColor(Color.white)
.font(Font.custom("AveriaSerifLibre-Regular", size: 15))
}
2023-03-11 20:31:48 -08:00
return retView
}
2023-03-01 10:47:34 -08:00
2023-03-11 20:31:48 -08:00
private struct SegRow: View {
var seg: SegDenorm
2023-06-01 12:45:36 -07:00
var ribbonId: Int64
2023-03-01 10:47:34 -08:00
2023-03-11 20:31:48 -08:00
var body: some View {
var retView = Text("")
2024-05-15 08:57:41 -07:00
// .onTapGesture {
// // selectedLine = seg.id
// // Print(selectedLine)
// Print("meow")
// // Print(verse.body)
// }
2023-03-11 20:31:48 -08:00
var segSplit = seg.body.components(separatedBy: ";;")
let decoder = JSONDecoder()
// Text(segSplit[0].body)
// .id(seg.id)
// VStack {
2024-05-15 08:57:41 -07:00
// ForEach(segSplit.indices) { i in
segSplit.enumerated().forEach { _, item in
let verse = try! decoder.decode(Verse.self, from: item.data(using: .utf8)!)
var attributedString: AttributedString {
// var result = AttributedString("Hello World!")
var result = AttributedString(verse.body)
// result.underlineStyle = Text.LineStyle(
// pattern: .dot, color: .white)
return result
}
2023-05-31 13:57:17 -07:00
2024-05-15 08:57:41 -07:00
retView = retView + Text(String(ribbonId))
// retView = retView + Text(attributedString)
2023-03-11 20:31:48 -08:00
// Text(seg.body)
// .contentShape(Rectangle())
2023-04-23 20:41:17 -07:00
.font(Font.custom("AveriaSerifLibre-Regular", size: 10))
2023-03-11 20:31:48 -08:00
.baselineOffset(6.0)
2023-05-31 13:57:17 -07:00
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
2023-03-11 20:31:48 -08:00
2024-05-15 08:57:41 -07:00
retView = retView +
Text(attributedString)
2023-05-31 13:57:17 -07:00
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
2023-04-23 20:41:17 -07:00
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
2024-05-15 08:57:41 -07:00
// .frame(maxWidth: .infinity, alignment: .leading)
// .contentShape(Rectangle())
2023-03-01 10:47:34 -08:00
2024-05-15 08:57:41 -07:00
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "body" + String(i))
// .id(seg.id)
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "verse" + String(i))
// .id(seg.id)
// .onTapGesture {
// selectedLine = seg.id
// Print(selectedLine)
// }
}
// }
2024-05-15 08:57:41 -07:00
let myText = "There was a man sent from God, whose name was John. This man came for a witness, to give testimony of the light, that all men might believe through him. He was not the light, but was to give testimony of the light. That was the true light, which enlighteneth every man that cometh into this world. He was in the world, and the world was made by him, and the world knew him not."
let arrayOfText = myText.components(separatedBy: " ")
var wordSelected = ""
var newView = WrappingHStack(alignment: .leading, horizontalSpacing: 3.5) {
ForEach(0..<arrayOfText.count, id: \.self) { index in
Text(arrayOfText[index])
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
.foregroundColor(Color.white)
// .background(Color.black)
.padding(.horizontal, 0)
.onTapGesture {
Print(arrayOfText[index])
Print(index)
}
}
}
// return retView
return newView } }
struct ContentView: View {
@State var viewState = CGSize.zero
@State var pulledOut = CGSize.zero
2024-05-15 08:57:41 -07:00
@State var taskTitle: String = "FIRST DOGGG"
@State var curBook: String = "Matthew"
@State var selectedLine: Int64?
2023-02-28 14:03:58 -08:00
2024-05-15 08:57:41 -07:00
@State var thisScrollView: UIScrollView?
2023-03-11 20:31:48 -08:00
@State var scrollUpdate = false
2023-03-01 10:47:34 -08:00
@State var initLoad = false
2023-04-21 17:06:30 -07:00
// set this to scroll to area
2024-05-15 08:57:41 -07:00
@State var scrollId: String?
@State var scrollOffset: CGFloat?
2023-04-21 17:06:30 -07:00
2024-05-15 08:57:41 -07:00
@State var setScrollOffset: CGFloat?
@State var showOverlay: Bool = false
2023-07-21 17:19:30 -07:00
@State var vertSep = CGFloat(20)
2023-06-01 12:45:36 -07:00
@Environment(\.appDatabase) private var appDatabase
2023-03-11 20:31:48 -08:00
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
2023-04-21 17:06:30 -07:00
// @State var scrollDelegate: ScrollViewHandler
2023-03-11 20:31:48 -08:00
// @State var scrollDelegate = ScrollViewHandler()
2023-03-01 10:47:34 -08:00
2023-02-28 14:03:58 -08:00
// @State var selectedRibbonId = Int64(UserDefaults.standard.optionalInt(forKey: "selectedRibbonId") ?? 1)
2023-03-01 10:47:34 -08:00
// ribbon
2023-06-01 12:45:36 -07:00
// @Query(SelectedRibbonRequest()) private var selectedRibbon: [Ribbon]
2023-02-28 14:03:58 -08:00
@State var endedDrag = true
@State var readOffset = CGPoint()
2023-07-21 17:19:30 -07:00
@State var dragOffset = CGFloat()
2023-11-14 13:39:46 -08:00
2023-03-11 20:31:48 -08:00
@State var refresh: Bool = false
2023-06-01 12:45:36 -07:00
@State var refresh2: Bool = false
2023-11-14 13:39:46 -08:00
@State var draggedRibbon: Ribbon?
2023-08-03 12:40:12 -07:00
@State var isDragging = false
2023-11-14 13:39:46 -08:00
@State var reorder = true
@Query(RibbonRequest()) private var ribbons: [Ribbon]
2023-06-01 12:45:36 -07:00
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
2023-02-28 14:03:58 -08:00
// @Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1))) private var selectedRibbon: [Ribbon]
2023-11-14 13:39:46 -08:00
init() {
UITableView.appearance().backgroundColor = UIColor(Color(red: 0.2, green: 0.2, blue: 0.2))
2024-05-15 08:57:41 -07:00
_selectedRibbon = Query(SelectedRibbonRequest())
2023-06-01 12:45:36 -07:00
2023-04-21 17:06:30 -07:00
// self._scrollDelegate = State(initialValue: ScrollViewHandler())
}
2023-11-14 13:39:46 -08:00
var body: some View {
// Print("rendering")
2023-03-11 20:31:48 -08:00
var size1 = CGFloat(11)
var size2 = CGFloat(100)
var fontSize = CGFloat(15)
var scale = 0.65
var height = CGFloat(50)
var xOffset = CGFloat(25)
2023-07-21 17:19:30 -07:00
2023-07-31 10:54:42 -07:00
var width = CGFloat(100 * 1.66 * scale)
// ForEach(ribbons) { ribbon in
// data.append(ribbon)
// }
2023-07-31 10:54:42 -07:00
GeometryReader { geometry in
2024-05-15 08:57:41 -07:00
ZStack(alignment: .top) {
VStack(alignment: .leading) {
2023-07-21 17:19:30 -07:00
VStack {
// ReorderableForEach($data, allowReordering: $reorder) { item, isDragged in
ForEach(ribbons) { ribbon in
RibbonCrown(ribbon: ribbon,
2024-05-15 08:57:41 -07:00
scrollId: $scrollId,
scrollOffset: $scrollOffset,
showOverlay: $showOverlay,
2024-05-15 08:57:41 -07:00
refresh: $refresh,
2023-08-03 12:40:12 -07:00
draggedRibbon: draggedRibbon,
2024-05-15 08:57:41 -07:00
isDragging: isDragging)
.onDrag {
self.draggedRibbon = ribbon
return NSItemProvider()
}
.onDrop(of: [.item],
delegate: DropViewDelegate(destinationItem: ribbon,
draggedItem: $draggedRibbon,
isDragging: $isDragging,
appDatabase: appDatabase))
.offset(x: 6, y: 6)
2023-07-31 10:54:42 -07:00
}
2023-07-21 17:19:30 -07:00
2023-07-31 10:54:42 -07:00
// .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
2023-07-21 17:19:30 -07:00
}
.frame(width: geometry.size.width, height: geometry.size.height - 100, alignment: .topLeading)
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
.zIndex(0)
.animation(.default, value: ribbons)
2023-08-03 15:22:18 -07:00
.onDrop(of: [.item],
2024-05-15 08:57:41 -07:00
delegate: DropViewDelegate2(isDragging: $isDragging))
2023-08-03 15:22:18 -07:00
2023-07-21 17:19:30 -07:00
// Spacer()
2023-03-11 20:31:48 -08:00
// ForEach(ribbons) { ribbon in
// RibbonCrown(ribbon: ribbon,
// scrollId:$scrollId,
// scrollOffset:$scrollOffset,
// showOverlay: $showOverlay,
// refresh:$refresh
// )
// // .buttonStyle(BlueButtonStyle())
// // .frame(alignment: .topLeading)
// // .background(Color(red: 0.4, green: 0.4, blue: 0.1))
// .animation(nil)
// }
}
2023-03-11 20:31:48 -08:00
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
2023-07-21 17:19:30 -07:00
.frame(alignment: .topLeading)
2024-05-15 08:57:41 -07:00
// .animation(nil)
2023-07-21 17:19:30 -07:00
VStack {
ScrollViewReader { proxy in
VisibilityTrackingScrollView(action: handleVisibilityChanged) {
// ScrollView {
LazyVStack {
ForEach(segs) { seg in
SegRow(seg: seg,
2024-05-15 08:57:41 -07:00
ribbonId: selectedRibbon[0].id!)
.id("\(seg.id)")
.offset(x: -dragOffset)
// .offset(x: pulledOut.width)
2023-07-21 17:19:30 -07:00
2024-05-15 08:57:41 -07:00
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
.trackVisibility(id: "\(seg.id)")
2023-07-21 17:19:30 -07:00
// .onChange(of: geometry.frame(in: .named("scrollView"))) { imageRect in
2024-05-15 08:57:41 -07:00
// Print(imageRect)
// Print(outerProxy)
2023-07-21 17:19:30 -07:00
// if isInView(innerRect: imageRect, isIn: outerProxy) {
// visibleIndex.insert(item)
2024-05-15 08:57:41 -07:00
// } else {
2023-07-21 17:19:30 -07:00
// visibleIndex.remove(item)
// }
// }
}
2023-06-27 16:04:24 -07:00
}
2023-07-21 17:19:30 -07:00
.background(Color(red: 0.18, green: 0.18, blue: 0.18))
}
2023-06-01 12:45:36 -07:00
2024-05-15 08:57:41 -07:00
.onAppear {
2023-07-21 17:19:30 -07:00
Print("APPEAR")
// Print(selectedRibbon[0])
// scrollId = "3"
// scrollOffset = 103
// refresh.toggle()
goToRibbon(selectedRibbon: selectedRibbon[0],
destRibbon: selectedRibbon[0],
scrollId: $scrollId,
scrollOffset: $scrollOffset,
refresh: $refresh,
showOverlay: $showOverlay,
appDatabase: appDatabase,
loading: true)
}
2024-05-15 08:57:41 -07:00
.onChange(of: refresh) { _ in
// if let target = target {
// gTracker!.visibleViews["123123"] = CGFloat(100)
2023-07-21 17:19:30 -07:00
// Print("ON CHANGE", gTracker!.visibleViews)
// Print("removing", gTracker!.visibleViews.removeAll())
2023-06-01 12:45:36 -07:00
2023-07-21 17:19:30 -07:00
Task {
DispatchQueue.main.async {
Print("scroll Id target: \(scrollId)")
2024-05-15 08:57:41 -07:00
proxy.scrollTo(scrollId!, anchor: .top)
2023-07-21 17:19:30 -07:00
// proxy.scrollTo(String(Int(scrollId!)! + 1))
// currentId = scrollId!
// if (currentId != scrollId!) {
2023-06-02 14:25:20 -07:00
2023-07-21 17:19:30 -07:00
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
Print(" scroll id target", scrollId)
Print(" current id ", currentId)
Print(gTracker!.sortedViewIDs)
2024-05-15 08:57:41 -07:00
if currentId! != scrollId! {
2023-07-21 17:19:30 -07:00
Print("NO MATCH")
}
2023-06-02 14:25:20 -07:00
2023-07-21 17:19:30 -07:00
// Print(" scroll offset target", scrollOffset)
Print(" current offset ", gTracker!.visibleViews[scrollId!])
var curOffset = gTracker!.visibleViews[scrollId!]
Print(" stats", gTracker!.visibleViews)
// // setScrollOffset = CGFloat(Int(currentOffset!) * -1 + Int(scrollOffset!))
2024-05-15 08:57:41 -07:00
if curOffset != nil {
2023-07-21 17:19:30 -07:00
setScrollOffset = CGFloat(Int(scrollOffset!) - Int(curOffset!))
Print("applying scroll offset \(setScrollOffset)")
// // setScrollOffset = CGFloat(Int(scrollOffset!))
// Print("setting scroll offset", setScrollOffset)
refresh2.toggle()
} else {
var adjust = (Int(scrollId!)! - Int(currentId!)!) * 200
Print("adjusting \(adjust)")
2023-06-02 14:25:20 -07:00
2023-07-21 17:19:30 -07:00
setScrollOffset = CGFloat(adjust)
refresh.toggle()
}
// // currentId = scrollId!
2023-06-02 14:25:20 -07:00
2023-07-21 17:19:30 -07:00
// DispatchQueue.main.async {
2023-06-02 14:25:20 -07:00
2023-07-21 17:19:30 -07:00
// currentOffset = scrollOffset!
// currentId = scrollId!
// }
}
2023-06-27 16:04:24 -07:00
}
2023-06-02 14:25:20 -07:00
}
2023-04-21 17:06:30 -07:00
}
2024-05-15 08:57:41 -07:00
.introspect(.scrollView, on: .iOS(.v13, .v14, .v15, .v16, .v17)) { scrollView in Print("introspect")
// Print("Scroll delegate offset", scrollDelegate.scrollOffset)
2023-07-21 17:19:30 -07:00
2024-05-15 08:57:41 -07:00
if setScrollOffset != nil {
2023-07-21 17:19:30 -07:00
// Print("Setting scroll offset in introspect", setScrollOffset)
2023-11-14 13:39:46 -08:00
DispatchQueue.main.async {
2023-07-21 17:19:30 -07:00
scrollView.contentOffset.y = scrollView.contentOffset.y + setScrollOffset!
setScrollOffset = nil
2024-05-15 08:57:41 -07:00
// self.showOverlay = false
2023-07-21 17:19:30 -07:00
withAnimation {
showOverlay = false
}
}
}
// if (thisScrollView == nil) {
// Print("init scroll")
// thisScrollView = scrollView
// scrollView.contentOffset.y = CGFloat(selectedRibbon[0].scrollOffset)
// }
Print("end introspect")
}
.listStyle(PlainListStyle())
2023-06-02 14:25:20 -07:00
}
2023-07-21 17:19:30 -07:00
.zIndex(1)
.background(Color(red: 0.2, green: 0.2, blue: 0.2))
2023-11-14 13:39:46 -08:00
.frame(width: geometry.size.width - 50, height: geometry.size.height / 2 - vertSep)
2024-05-15 08:57:41 -07:00
.offset(x: 30, y: 0)
2023-07-21 17:19:30 -07:00
.offset(x: pulledOut.width)
.offset(x: viewState.width, y: viewState.height)
.gesture(
DragGesture()
2024-05-15 08:57:41 -07:00
.onChanged { gesture in
2023-07-21 17:19:30 -07:00
2024-05-15 08:57:41 -07:00
if endedDrag {
endedDrag = false
scrollOffset = readOffset.y - 20
// _ = Print("meow")
2023-06-27 16:04:24 -07:00
}
2024-05-15 08:57:41 -07:00
// logger.error("hello222")
// NSLog("hellooo")
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
}
}
// offset.y = gesture.translation.width
// logger.log("hello")
2023-06-27 16:04:24 -07:00
}
2024-05-15 08:57:41 -07:00
.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)
}
2023-06-02 14:25:20 -07:00
2024-05-15 08:57:41 -07:00
withAnimation(.spring(response: 0.2)) {
pulledOut.width = pulledOutWidth
viewState = .zero
dragOffset = .zero
}
2023-07-21 17:19:30 -07:00
}
)
2024-05-15 08:57:41 -07:00
Text("separator").foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
.gesture(
DragGesture()
.onChanged { gesture in
2023-07-21 17:19:30 -07:00
2024-05-15 08:57:41 -07:00
vertSep = vertSep - gesture.translation.height
Print(gesture.translation.width)
Print(gesture.translation.height)
Print("drag")
// if (endedDrag) {
// endedDrag = false
// scrollOffset = readOffset.y - 20
// // _ = Print("meow")
// }
//// logger.error("hello222")
//// NSLog("hellooo")
// Print(viewState.width)
// if (abs(gesture.translation.width) > 20) {
// viewState.width = gesture.translation.width
// }
////offset.y = gesture.translation.width
//// logger.log("hello")
}
// .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
// }
// }
)
ScrollViewReader { _ in
2023-07-21 17:19:30 -07:00
VisibilityTrackingScrollView(action: handleVisibilityChanged2) {
// ScrollView {
LazyVStack {
ForEach(segs) { seg in
SegRow(seg: seg,
2024-05-15 08:57:41 -07:00
ribbonId: selectedRibbon[0].id!)
.id("\(seg.id)")
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
.trackVisibility(id: "\(seg.id)")
2023-07-21 17:19:30 -07:00
// .onChange(of: geometry.frame(in: .named("scrollView"))) { imageRect in
2024-05-15 08:57:41 -07:00
// Print(imageRect)
// Print(outerProxy)
2023-07-21 17:19:30 -07:00
// if isInView(innerRect: imageRect, isIn: outerProxy) {
// visibleIndex.insert(item)
2024-05-15 08:57:41 -07:00
// } else {
2023-07-21 17:19:30 -07:00
// visibleIndex.remove(item)
// }
// }
}
}
.background(Color(red: 0.18, green: 0.18, blue: 0.18))
}
2023-06-27 16:04:24 -07:00
2024-05-15 08:57:41 -07:00
.onAppear {
2023-07-21 17:19:30 -07:00
Print("APPEAR")
// Print(selectedRibbon[0])
// scrollId = "3"
// scrollOffset = 103
// refresh.toggle()
// goToRibbon(selectedRibbon: selectedRibbon[0],
// destRibbon: selectedRibbon[0],
// scrollId: $scrollId,
// scrollOffset: $scrollOffset,
// refresh: $refresh,
// showOverlay: $showOverlay,
// appDatabase: appDatabase,
// loading: true)
2023-02-28 14:03:58 -08:00
}
2024-05-15 08:57:41 -07:00
// .onChange(of: refresh) { target in
2023-07-21 17:19:30 -07:00
// //if let target = target {
// //gTracker!.visibleViews["123123"] = CGFloat(100)
// // Print("ON CHANGE", gTracker!.visibleViews)
// // Print("removing", gTracker!.visibleViews.removeAll())
// Task {
// DispatchQueue.main.async {
// Print("scroll Id target: \(scrollId)")
// proxy.scrollTo(scrollId! , anchor: .top)
// // proxy.scrollTo(String(Int(scrollId!)! + 1))
// // currentId = scrollId!
// // if (currentId != scrollId!) {
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// Print(" scroll id target", scrollId)
// Print(" current id ", currentId)
// Print(gTracker!.sortedViewIDs)
// if (currentId! != scrollId!) {
// Print("NO MATCH")
// }
// // Print(" scroll offset target", scrollOffset)
// Print(" current offset ", gTracker!.visibleViews[scrollId!])
// var curOffset = gTracker!.visibleViews[scrollId!]
// Print(" stats", gTracker!.visibleViews)
// // // setScrollOffset = CGFloat(Int(currentOffset!) * -1 + Int(scrollOffset!))
// if (curOffset != nil) {
// setScrollOffset = CGFloat(Int(scrollOffset!) - Int(curOffset!))
// Print("applying scroll offset \(setScrollOffset)")
// // // setScrollOffset = CGFloat(Int(scrollOffset!))
// // Print("setting scroll offset", setScrollOffset)
// refresh2.toggle()
// } else {
// var adjust = (Int(scrollId!)! - Int(currentId!)!) * 200
// Print("adjusting \(adjust)")
// setScrollOffset = CGFloat(adjust)
// refresh.toggle()
// }
// // // currentId = scrollId!
// // DispatchQueue.main.async {
// // currentOffset = scrollOffset!
// // currentId = scrollId!
// // }
// }
// }
// }
2024-05-15 08:57:41 -07:00
// }
// .introspectScrollView { scrollView in
2023-07-21 17:19:30 -07:00
// Print("introspect")
// // scrollView.delegate = scrollDelegate
// //Print("Scroll delegate offset", scrollDelegate.scrollOffset)
// if (setScrollOffset != nil) {
// // Print("Setting scroll offset in introspect", setScrollOffset)
2023-11-14 13:39:46 -08:00
// DispatchQueue.main.async {
2023-07-21 17:19:30 -07:00
// scrollView.contentOffset.y = scrollView.contentOffset.y + setScrollOffset!
// setScrollOffset = nil
// withAnimation {
// showOverlay = false
// }
// }
// }
// // if (thisScrollView == nil) {
// // Print("init scroll")
// // thisScrollView = scrollView
// // scrollView.contentOffset.y = CGFloat(selectedRibbon[0].scrollOffset)
// // }
// Print("end instrospect")
2024-05-15 08:57:41 -07:00
// }
2023-07-21 17:19:30 -07:00
.listStyle(PlainListStyle())
}
2023-07-21 17:19:30 -07:00
.zIndex(1)
.background(Color(red: 0.2, green: 0.2, blue: 0.2))
.frame(width: geometry.size.width - 50)
2024-05-15 08:57:41 -07:00
.offset(x: 30, y: 0)
2023-07-21 17:19:30 -07:00
.offset(x: pulledOut.width)
.offset(x: viewState.width, y: viewState.height)
.gesture(
DragGesture()
2024-05-15 08:57:41 -07:00
.onChanged { gesture in
2023-07-21 17:19:30 -07:00
2024-05-15 08:57:41 -07:00
if endedDrag {
endedDrag = false
scrollOffset = readOffset.y - 20
// _ = Print("meow")
}
// logger.error("hello222")
// NSLog("hellooo")
Print(viewState.width)
if abs(gesture.translation.width) > 20 {
viewState.width = gesture.translation.width
}
// offset.y = gesture.translation.width
// logger.log("hello")
2023-07-21 17:19:30 -07:00
}
2024-05-15 08:57:41 -07:00
.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)
}
2024-05-15 08:57:41 -07:00
withAnimation(.spring(response: 0.2)) {
pulledOut.width = pulledOutWidth
viewState = .zero
}
2023-07-21 17:19:30 -07:00
}
)
}
2023-06-27 16:04:24 -07:00
2024-05-15 08:57:41 -07:00
if showOverlay {
2023-06-27 16:04:24 -07:00
Rectangle()
2023-11-14 13:39:46 -08:00
.frame(width: geometry.size.width - 50, height: geometry.size.height + 200)
.background(.ultraThinMaterial)
2023-06-27 16:04:24 -07:00
2024-05-15 08:57:41 -07:00
// .blur(radius: 0.8)
.offset(x: 30, y: -100)
2023-11-14 13:39:46 -08:00
.opacity(0.98)
.transition(.opacity)
2023-06-27 16:04:24 -07:00
2023-11-14 13:39:46 -08:00
// .frame(width: geometry.size.width - 50)
.offset(x: pulledOut.width)
.offset(x: viewState.width, y: viewState.height)
.zIndex(2)
2023-06-27 16:04:24 -07:00
}
}
}
}
2024-05-15 08:57:41 -07:00
func handleVisibilityChanged2(_: String, change _: VisibilityChange, tracker _: VisibilityTracker<String>) {}
2024-05-15 08:57:41 -07:00
func handleVisibilityChanged(_: String, change _: VisibilityChange, tracker: VisibilityTracker<String>) {
2023-06-02 14:25:20 -07:00
// var printRate: Int64 = 10
2023-06-01 12:45:36 -07:00
gTracker = tracker
2023-04-21 17:06:30 -07:00
// @Environment(\.appDatabase) var appDatabase
// switch change {
// case .shown: print("\(id) shown")
// case .hidden: print("\(id) hidden")
// }
2023-06-02 14:25:20 -07:00
// if (printCount % printRate == 0) {
// print("VISIBILITY CHANGED STARTED")
// print(tracker.visibleViews)
// print(tracker.sortedViewIDs)
// print("VISIBILITY CHANGED ENDED")
// }
// printCount += 1
2023-06-01 12:45:36 -07:00
2023-11-14 13:39:46 -08:00
// if (currentId != nil) {
2023-04-21 17:06:30 -07:00
// currentOffset = tracker.visibleViews[currentId!]!
// }
2023-04-23 20:41:17 -07:00
let visibleViews2 = Array(tracker.visibleViews.keys)
2024-05-15 08:57:41 -07:00
if visibleViews2.count == 0 {
return
}
2023-06-02 16:20:04 -07:00
// currentId = tracker.sortedViewIDs[tracker.sortedViewIDs.count - 1]
currentId = tracker.sortedViewIDs[0]
2023-06-02 14:25:20 -07:00
currentOffset = tracker.visibleViews[currentId!]!
2023-06-02 16:20:04 -07:00
// if (Int(currentOffset!) != -1 && Int(currentOffset!) < 0) {
// if (tracker.sortedViewIDs.count > 1) {
// currentId = tracker.sortedViewIDs[1]
// currentOffset = tracker.visibleViews[currentId!]!
// }
// }
2024-05-15 08:57:41 -07:00
// if (currentId != nil) {
// // if (printCount % printRate == 0) {
// // print(printCount)
// // print("cat current ID:", currentId)
// // }
// // print("got here")
// currentOffset = tracker.visibleViews[currentId!]!
// }
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()
2023-08-03 15:22:18 -07:00
struct DropViewDelegate2: DropDelegate {
@Binding var isDragging: Bool
2024-05-15 08:57:41 -07:00
func dropUpdated(info _: DropInfo) -> DropProposal? {
2023-08-03 15:22:18 -07:00
return DropProposal(operation: .move)
}
2024-05-15 08:57:41 -07:00
func performDrop(info _: DropInfo) -> Bool {
2023-08-04 12:02:22 -07:00
isDragging = false
2023-08-03 15:22:18 -07:00
return true
}
2024-05-15 08:57:41 -07:00
func dropEntered(info _: DropInfo) {
2023-08-03 15:22:18 -07:00
isDragging = true
print("SECOND DROPPPOOO")
}
}
struct DropViewDelegate: DropDelegate {
let destinationItem: Ribbon
// @Binding var colors: [Color]
@Binding var draggedItem: Ribbon?
2023-08-03 12:40:12 -07:00
@Binding var isDragging: Bool
let appDatabase: AppDatabase
2023-11-14 13:39:46 -08:00
2024-05-15 08:57:41 -07:00
func dropUpdated(info _: DropInfo) -> DropProposal? {
return DropProposal(operation: .move)
}
2024-05-15 08:57:41 -07:00
func dropExited(info _: DropInfo) {
2023-08-03 12:40:12 -07:00
print("EXITED")
isDragging = false
}
2024-05-15 08:57:41 -07:00
func dropEntered(info _: DropInfo) {
Task {
2023-08-03 12:40:12 -07:00
isDragging = true
2024-05-15 08:57:41 -07:00
if draggedItem == nil {
2023-08-03 12:40:12 -07:00
return
}
2023-11-14 13:39:46 -08:00
if disableDrop {
2024-05-15 08:57:41 -07:00
return
2023-11-14 13:39:46 -08:00
}
2023-08-16 12:19:14 -07:00
2023-11-14 13:39:46 -08:00
var newRibbon = draggedItem!
var newDest = destinationItem
var oldPos = draggedItem!.pos
var newPos = destinationItem.pos
print("dragged item")
print(draggedItem)
print("dest item")
print(destinationItem)
2024-05-15 08:57:41 -07:00
if draggedItem!.id! == destinationItem.id! {
return
}
newRibbon.pos = destinationItem.pos
2024-05-15 08:57:41 -07:00
_ = try await appDatabase.updateRibbonPosition(&newRibbon, oldPos, newPos)
2023-08-16 12:19:14 -07:00
disableDrop = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
disableDrop = false
}
2023-08-03 12:40:12 -07:00
draggedItem!.pos = newPos
2023-08-03 12:40:12 -07:00
// draggedItem = nil
}
}
2023-11-14 13:39:46 -08:00
2024-05-15 08:57:41 -07:00
func performDrop(info _: DropInfo) -> Bool {
2023-08-03 12:40:12 -07:00
print("PERFORMED DROPPPP")
draggedItem = nil
2023-08-03 12:40:12 -07:00
isDragging = false
return true
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
ContentView().environment(\.appDatabase, .random())
}
}
extension View {
func Print(_ vars: Any...) -> some View {
2024-05-15 08:57:41 -07:00
for v in vars {
print(v)
}
return EmptyView()
}
}