builds, still working on undo
parent
168a057a2a
commit
19ca7be678
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,30 +2,18 @@ import Combine
|
||||||
import GRDB
|
import GRDB
|
||||||
import GRDBQuery
|
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")
|
var idColumn = Column("id")
|
||||||
struct RibbonRequest: Queryable {
|
struct RibbonRequest: Queryable {
|
||||||
// enum Ordering {
|
enum UndoDir {
|
||||||
// case byScore
|
case prev
|
||||||
// case byName
|
case next
|
||||||
// }
|
}
|
||||||
|
|
||||||
/// The ordering used by the player request.
|
/// The ordering used by the player request.
|
||||||
// var ordering: Ordering
|
// var ordering: Ordering
|
||||||
var id: Int64!
|
var id: Int64!
|
||||||
|
var dir: UndoDir?
|
||||||
|
var groupId: Int?
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Queryable Implementation
|
// MARK: - Queryable Implementation
|
||||||
|
@ -50,17 +38,73 @@ struct RibbonRequest: Queryable {
|
||||||
// This method is not required by Queryable, but it makes it easier
|
// This method is not required by Queryable, but it makes it easier
|
||||||
func fetchValue(_ db: Database) throws -> [Ribbon] {
|
func fetchValue(_ db: Database) throws -> [Ribbon] {
|
||||||
|
|
||||||
var sql = """
|
var ret: [Ribbon]
|
||||||
|
var sql: String
|
||||||
|
|
||||||
|
// this has to be a global variable
|
||||||
|
let totalLevels = 3
|
||||||
|
do {
|
||||||
|
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 \
|
select distinct r1.* from Ribbon r1 join Ribbon r2 ON \
|
||||||
r1.undoLevel = r2.currentLevel AND r1.id = r2.id ORDER BY pos ASC
|
r1.undoLevel = r2.currentLevel AND r1.id = r2.id ORDER BY pos ASC
|
||||||
"""
|
"""
|
||||||
|
|
||||||
do {
|
|
||||||
var ret = try Ribbon.fetchAll(db, sql: sql)
|
var ret = try Ribbon.fetchAll(db, sql: sql)
|
||||||
print("xxxxx fetching ribbons")
|
print("xxxxx fetching ribbons")
|
||||||
print(ret)
|
print(ret)
|
||||||
return ret
|
return ret
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
print(error)
|
print(error)
|
||||||
|
@ -68,11 +112,12 @@ struct RibbonRequest: Queryable {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
if id == nil {
|
// if id == nil {
|
||||||
return try Ribbon.order(Column("pos")).fetchAll(db)
|
// return try Ribbon.order(Column("pos")).fetchAll(db)
|
||||||
} else {
|
// } else {
|
||||||
return try Ribbon.filter(idColumn == id).fetchAll(db)
|
// return try Ribbon.filter(idColumn == id).fetchAll(db)
|
||||||
}
|
// }
|
||||||
|
// {
|
||||||
|
|
||||||
// if book == "" {
|
// if book == "" {
|
||||||
// return try Ribbon.filter(bookColumn == Ribbon.randomBook()).fetchAll(db)
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
851259B02C05281300BE70F8 /* BackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259AF2C05281300BE70F8 /* BackButton.swift */; };
|
851259B02C05281300BE70F8 /* BackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259AF2C05281300BE70F8 /* BackButton.swift */; };
|
||||||
851259B22C05299200BE70F8 /* ForwardArrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259B12C05299200BE70F8 /* ForwardArrow.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 */; };
|
8514D5BC299EFB780054F185 /* store.db in Resources */ = {isa = PBXBuildFile; fileRef = 8514D5BB299EFB780054F185 /* store.db */; };
|
||||||
8514D5BF299F04710054F185 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 8514D5BE299F04710054F185 /* GRDB */; };
|
8514D5BF299F04710054F185 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 8514D5BE299F04710054F185 /* GRDB */; };
|
||||||
852774C129A150B100458CA7 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852774C029A150B100458CA7 /* Line.swift */; };
|
852774C129A150B100458CA7 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852774C029A150B100458CA7 /* Line.swift */; };
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
851259AF2C05281300BE70F8 /* BackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackButton.swift; sourceTree = "<group>"; };
|
851259AF2C05281300BE70F8 /* BackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackButton.swift; sourceTree = "<group>"; };
|
||||||
851259B12C05299200BE70F8 /* ForwardArrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardArrow.swift; sourceTree = "<group>"; };
|
851259B12C05299200BE70F8 /* ForwardArrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardArrow.swift; sourceTree = "<group>"; };
|
||||||
|
851259B52C07560800BE70F8 /* NaviBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NaviBar.swift; sourceTree = "<group>"; };
|
||||||
8514D5BB299EFB780054F185 /* store.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = store.db; sourceTree = "<group>"; };
|
8514D5BB299EFB780054F185 /* store.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = store.db; sourceTree = "<group>"; };
|
||||||
852774C029A150B100458CA7 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
852774C029A150B100458CA7 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
||||||
8528897429B2B86B003F2E16 /* CrownOfThorns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrownOfThorns.swift; sourceTree = "<group>"; };
|
8528897429B2B86B003F2E16 /* CrownOfThorns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrownOfThorns.swift; sourceTree = "<group>"; };
|
||||||
|
@ -123,6 +125,7 @@
|
||||||
85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */,
|
85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */,
|
||||||
85942EF429B108C600307621 /* Seg.swift */,
|
85942EF429B108C600307621 /* Seg.swift */,
|
||||||
85942EF629B108EA00307621 /* SegDenormRequest.swift */,
|
85942EF629B108EA00307621 /* SegDenormRequest.swift */,
|
||||||
|
851259B52C07560800BE70F8 /* NaviBar.swift */,
|
||||||
85942EF829B1150B00307621 /* SegDenorm.swift */,
|
85942EF829B1150B00307621 /* SegDenorm.swift */,
|
||||||
85942EEA29AD55A400307621 /* RibbonRequest.swift */,
|
85942EEA29AD55A400307621 /* RibbonRequest.swift */,
|
||||||
85942EE329ACF54A00307621 /* ScrollableView.swift */,
|
85942EE329ACF54A00307621 /* ScrollableView.swift */,
|
||||||
|
@ -311,6 +314,7 @@
|
||||||
851259B22C05299200BE70F8 /* ForwardArrow.swift in Sources */,
|
851259B22C05299200BE70F8 /* ForwardArrow.swift in Sources */,
|
||||||
8528897E29BD69B2003F2E16 /* VisibilityTracker.swift in Sources */,
|
8528897E29BD69B2003F2E16 /* VisibilityTracker.swift in Sources */,
|
||||||
85942EF729B108EA00307621 /* SegDenormRequest.swift in Sources */,
|
85942EF729B108EA00307621 /* SegDenormRequest.swift in Sources */,
|
||||||
|
851259B62C07560800BE70F8 /* NaviBar.swift in Sources */,
|
||||||
8528897D29BD69B2003F2E16 /* VisibilityTrackingModifier.swift in Sources */,
|
8528897D29BD69B2003F2E16 /* VisibilityTrackingModifier.swift in Sources */,
|
||||||
85942EE429ACF54A00307621 /* ScrollableView.swift in Sources */,
|
85942EE429ACF54A00307621 /* ScrollableView.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct AppDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change this to nuke/remake the database
|
// 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.autoIncrementedPrimaryKey("id")
|
||||||
t.column("ribbonId", .integer).notNull()
|
t.column("ribbonId", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
@ -215,9 +215,9 @@ extension AppDatabase {
|
||||||
let delLevels = delLevels2
|
let delLevels = delLevels2
|
||||||
print(delLevels)
|
print(delLevels)
|
||||||
|
|
||||||
let newMax = (ribbon.currentLevel + 1) % totalLevels + 1
|
let newMax = (ribbon.currentLevel + 1) % totalLevels
|
||||||
let newCurrent = newMax
|
let newCurrent = newMax
|
||||||
let newMin = newMax == ribbon.minLevel ? (ribbon.minLevel + 1) % totalLevels + 1
|
let newMin = newMax == ribbon.minLevel ? (ribbon.minLevel + 1) % totalLevels
|
||||||
: ribbon.minLevel
|
: ribbon.minLevel
|
||||||
|
|
||||||
print(newMin)
|
print(newMin)
|
||||||
|
@ -336,10 +336,10 @@ extension AppDatabase {
|
||||||
_ = try Ribbon(id: 1,
|
_ = try Ribbon(id: 1,
|
||||||
groupId: 1,
|
groupId: 1,
|
||||||
pos: 1,
|
pos: 1,
|
||||||
undoLevel: 1,
|
undoLevel: 0,
|
||||||
currentLevel: 1,
|
currentLevel: 0,
|
||||||
minLevel: 1,
|
minLevel: 0,
|
||||||
maxLevel: 1,
|
maxLevel: 0,
|
||||||
title: "John",
|
title: "John",
|
||||||
book: "bible.john",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
|
@ -347,10 +347,10 @@ extension AppDatabase {
|
||||||
_ = try Ribbon(id: 2,
|
_ = try Ribbon(id: 2,
|
||||||
groupId: 2,
|
groupId: 2,
|
||||||
pos: 2,
|
pos: 2,
|
||||||
undoLevel: 1,
|
undoLevel: 0,
|
||||||
currentLevel: 1,
|
currentLevel: 0,
|
||||||
minLevel: 1,
|
minLevel: 0,
|
||||||
maxLevel: 1,
|
maxLevel: 0,
|
||||||
title: "Gospel of Mark",
|
title: "Gospel of Mark",
|
||||||
book: "bible.mark",
|
book: "bible.mark",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
|
@ -361,10 +361,10 @@ extension AppDatabase {
|
||||||
_ = try Ribbon(id: 3,
|
_ = try Ribbon(id: 3,
|
||||||
groupId: 3,
|
groupId: 3,
|
||||||
pos: 3,
|
pos: 3,
|
||||||
undoLevel: 1,
|
undoLevel: 0,
|
||||||
currentLevel: 3,
|
currentLevel: 2,
|
||||||
minLevel: 1,
|
minLevel: 0,
|
||||||
maxLevel: 3,
|
maxLevel: 2,
|
||||||
title: "bottom",
|
title: "bottom",
|
||||||
book: "bible.john",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
|
@ -373,10 +373,10 @@ extension AppDatabase {
|
||||||
_ = try Ribbon(id: 4,
|
_ = try Ribbon(id: 4,
|
||||||
groupId: 3,
|
groupId: 3,
|
||||||
pos: 3,
|
pos: 3,
|
||||||
undoLevel: 2,
|
undoLevel: 1,
|
||||||
currentLevel: 3,
|
currentLevel: 2,
|
||||||
minLevel: 1,
|
minLevel: 0,
|
||||||
maxLevel: 3,
|
maxLevel: 2,
|
||||||
title: "topp",
|
title: "topp",
|
||||||
book: "bible.john",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
|
@ -385,10 +385,10 @@ extension AppDatabase {
|
||||||
_ = try Ribbon(id: 5,
|
_ = try Ribbon(id: 5,
|
||||||
groupId: 3,
|
groupId: 3,
|
||||||
pos: 3,
|
pos: 3,
|
||||||
undoLevel: 3,
|
undoLevel: 2,
|
||||||
currentLevel: 3,
|
currentLevel: 2,
|
||||||
minLevel: 1,
|
minLevel: 0,
|
||||||
maxLevel: 3,
|
maxLevel: 2,
|
||||||
title: "topp",
|
title: "topp",
|
||||||
book: "bible.john",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
|
|
|
@ -89,6 +89,8 @@ func goToRibbon(selectedRibbon: Ribbon,
|
||||||
if !loading {
|
if !loading {
|
||||||
print("not loading")
|
print("not loading")
|
||||||
|
|
||||||
|
|
||||||
|
print("saving ribbon")
|
||||||
// updating the ribbon location
|
// updating the ribbon location
|
||||||
updatedRibbon.scrollOffset = Int(floor(scrollOffsetToSave))
|
updatedRibbon.scrollOffset = Int(floor(scrollOffsetToSave))
|
||||||
updatedRibbon.scrollId = scrollIdToSave
|
updatedRibbon.scrollId = scrollIdToSave
|
||||||
|
@ -274,21 +276,7 @@ struct ContentView: View {
|
||||||
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
||||||
.frame(alignment: .topLeading)
|
.frame(alignment: .topLeading)
|
||||||
|
|
||||||
VStack {
|
NaviBar().offset(x: geometry.size.width - 300)
|
||||||
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)
|
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
// Top pane
|
// Top pane
|
||||||
|
|
Loading…
Reference in New Issue