diff --git a/.DS_Store b/.DS_Store index f74a462..2c27fca 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/gloss.xcodeproj/xcuserdata/saint.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/gloss.xcodeproj/xcuserdata/saint.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 0058495..a0cb3cf 100644 --- a/gloss.xcodeproj/xcuserdata/saint.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/gloss.xcodeproj/xcuserdata/saint.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -14,8 +14,8 @@ filePath = "gloss/ContentView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "566" - endingLineNumber = "566" + startingLineNumber = "565" + endingLineNumber = "565" landmarkName = "body" landmarkType = "24"> @@ -30,8 +30,8 @@ filePath = "gloss/ContentView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "568" - endingLineNumber = "568" + startingLineNumber = "567" + endingLineNumber = "567" landmarkName = "body" landmarkType = "24"> @@ -46,8 +46,8 @@ filePath = "gloss/ContentView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "459" - endingLineNumber = "459" + startingLineNumber = "458" + endingLineNumber = "458" landmarkName = "body" landmarkType = "24"> @@ -62,8 +62,8 @@ filePath = "gloss/ContentView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "427" - endingLineNumber = "427" + startingLineNumber = "426" + endingLineNumber = "426" landmarkName = "body" landmarkType = "24"> diff --git a/gloss/AppDatabase.swift b/gloss/AppDatabase.swift index 1928add..a7f4c56 100644 --- a/gloss/AppDatabase.swift +++ b/gloss/AppDatabase.swift @@ -52,6 +52,7 @@ struct AppDatabase { try db.create(table: "Ribbon") { t in t.autoIncrementedPrimaryKey("id") + t.column("title", .text).notNull() t.column("book", .text).notNull() t.column("scrollOffset", .integer).notNull() t.column("scrollId", .text) @@ -68,7 +69,7 @@ struct AppDatabase { t.column("scrollOffset", .integer).notNull() } - try db.create(table: "foo3") { t in + try db.create(table: "foo4") { t in t.autoIncrementedPrimaryKey("id") t.column("ribbonId", .integer).notNull() } @@ -140,38 +141,34 @@ extension AppDatabase { } + func importJson(_ filename: String, _ db: Database) throws { + let importJson : JsonImport = load(filename) + + if try Line.all().isEmpty(db) { + for l in importJson.lines { + print("importing Lines") + _ = try l.inserted(db) + } + + for l in importJson.segs { + print("importing SEGS") + _ = try l.inserted(db) + } + } + } /// Create random Lines if the database is empty. - func createRandomLinesIfEmpty() throws { - - let imports : JsonImport = load("john_export.json") + func initDatabase() throws { try dbWriter.write { db in -// try db.execute(sql: "DELETE FROM Line") -// try db.execute(sql: "DELETE FROM Seg") -// try db.execute(sql: "DELETE FROM Ribbon") -// try db.execute(sql: "DELETE FROM SelectedRibbon") - if try Line.all().isEmpty(db) { - for l in imports.lines { - print("here") - print(l.body) - _ = try l.inserted(db) - } - for l in imports.segs { - print("here SEGS") - print(l.seg_id) - _ = try l.inserted(db) - } - - // print("cat") - // try createRandomLines(db) - - _ = try Ribbon(id: 1, book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db) - _ = try Ribbon(id: 2, book: "bible.john", scrollId: "1", scrollOffset: 300).inserted(db) + try importJson("john_export.json", db) + try importJson("mark_export.json", db) + _ = try Ribbon(id: 1, title: "John", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db) + _ = try Ribbon(id: 2, title: "Gospel of Mark", book: "bible.mark", scrollId: "1", scrollOffset: 300).inserted(db) _ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db) } } diff --git a/gloss/ContentView.swift b/gloss/ContentView.swift index 12c6ab2..d26388d 100644 --- a/gloss/ContentView.swift +++ b/gloss/ContentView.swift @@ -43,7 +43,7 @@ struct BlueButtonStyle: ButtonStyle { func makeBody(configuration: Self.Configuration) -> some View { configuration.label .font(.headline) - .frame(width: 160) + .frame(width: 100) .contentShape(Rectangle()) .foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.black) .background(configuration.isPressed ? Color.purple.opacity(0.5) : Color.purple) @@ -119,13 +119,17 @@ func goToRibbon(selectedRibbon: Ribbon, } } -struct SwitchButton : View { +struct RibbonCrown : View { var ribbon: Ribbon @Binding var scrollId : String? @Binding var scrollOffset : CGFloat? @Binding var showOverlay : Bool @Binding var refresh : Bool + var height = CGFloat(50) + var xOffset = CGFloat(25) + var scale = 0.65 + @Environment(\.appDatabase) private var appDatabase @Query(SelectedRibbonRequest()) private var sr: [Ribbon] @@ -133,24 +137,47 @@ struct SwitchButton : View { @State var saveOffset = CGFloat() var body: some View { - // ForEach(sr) { selectedRibbon in - let ribbonString = String(sr[0].id!) + " " + String(ribbon.id!) + " " + String(ribbon.scrollOffset) + " " + ribbon.scrollId - Button(ribbonString, - action: { - Task { - goToRibbon(selectedRibbon: sr[0], - destRibbon: ribbon, - scrollId: $scrollId, - scrollOffset: $scrollOffset, - refresh: $refresh, - showOverlay: $showOverlay, - appDatabase: appDatabase, - loading: false) - } - } + Text(ribbon.title) + .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) + // // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) + // .foregroundColor(.white)) + // .foregroundColor(.black) + .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) + // .background(.red) + // .background(.yellow) + .multilineTextAlignment(.center) + // .minimumScaleFactor(0.5) + .padding([.top, .bottom], 10) + .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10))) - ) - .buttonStyle(BlueButtonStyle()) + .overlay( 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)))) + + .offset(x: xOffset) + .onTapGesture { + Print("TAP") + // selectedLine = seg.id + // Print(selectedLine) + } + + + // ForEach(sr) { selectedRibbon in + // let ribbonString = String(sr[0].id!) + " " + String(ribbon.id!) + " " + String(ribbon.scrollOffset) + " " + ribbon.scrollId + // Button(ribbonString, + // action: { + // Task { + // goToRibbon(selectedRibbon: sr[0], + // destRibbon: ribbon, + // scrollId: $scrollId, + // scrollOffset: $scrollOffset, + // refresh: $refresh, + // showOverlay: $showOverlay, + // appDatabase: appDatabase, + // loading: false) + // } + // } + + // ) + // .buttonStyle(BlueButtonStyle()) } } @@ -261,6 +288,8 @@ struct ContentView: View { @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] @@ -276,6 +305,7 @@ struct ContentView: View { @State var endedDrag = true @State var readOffset = CGPoint() + @State var dragOffset = CGFloat() @State var refresh: Bool = false @@ -304,287 +334,485 @@ struct ContentView: View { var scale = 0.65 var height = CGFloat(50) var xOffset = CGFloat(25) + GeometryReader { geometry in ZStack (alignment: .top) { + VStack (alignment: .leading) { + VStack { + Text("Imitation of Christ") + .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) + // // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) + // .foregroundColor(.white)) + // .foregroundColor(.black) + .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) + // .background(.red) + // .background(.yellow) + .multilineTextAlignment(.center) + // .minimumScaleFactor(0.5) + .padding([.top, .bottom], 10) + .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10))) + .overlay( 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)))) - VStack{ + .offset(x: xOffset) + .onTapGesture { + Print("TAP") + // selectedLine = seg.id + // Print(selectedLine) + } + // .offset(y: 25) - Text("Imitation of Christ") - .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) - // // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) - // .foregroundColor(.white)) - // .foregroundColor(.black) - .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) - // .background(.red) - // .background(.yellow) - .multilineTextAlignment(.center) - // .minimumScaleFactor(0.5) - .padding([.top, .bottom], 10) - .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10))) + Text("Psalms") + .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) + // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) + // .foregroundColor(.white)) + // .foregroundColor(.black) + .overlay( MyIcon().frame(width: CGFloat(100 * 1.66 * scale), height: CGFloat(100 * scale)) .foregroundColor(Color(UIColor(red: 0.56, green: 0.30, blue: 0.30, alpha: 0.4)))) + .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) + // .background(.red) + .multilineTextAlignment(.center) - .overlay( 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)))) + .offset(x: xOffset) + .padding([.top, .bottom], 10) + // .minimumScaleFactor(0.5) + .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(14))) - .offset(x: xOffset) - // .offset(y: 25) + // Text("padding") - Text("Psalms") - .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) - // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) - // .foregroundColor(.white)) - // .foregroundColor(.black) - .overlay( MyIcon().frame(width: CGFloat(100 * 1.66 * scale), height: CGFloat(100 * scale)) .foregroundColor(Color(UIColor(red: 0.56, green: 0.30, blue: 0.30, alpha: 0.4)))) - .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) - // .background(.red) - .multilineTextAlignment(.center) + Text("Fundamentals of Dogmatic Theology") + .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) + // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) + // .foregroundColor(.black) + .overlay( MyIcon().frame(width: CGFloat(100 * 1.66 * scale), height: CGFloat(100 * scale)) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))) + .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) + // .background(.red) + .multilineTextAlignment(.center) + .padding([.top, .bottom], 10) + .offset(x: xOffset) + // .minimumScaleFactor(0.5) + .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10))) + // .minimumScaleFactor(0.9) - .offset(x: xOffset) - .padding([.top, .bottom], 10) - // .minimumScaleFactor(0.5) - .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(14))) + // Text("padding") - // Text("padding") - - Text("Fundamentals of Dogmatic Theology") - .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) - // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) - // .foregroundColor(.black) - .overlay( MyIcon().frame(width: CGFloat(100 * 1.66 * scale), height: CGFloat(100 * scale)) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))) - .frame(minWidth: CGFloat(75), maxWidth: CGFloat(75), minHeight: height, maxHeight: height, alignment: .center) - // .background(.red) - .multilineTextAlignment(.center) - .padding([.top, .bottom], 10) - .offset(x: xOffset) - // .minimumScaleFactor(0.5) - .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(10))) - // .minimumScaleFactor(0.9) - - // Text("padding") - - - // // Text("Fundamentals of Dogmatic Theology") - // Text("FoDT") - // .font(Font.custom("AveriaSerifLibre-Regular", size: CGFloat(15))) - // .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) - // // .backgroundColor(Color(UIColor(red: 1.00, green: 0.76, blue: 0.76, alpha: 1.00))) - // // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) - // .overlay( MyIcon().frame(width: size2, height: size2) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))) - // // .background(.yellow) - // // .foregroundColor(.white)) - // .frame(width: CGFloat(50), height: CGFloat(80)) - // .lineLimit(nil) - // .multilineTextAlignment(.leading) - // .minimumScaleFactor(0.9) - - // Text("Jn") - // .font(Font.custom("AveriaSerifLibre-Regular", size: fontSize)) - // .foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))) - // // .background(Color(red: 0.3, green: 0.3, blue: 0.3)) - // .overlay( MyIcon().frame(width: size1, height: size1) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))) - // // .foregroundColor(.white)) - // .frame(width: size2, height: size2) - - - // Text("MTW") - // .font(Font.custom("AveriaSerifLibre-Regular", size: 20)) - // .foregroundColor(Color.white) - // .overlay( MyCustomShape().frame(width: 120, height: 100)) - // .frame(width: 120, height: 120) + } + .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) + // Spacer() ForEach(ribbons) { ribbon in - SwitchButton(ribbon: ribbon, + RibbonCrown(ribbon: ribbon, scrollId:$scrollId, scrollOffset:$scrollOffset, showOverlay: $showOverlay, refresh:$refresh ) - .buttonStyle(BlueButtonStyle()) - // Print("RIBBON") - // Print(ribbon) + // .buttonStyle(BlueButtonStyle()) + // .frame(alignment: .topLeading) + + // .background(Color(red: 0.4, green: 0.4, blue: 0.1)) + .animation(nil) } } - .frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading) .background(Color(red: 0.1, green: 0.1, blue: 0.1)) - .zIndex(0) + .frame(alignment: .topLeading) + .animation(nil) - ScrollViewReader { proxy in - VisibilityTrackingScrollView(action: handleVisibilityChanged) { - // ScrollView { + VStack { - LazyVStack { - Text(refresh ? "Selected" : "not Selected") - Button("Jump to #8") { - scrollId = "20" + ScrollViewReader { proxy in + VisibilityTrackingScrollView(action: handleVisibilityChanged) { + // ScrollView { - } - ForEach(segs) { seg in - SegRow(seg: seg, - ribbonId: selectedRibbon[0].id! - ) - .id("\(seg.id)") + 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)") + .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.2, green: 0.2, blue: 0.2)) - } - - .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! + // .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)) } - } - .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 + .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 (thisScrollView == nil) { - // Print("init scroll") - // thisScrollView = scrollView - // scrollView.contentOffset.y = CGFloat(selectedRibbon[0].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 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("DRAG") + .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 + // } // } + ) - Print("end instrospect") + ScrollViewReader { proxy 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()) } - .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 + } + } + ) + } - .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() @@ -609,6 +837,9 @@ struct ContentView: View { } } + func handleVisibilityChanged2(_ id: String, change: VisibilityChange, tracker: VisibilityTracker) { + } + func handleVisibilityChanged(_ id: String, change: VisibilityChange, tracker: VisibilityTracker) { diff --git a/gloss/Persistence.swift b/gloss/Persistence.swift index e958f23..ed37169 100644 --- a/gloss/Persistence.swift +++ b/gloss/Persistence.swift @@ -40,7 +40,7 @@ extension AppDatabase { // // demo purpose. // try appDatabase.createRandomPlayersIfEmpty() // } - try appDatabase.createRandomLinesIfEmpty() + try appDatabase.initDatabase() return appDatabase @@ -69,7 +69,7 @@ extension AppDatabase { /// Creates a database full of random players for SwiftUI previews static func random() -> AppDatabase { let appDatabase = empty() - try! appDatabase.createRandomLinesIfEmpty() + try! appDatabase.initDatabase() return appDatabase } } diff --git a/gloss/Ribbon.swift b/gloss/Ribbon.swift index 4f771c4..44ccff6 100644 --- a/gloss/Ribbon.swift +++ b/gloss/Ribbon.swift @@ -17,6 +17,7 @@ struct Ribbon: Identifiable, Equatable { /// Int64 is the recommended type for auto-incremented database ids. /// Use nil for players that are not inserted yet in the database. var id: Int64? + var title: String var book: String var scrollId: String var scrollOffset: Int @@ -35,6 +36,7 @@ extension Ribbon: Codable, FetchableRecord, MutablePersistableRecord { fileprivate enum Columns { static let id = Column(CodingKeys.id) static let book = Column(CodingKeys.book) + static let title = Column(CodingKeys.title) static let scrollOffset = Column(CodingKeys.scrollOffset) } diff --git a/test b/test deleted file mode 100644 index 39ecb45..0000000 --- a/test +++ /dev/null @@ -1,22 +0,0 @@ -struct ContentView: View { - @State var scrollId : String? - var body: some View { - SwitchButton(scrollId:$scrollId) - } -} - -struct SwitchButton : View { - @Binding var scrollId : String? - - var body: some View { - Button("This button", - action: { - goToRibbon($scrollId) - } - ) - } -} - -func goToRibbon(scrollId: Binding) { - scrollId = "SomeValue" -} diff --git a/test.c b/test.c deleted file mode 100644 index 4cce7f6..0000000 --- a/test.c +++ /dev/null @@ -1,3 +0,0 @@ -int main() { - return 0; -}