gloss-ios/gloss/ContentView.swift

963 lines
40 KiB
Swift

//
// ContentView.swift
// gloss
//
// Created by Saint on 10/23/22.
//
import GRDB
import GRDBQuery
import SwiftUIIntrospect
import os
import SwiftUI
import WrappingHStack
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
var currentId: String?
var currentOffset: CGFloat?
var gTracker: VisibilityTracker<String>?
var printCount: Int64 = 0
var disableDrop = false
// var curBook = "John"
public extension UserDefaults {
func optionalInt(forKey defaultName: String) -> Int? {
let defaults = self
if let value = defaults.value(forKey: defaultName) {
return value as? Int
}
return nil
}
func optionalBool(forKey defaultName: String) -> Bool? {
let defaults = self
if let value = defaults.value(forKey: defaultName) {
return value as? Bool
}
return nil
}
}
func goToRibbon(selectedRibbon: Ribbon,
destRibbon: Ribbon,
scrollId: Binding<String?>,
scrollOffset: Binding<CGFloat?>,
refresh: Binding<Bool>,
showOverlay: Binding<Bool>,
appDatabase: AppDatabase,
loading: Bool)
{
Task {
// print("SELECTED RIBBON", selectedRibbon)
var scrollOffsetToSave = currentOffset
var scrollIdToSave = currentId
var updatedRibbon = selectedRibbon
if selectedRibbon.id != destRibbon.id! || loading {
print("switching ribbons")
// withAnimation(.spring(response: 0.05)) {
// showOverlay.wrappedValue = true
showOverlay.wrappedValue = true
// }
if loading {
currentId = destRibbon.scrollId
// currentOffset = CGFloat(destRibbon.scrollOffset)
}
scrollId.wrappedValue = destRibbon.scrollId
// print("setting scroll offset")
scrollOffset.wrappedValue = CGFloat(destRibbon.scrollOffset)
// print(scrollOffset.wrappedValue)
// print("end setting scroll offset")
refresh.wrappedValue.toggle()
var updateSelectRibbon = SelectedRibbon(id: Int64(1), ribbonId: destRibbon.id!)
// print("Saving selected ribbon")
// print(updateSelectRibbon)
do {
_ = try await appDatabase.saveSelectedRibbon(&updateSelectRibbon)
} catch {
// Print("something wrong")
}
}
if !loading {
print("not loading")
updatedRibbon.scrollOffset = Int(floor(scrollOffsetToSave!))
updatedRibbon.scrollId = scrollIdToSave!
_ = try await appDatabase.saveRibbon(&updatedRibbon)
// print("saved updatedRibbon", updatedRibbon)
// print("UPDATED")
// scrollOffsetToSave = userDefaults.object(forKey: "currentOffset") as? CGFloat
// scrollIdToSave = userDefaults.object(forKey: "currentId") as? String
} else {
print("loading")
}
// print("scrollOffsetToSave: ", scrollOffsetToSave)
// print("scrollIdToSave: ", scrollIdToSave)
}
}
extension View {
@ViewBuilder
func `if`<Transform: View>(_ condition: Bool, transform: (Self) -> Transform) -> some View {
if condition { transform(self) }
else { self }
}
}
struct RibbonCrown: View {
var ribbon: Ribbon
@Binding var scrollId: String?
@Binding var scrollOffset: CGFloat?
@Binding var showOverlay: Bool
@Binding var refresh: Bool
var draggedRibbon: Ribbon?
var isDragging: Bool
var height = CGFloat(45)
var xOffset = CGFloat(25)
var scale = 0.65
@Environment(\.appDatabase) private var appDatabase
@Query(SelectedRibbonRequest()) private var sr: [Ribbon]
@State var saveOffset = CGFloat()
var body: some View {
ZStack {
MyIcon().frame(
width: CGFloat(100 * 1.66 * scale),
height: CGFloat(100 * scale),
alignment: .center
).foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.if(draggedRibbon != nil && draggedRibbon!.id == ribbon.id && isDragging) { $0.overlay(Color(red: 0.1, green: 0.1, blue: 0.1)) }
// .offset(x: 10)
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),
maxWidth: CGFloat(70),
minHeight: height,
maxHeight: height,
alignment: .center)
.if(draggedRibbon != nil && draggedRibbon!.id == ribbon.id && isDragging) { $0.overlay(Color(red: 0.1, green: 0.1, blue: 0.1)) }
// .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)))
}
.frame(width: CGFloat(100 * 1.66 * scale + 10), height: CGFloat(100 * scale + 5))
}
}
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()
for (index, item) in segSplit.enumerated() {
let verse = try! decoder.decode(Verse.self, from: item.data(using: .utf8)!)
retView = retView + Text(String(verse.verse))
.font(Font.custom("AveriaSerifLibre-Regular", size: 6))
.baselineOffset(6.0)
.foregroundColor(Color.white)
retView = retView + Text(verse.body)
.foregroundColor(Color.white)
.font(Font.custom("AveriaSerifLibre-Regular", size: 15))
}
return retView
}
private struct SegRow: View {
var seg: SegDenorm
var ribbonId: Int64
var body: some View {
var retView = Text("")
// .onTapGesture {
// // selectedLine = seg.id
// // Print(selectedLine)
// Print("meow")
// // Print(verse.body)
// }
var segSplit = seg.body.components(separatedBy: ";;")
let decoder = JSONDecoder()
// Text(segSplit[0].body)
// .id(seg.id)
// VStack {
// 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
}
retView = retView + Text(String(ribbonId))
// retView = retView + Text(attributedString)
// Text(seg.body)
// .contentShape(Rectangle())
.font(Font.custom("AveriaSerifLibre-Regular", size: 10))
.baselineOffset(6.0)
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
retView = retView +
Text(attributedString)
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
// .frame(maxWidth: .infinity, alignment: .leading)
// .contentShape(Rectangle())
// .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)
// }
}
// }
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
@State var taskTitle: String = "FIRST DOGGG"
@State var curBook: String = "Matthew"
@State var selectedLine: Int64?
@State var thisScrollView: UIScrollView?
@State var scrollUpdate = false
@State var initLoad = false
// set this to scroll to area
@State var scrollId: String?
@State var scrollOffset: CGFloat?
@State var setScrollOffset: CGFloat?
@State var showOverlay: Bool = false
@State var vertSep = CGFloat(20)
@Environment(\.appDatabase) private var appDatabase
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
// @State var scrollDelegate: ScrollViewHandler
// @State var scrollDelegate = ScrollViewHandler()
// @State var selectedRibbonId = Int64(UserDefaults.standard.optionalInt(forKey: "selectedRibbonId") ?? 1)
// ribbon
// @Query(SelectedRibbonRequest()) private var selectedRibbon: [Ribbon]
@State var endedDrag = true
@State var readOffset = CGPoint()
@State var dragOffset = CGFloat()
@State var refresh: Bool = false
@State var refresh2: Bool = false
@State var draggedRibbon: Ribbon?
@State var isDragging = false
@State var reorder = true
@Query(RibbonRequest()) private var ribbons: [Ribbon]
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
// @Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1))) private var selectedRibbon: [Ribbon]
init() {
UITableView.appearance().backgroundColor = UIColor(Color(red: 0.2, green: 0.2, blue: 0.2))
_selectedRibbon = Query(SelectedRibbonRequest())
// self._scrollDelegate = State(initialValue: ScrollViewHandler())
}
var body: some View {
// Print("rendering")
var size1 = CGFloat(11)
var size2 = CGFloat(100)
var fontSize = CGFloat(15)
var scale = 0.65
var height = CGFloat(50)
var xOffset = CGFloat(25)
var width = CGFloat(100 * 1.66 * scale)
// ForEach(ribbons) { ribbon in
// data.append(ribbon)
// }
GeometryReader { geometry in
ZStack(alignment: .top) {
VStack(alignment: .leading) {
VStack {
// ReorderableForEach($data, allowReordering: $reorder) { item, isDragged in
ForEach(ribbons) { ribbon in
RibbonCrown(ribbon: ribbon,
scrollId: $scrollId,
scrollOffset: $scrollOffset,
showOverlay: $showOverlay,
refresh: $refresh,
draggedRibbon: draggedRibbon,
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)
}
// .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.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)
.onDrop(of: [.item],
delegate: DropViewDelegate2(isDragging: $isDragging))
// Spacer()
// 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)
// }
}
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
.frame(alignment: .topLeading)
// .animation(nil)
VStack {
ScrollViewReader { proxy in
VisibilityTrackingScrollView(action: handleVisibilityChanged) {
// ScrollView {
LazyVStack {
ForEach(segs) { seg in
SegRow(seg: seg,
ribbonId: selectedRibbon[0].id!)
.id("\(seg.id)")
.offset(x: -dragOffset)
// .offset(x: pulledOut.width)
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
.trackVisibility(id: "\(seg.id)")
// .onChange(of: geometry.frame(in: .named("scrollView"))) { imageRect in
// Print(imageRect)
// Print(outerProxy)
// if isInView(innerRect: imageRect, isIn: outerProxy) {
// visibleIndex.insert(item)
// } else {
// visibleIndex.remove(item)
// }
// }
}
}
.background(Color(red: 0.18, green: 0.18, blue: 0.18))
}
.onAppear {
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)
}
.onChange(of: refresh) { _ in
// 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!
// }
}
}
}
}
.introspect(.scrollView, on: .iOS(.v13, .v14, .v15, .v16, .v17)) { scrollView in Print("introspect")
// Print("Scroll delegate offset", scrollDelegate.scrollOffset)
if setScrollOffset != nil {
// Print("Setting scroll offset in introspect", setScrollOffset)
DispatchQueue.main.async {
scrollView.contentOffset.y = scrollView.contentOffset.y + setScrollOffset!
setScrollOffset = nil
// self.showOverlay = false
withAnimation {
showOverlay = false
}
}
}
// if (thisScrollView == nil) {
// Print("init scroll")
// thisScrollView = scrollView
// scrollView.contentOffset.y = CGFloat(selectedRibbon[0].scrollOffset)
// }
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)
.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("meow")
}
// 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")
}
.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
}
}
)
Text("separator").foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
.gesture(
DragGesture()
.onChanged { gesture in
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
VisibilityTrackingScrollView(action: handleVisibilityChanged2) {
// ScrollView {
LazyVStack {
ForEach(segs) { seg in
SegRow(seg: seg,
ribbonId: selectedRibbon[0].id!)
.id("\(seg.id)")
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
.trackVisibility(id: "\(seg.id)")
// .onChange(of: geometry.frame(in: .named("scrollView"))) { imageRect in
// Print(imageRect)
// Print(outerProxy)
// if isInView(innerRect: imageRect, isIn: outerProxy) {
// visibleIndex.insert(item)
// } else {
// visibleIndex.remove(item)
// }
// }
}
}
.background(Color(red: 0.18, green: 0.18, blue: 0.18))
}
.onAppear {
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)
}
// .onChange(of: refresh) { target in
// //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!
// // }
// }
// }
// }
// }
// .introspectScrollView { scrollView in
// Print("introspect")
// // scrollView.delegate = scrollDelegate
// //Print("Scroll delegate offset", scrollDelegate.scrollOffset)
// if (setScrollOffset != nil) {
// // Print("Setting scroll offset in introspect", setScrollOffset)
// DispatchQueue.main.async {
// 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")
// }
.listStyle(PlainListStyle())
}
.zIndex(1)
.background(Color(red: 0.2, green: 0.2, blue: 0.2))
.frame(width: geometry.size.width - 50)
.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("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
}
}
)
}
if showOverlay {
Rectangle()
.frame(width: geometry.size.width - 50, height: geometry.size.height + 200)
.background(.ultraThinMaterial)
// .blur(radius: 0.8)
.offset(x: 30, y: -100)
.opacity(0.98)
.transition(.opacity)
// .frame(width: geometry.size.width - 50)
.offset(x: pulledOut.width)
.offset(x: viewState.width, y: viewState.height)
.zIndex(2)
}
}
}
}
func handleVisibilityChanged2(_: String, change _: VisibilityChange, tracker _: VisibilityTracker<String>) {}
func handleVisibilityChanged(_: String, change _: VisibilityChange, tracker: VisibilityTracker<String>) {
// var printRate: Int64 = 10
gTracker = tracker
// @Environment(\.appDatabase) var appDatabase
// switch change {
// case .shown: print("\(id) shown")
// case .hidden: print("\(id) hidden")
// }
// if (printCount % printRate == 0) {
// print("VISIBILITY CHANGED STARTED")
// print(tracker.visibleViews)
// print(tracker.sortedViewIDs)
// print("VISIBILITY CHANGED ENDED")
// }
// printCount += 1
// if (currentId != nil) {
// currentOffset = tracker.visibleViews[currentId!]!
// }
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!]!
// if (Int(currentOffset!) != -1 && Int(currentOffset!) < 0) {
// if (tracker.sortedViewIDs.count > 1) {
// currentId = tracker.sortedViewIDs[1]
// currentOffset = tracker.visibleViews[currentId!]!
// }
// }
// 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
}()
struct DropViewDelegate2: DropDelegate {
@Binding var isDragging: Bool
func dropUpdated(info _: DropInfo) -> DropProposal? {
return DropProposal(operation: .move)
}
func performDrop(info _: DropInfo) -> Bool {
isDragging = false
return true
}
func dropEntered(info _: DropInfo) {
isDragging = true
print("SECOND DROPPPOOO")
}
}
struct DropViewDelegate: DropDelegate {
let destinationItem: Ribbon
// @Binding var colors: [Color]
@Binding var draggedItem: Ribbon?
@Binding var isDragging: Bool
let appDatabase: AppDatabase
func dropUpdated(info _: DropInfo) -> DropProposal? {
return DropProposal(operation: .move)
}
func dropExited(info _: DropInfo) {
print("EXITED")
isDragging = false
}
func dropEntered(info _: DropInfo) {
Task {
isDragging = true
if draggedItem == nil {
return
}
if disableDrop {
return
}
var newRibbon = draggedItem!
var newDest = destinationItem
var oldPos = draggedItem!.pos
var newPos = destinationItem.pos
print("dragged item")
print(draggedItem)
print("dest item")
print(destinationItem)
if draggedItem!.id! == destinationItem.id! {
return
}
newRibbon.pos = destinationItem.pos
_ = try await appDatabase.updateRibbonPosition(&newRibbon, oldPos, newPos)
disableDrop = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
disableDrop = false
}
draggedItem!.pos = newPos
// draggedItem = nil
}
}
func performDrop(info _: DropInfo) -> Bool {
print("PERFORMED DROPPPP")
draggedItem = nil
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 {
for v in vars {
print(v)
}
return EmptyView()
}
}