diff --git a/NaviBar.swift b/NaviBar.swift new file mode 100644 index 0000000..96ba3e0 --- /dev/null +++ b/NaviBar.swift @@ -0,0 +1,40 @@ + +import GRDB +import GRDBQuery +import Foundation +import SwiftUI + +struct NaviBar: View { + + @Query(RibbonRequest(dir: .prev, groupId: 1)) private var backRibbon: [Ribbon] + @Query(RibbonRequest(dir: .next, groupId: 1)) private var nextRibbon: [Ribbon] + @Query(SelectedRibbonRequest()) private var selectedRibbon: [Ribbon] + @Environment(\.appDatabase) private var appDatabase + + var body: some View { + VStack { + HStack { + + BackArrow() + .frame(width: CGFloat(30), height: CGFloat(30)) + .background(Color(red: 0.1, green: 0.1, blue: 0.1)) + .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4))) + .onTapGesture { + // goToRibbon(selectedRibbon: sr[0], + // destRibbon: ribbon, + // appDatabase: appDatabase, + // paneConnector: paneConnector, + // refresh: $refresh, + // loading: false) + + } + + ForwardArrow() + .frame(width: CGFloat(30), height: CGFloat(30)) + .background(Color(red: 0.1, green: 0.1, blue: 0.1)) + .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4))) + } + .cornerRadius(5) + } + } +} diff --git a/RibbonRequest.swift b/RibbonRequest.swift index ad6ccc3..70c5854 100644 --- a/RibbonRequest.swift +++ b/RibbonRequest.swift @@ -2,30 +2,18 @@ import Combine import GRDB import GRDBQuery -/// A player request can be used with the `@Query` property wrapper in order to -/// feed a view with a list of players. -/// -/// For example: -/// -/// struct MyView: View { -/// @Query(RibbonRequest(ordering: .byName)) private var players: [Ribbon] -/// -/// var body: some View { -/// List(players) { player in ... ) -/// } -/// } - - var idColumn = Column("id") struct RibbonRequest: Queryable { - // enum Ordering { - // case byScore - // case byName - // } + enum UndoDir { + case prev + case next + } /// The ordering used by the player request. // var ordering: Ordering var id: Int64! + var dir: UndoDir? + var groupId: Int? // MARK: - Queryable Implementation @@ -50,17 +38,73 @@ struct RibbonRequest: Queryable { // This method is not required by Queryable, but it makes it easier func fetchValue(_ db: Database) throws -> [Ribbon] { - var sql = """ - select distinct r1.* from Ribbon r1 join Ribbon r2 ON \ - r1.undoLevel = r2.currentLevel AND r1.id = r2.id ORDER BY pos ASC - """ + var ret: [Ribbon] + var sql: String + // this has to be a global variable + let totalLevels = 3 do { - var ret = try Ribbon.fetchAll(db, sql: sql) - print("xxxxx fetching ribbons") - print(ret) - return ret + if dir != nil && groupId != nil { + sql = """ + SELECT * FROM Ribbon \ + WHERE groupId = ? + """ + ret = try Ribbon.fetchAll(db, sql: sql, arguments: [groupId]) + if ret.count == 0 { + print("error no ribbons found") + return [] + } + print("back all ribbon test: \(ret)") + + let currentLevel = ret[0].currentLevel + let minLevel = ret[0].minLevel + let maxLevel = ret[0].maxLevel + + var newCurrentLevel = (currentLevel - 1) %% totalLevels + + // probably need more error checking to check + // if current level gets into an error state + // between minLevel and maxLevel somehow but there + // are probably a bunch of edge cases casue of the + // mod stuff + if dir == .prev { + // no back undo steps left + if currentLevel == minLevel { + return [] + } + } else if dir == .prev { + // no forward redo steps left + if currentLevel == maxLevel { + return [] + } + newCurrentLevel = (currentLevel + 1) %% totalLevels + } + + + print("back newcurrentlevel \(newCurrentLevel)") + sql = """ + SELECT * FROM Ribbon \ + WHERE groupId = ? AND + undoLevel = ? + LIMIT 1 + """ + ret = try Ribbon.fetchAll(db, sql: sql, arguments: [groupId, newCurrentLevel]) + + print("back ribbon test: \(ret)") + return ret + + } else { + let sql = """ + select distinct r1.* from Ribbon r1 join Ribbon r2 ON \ + r1.undoLevel = r2.currentLevel AND r1.id = r2.id ORDER BY pos ASC + """ + + var ret = try Ribbon.fetchAll(db, sql: sql) + print("xxxxx fetching ribbons") + print(ret) + return ret + } } catch { print(error.localizedDescription) print(error) @@ -68,11 +112,12 @@ struct RibbonRequest: Queryable { return [] } - if id == nil { - return try Ribbon.order(Column("pos")).fetchAll(db) - } else { - return try Ribbon.filter(idColumn == id).fetchAll(db) - } + // if id == nil { + // return try Ribbon.order(Column("pos")).fetchAll(db) + // } else { + // return try Ribbon.filter(idColumn == id).fetchAll(db) + // } + // { // if book == "" { // return try Ribbon.filter(bookColumn == Ribbon.randomBook()).fetchAll(db) @@ -88,3 +133,14 @@ struct RibbonRequest: Queryable { // } } } + +infix operator %% + +extension Int { + + static func %% (_ left: Int, _ right: Int) -> Int { + let mod = left % right + return mod >= 0 ? mod : mod + right + } + +} diff --git a/gloss.xcodeproj/project.pbxproj b/gloss.xcodeproj/project.pbxproj index fd3256a..1ec2536 100644 --- a/gloss.xcodeproj/project.pbxproj +++ b/gloss.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 851259B02C05281300BE70F8 /* BackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259AF2C05281300BE70F8 /* BackButton.swift */; }; 851259B22C05299200BE70F8 /* ForwardArrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259B12C05299200BE70F8 /* ForwardArrow.swift */; }; + 851259B62C07560800BE70F8 /* NaviBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259B52C07560800BE70F8 /* NaviBar.swift */; }; 8514D5BC299EFB780054F185 /* store.db in Resources */ = {isa = PBXBuildFile; fileRef = 8514D5BB299EFB780054F185 /* store.db */; }; 8514D5BF299F04710054F185 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 8514D5BE299F04710054F185 /* GRDB */; }; 852774C129A150B100458CA7 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852774C029A150B100458CA7 /* Line.swift */; }; @@ -49,6 +50,7 @@ /* Begin PBXFileReference section */ 851259AF2C05281300BE70F8 /* BackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackButton.swift; sourceTree = ""; }; 851259B12C05299200BE70F8 /* ForwardArrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardArrow.swift; sourceTree = ""; }; + 851259B52C07560800BE70F8 /* NaviBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NaviBar.swift; sourceTree = ""; }; 8514D5BB299EFB780054F185 /* store.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = store.db; sourceTree = ""; }; 852774C029A150B100458CA7 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; 8528897429B2B86B003F2E16 /* CrownOfThorns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrownOfThorns.swift; sourceTree = ""; }; @@ -123,6 +125,7 @@ 85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */, 85942EF429B108C600307621 /* Seg.swift */, 85942EF629B108EA00307621 /* SegDenormRequest.swift */, + 851259B52C07560800BE70F8 /* NaviBar.swift */, 85942EF829B1150B00307621 /* SegDenorm.swift */, 85942EEA29AD55A400307621 /* RibbonRequest.swift */, 85942EE329ACF54A00307621 /* ScrollableView.swift */, @@ -311,6 +314,7 @@ 851259B22C05299200BE70F8 /* ForwardArrow.swift in Sources */, 8528897E29BD69B2003F2E16 /* VisibilityTracker.swift in Sources */, 85942EF729B108EA00307621 /* SegDenormRequest.swift in Sources */, + 851259B62C07560800BE70F8 /* NaviBar.swift in Sources */, 8528897D29BD69B2003F2E16 /* VisibilityTrackingModifier.swift in Sources */, 85942EE429ACF54A00307621 /* ScrollableView.swift in Sources */, ); diff --git a/gloss/AppDatabase.swift b/gloss/AppDatabase.swift index 08091da..a4ecdd9 100644 --- a/gloss/AppDatabase.swift +++ b/gloss/AppDatabase.swift @@ -79,7 +79,7 @@ struct AppDatabase { } // change this to nuke/remake the database - try db.create(table: "foo3") { t in + try db.create(table: "foo1") { t in t.autoIncrementedPrimaryKey("id") t.column("ribbonId", .integer).notNull() } @@ -215,9 +215,9 @@ extension AppDatabase { let delLevels = delLevels2 print(delLevels) - let newMax = (ribbon.currentLevel + 1) % totalLevels + 1 + let newMax = (ribbon.currentLevel + 1) % totalLevels let newCurrent = newMax - let newMin = newMax == ribbon.minLevel ? (ribbon.minLevel + 1) % totalLevels + 1 + let newMin = newMax == ribbon.minLevel ? (ribbon.minLevel + 1) % totalLevels : ribbon.minLevel print(newMin) @@ -336,10 +336,10 @@ extension AppDatabase { _ = try Ribbon(id: 1, groupId: 1, pos: 1, - undoLevel: 1, - currentLevel: 1, - minLevel: 1, - maxLevel: 1, + undoLevel: 0, + currentLevel: 0, + minLevel: 0, + maxLevel: 0, title: "John", book: "bible.john", scrollId: "1", @@ -347,10 +347,10 @@ extension AppDatabase { _ = try Ribbon(id: 2, groupId: 2, pos: 2, - undoLevel: 1, - currentLevel: 1, - minLevel: 1, - maxLevel: 1, + undoLevel: 0, + currentLevel: 0, + minLevel: 0, + maxLevel: 0, title: "Gospel of Mark", book: "bible.mark", scrollId: "1", @@ -361,10 +361,10 @@ extension AppDatabase { _ = try Ribbon(id: 3, groupId: 3, pos: 3, - undoLevel: 1, - currentLevel: 3, - minLevel: 1, - maxLevel: 3, + undoLevel: 0, + currentLevel: 2, + minLevel: 0, + maxLevel: 2, title: "bottom", book: "bible.john", scrollId: "1", @@ -373,10 +373,10 @@ extension AppDatabase { _ = try Ribbon(id: 4, groupId: 3, pos: 3, - undoLevel: 2, - currentLevel: 3, - minLevel: 1, - maxLevel: 3, + undoLevel: 1, + currentLevel: 2, + minLevel: 0, + maxLevel: 2, title: "topp", book: "bible.john", scrollId: "1", @@ -385,10 +385,10 @@ extension AppDatabase { _ = try Ribbon(id: 5, groupId: 3, pos: 3, - undoLevel: 3, - currentLevel: 3, - minLevel: 1, - maxLevel: 3, + undoLevel: 2, + currentLevel: 2, + minLevel: 0, + maxLevel: 2, title: "topp", book: "bible.john", scrollId: "1", diff --git a/gloss/ContentView.swift b/gloss/ContentView.swift index 8b07deb..f5baff9 100644 --- a/gloss/ContentView.swift +++ b/gloss/ContentView.swift @@ -89,6 +89,8 @@ func goToRibbon(selectedRibbon: Ribbon, if !loading { print("not loading") + + print("saving ribbon") // updating the ribbon location updatedRibbon.scrollOffset = Int(floor(scrollOffsetToSave)) updatedRibbon.scrollId = scrollIdToSave @@ -274,21 +276,7 @@ struct ContentView: View { .background(Color(red: 0.1, green: 0.1, blue: 0.1)) .frame(alignment: .topLeading) - VStack { - HStack { - BackArrow() - .frame(width: CGFloat(30), height: CGFloat(30)) - .background(Color(red: 0.1, green: 0.1, blue: 0.1)) - .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4))) - - ForwardArrow() - .frame(width: CGFloat(30), height: CGFloat(30)) - .background(Color(red: 0.1, green: 0.1, blue: 0.1)) - .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4))) - } - .cornerRadius(5) - } - .offset(x: geometry.size.width - 300) + NaviBar().offset(x: geometry.size.width - 300) VStack { // Top pane