can request separate books
parent
9eb488a87a
commit
32696d7b58
|
@ -5,6 +5,8 @@
|
||||||
// Created by Saint on 5/20/24.
|
// Created by Saint on 5/20/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import GRDB
|
||||||
|
import GRDBQuery
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import WrappingHStack
|
import WrappingHStack
|
||||||
|
@ -14,8 +16,11 @@ struct SegRow: View {
|
||||||
var ribbonId: Int64
|
var ribbonId: Int64
|
||||||
@State var highlights = Set<Int>()
|
@State var highlights = Set<Int>()
|
||||||
|
|
||||||
|
let intraWordSpacing = CGFloat(1.6)
|
||||||
var body: some View {
|
var body: some View {
|
||||||
var segSplit = seg.body.components(separatedBy: ";;")
|
var segSplit = seg.body.components(separatedBy: ";;")
|
||||||
|
Print("got here meow")
|
||||||
|
Print(segSplit)
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
||||||
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
||||||
|
@ -53,7 +58,8 @@ struct SegRow: View {
|
||||||
Text(arrayOfText[index])
|
Text(arrayOfText[index])
|
||||||
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
||||||
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
||||||
.padding(.horizontal, 1.5) // intra word spacing
|
|
||||||
|
.padding(.horizontal, intraWordSpacing) // intra word spacing
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
@ -79,7 +85,6 @@ struct SegRow: View {
|
||||||
struct Pane: View {
|
struct Pane: View {
|
||||||
@ObservedObject var paneConnector: PaneConnector
|
@ObservedObject var paneConnector: PaneConnector
|
||||||
|
|
||||||
@State var segs: [SegDenorm]
|
|
||||||
@State var selectedRibbon: [Ribbon]
|
@State var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
@State var width: CGFloat
|
@State var width: CGFloat
|
||||||
|
@ -89,6 +94,8 @@ struct Pane: View {
|
||||||
|
|
||||||
@State var refresh: Bool = false
|
@State var refresh: Bool = false
|
||||||
|
|
||||||
|
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
// var handleVisibilityChanged: (String, VisibilityChange, VisibilityTracker<String>) -> Void
|
// var handleVisibilityChanged: (String, VisibilityChange, VisibilityTracker<String>) -> Void
|
||||||
|
@ -125,6 +132,9 @@ struct Pane: View {
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
if paneConnector.visibilityTracker == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
let gTracker = paneConnector.visibilityTracker!
|
let gTracker = paneConnector.visibilityTracker!
|
||||||
|
|
||||||
Print("scroll Id target: \(paneConnector.scrollId)")
|
Print("scroll Id target: \(paneConnector.scrollId)")
|
||||||
|
|
|
@ -24,15 +24,37 @@ struct SegDenormRequest: Queryable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchValue(_ db: Database) throws -> [SegDenorm] {
|
func fetchValue(_ db: Database) throws -> [SegDenorm] {
|
||||||
print("WOOOOOOF")
|
print("segs denorm fetching for \(book)")
|
||||||
var sql = "select seg_id as id, seg.book as book, group_concat(line.body, ';;') as body from seg join line on seg.line_id = line.rowid WHERE seg.book = 'bible.john' group by seg.seg_id"
|
print(book)
|
||||||
|
var sql = """
|
||||||
|
select seg_id as id, seg.book as book, group_concat(line.body, ';;') as body from \
|
||||||
|
(select * from seg where seg.book = '\(book)') as seg \
|
||||||
|
join (select * from line where line.book = '\(book)') as line \
|
||||||
|
on seg.line_id = line.line_id group by seg.seg_id
|
||||||
|
"""
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var ret = try SegDenorm.fetchAll(db, sql: sql)
|
||||||
|
|
||||||
|
print("SEGS DENORM")
|
||||||
|
print(ret[0])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var sql2 = """
|
||||||
|
// select count(1) from seg where seg.book = '\(book)'
|
||||||
|
// """
|
||||||
|
|
||||||
|
// var ret2 = try SegDenorm.fetchAll(db, sql: sql2)
|
||||||
|
|
||||||
|
// print("test sql result")
|
||||||
|
// print(ret2[0])
|
||||||
|
|
||||||
|
|
||||||
do {
|
|
||||||
var ret = try SegDenorm.fetchAll(db, sql: sql) // [Player]
|
|
||||||
|
|
||||||
// print("SEGS DENORM")
|
|
||||||
// print(ret)
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
} catch let error {
|
} catch let error {
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
print(error)
|
print(error)
|
||||||
|
|
|
@ -51,8 +51,6 @@ struct SelectedRibbonRequest: Queryable {
|
||||||
// var ret3 = try Ribbon.fetchAll(db, sql: "SELECT * FROM Ribbon") // [Player]
|
// var ret3 = try Ribbon.fetchAll(db, sql: "SELECT * FROM Ribbon") // [Player]
|
||||||
// print(ret3)
|
// print(ret3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// print("FETCH JOIN RIBBON")
|
// print("FETCH JOIN RIBBON")
|
||||||
var ret = try Ribbon.fetchAll(db, sql: "SELECT Ribbon.* FROM SelectedRibbon join Ribbon on SelectedRibbon.ribbonId = ribbon.rowId WHERE SelectedRibbon.rowId = 1") // [Player]
|
var ret = try Ribbon.fetchAll(db, sql: "SELECT Ribbon.* FROM SelectedRibbon join Ribbon on SelectedRibbon.ribbonId = ribbon.rowId WHERE SelectedRibbon.rowId = 1") // [Player]
|
||||||
// print(ret)
|
// print(ret)
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct AppDatabase {
|
||||||
t.autoIncrementedPrimaryKey("id")
|
t.autoIncrementedPrimaryKey("id")
|
||||||
t.column("body", .text).notNull()
|
t.column("body", .text).notNull()
|
||||||
t.column("chap", .integer).notNull()
|
t.column("chap", .integer).notNull()
|
||||||
|
t.column("line_id", .integer).notNull()
|
||||||
t.column("book", .text).notNull()
|
t.column("book", .text).notNull()
|
||||||
t.column("verse", .integer)
|
t.column("verse", .integer)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,8 @@ struct AppDatabase {
|
||||||
t.column("scrollOffset", .integer).notNull()
|
t.column("scrollOffset", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
try db.create(table: "foo2") { t in
|
// change this to nuke/remake the database
|
||||||
|
try db.create(table: "foo1") { t in
|
||||||
t.autoIncrementedPrimaryKey("id")
|
t.autoIncrementedPrimaryKey("id")
|
||||||
t.column("ribbonId", .integer).notNull()
|
t.column("ribbonId", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
@ -212,27 +214,36 @@ extension AppDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importJson(_ filename: String, _ db: Database) throws {
|
func importJson(_ filename: String, _ db: Database) throws {
|
||||||
let importJson : JsonImport = load(filename)
|
let importJson: JsonImport = load(filename)
|
||||||
|
|
||||||
if try Line.all().isEmpty(db) {
|
var x = 0
|
||||||
for l in importJson.lines {
|
// if try Line.all().isEmpty(db) {
|
||||||
print("importing Lines")
|
for l in importJson.lines {
|
||||||
_ = try l.inserted(db)
|
// print("importing Lines")
|
||||||
|
if x < 5 {
|
||||||
|
print(l)
|
||||||
|
x += 1
|
||||||
}
|
}
|
||||||
|
_ = try l.inserted(db)
|
||||||
|
}
|
||||||
|
|
||||||
for l in importJson.segs {
|
x = 0
|
||||||
print("importing SEGS")
|
for l in importJson.segs {
|
||||||
_ = try l.inserted(db)
|
// print("importing SEGS")
|
||||||
|
|
||||||
|
if x < 5 {
|
||||||
|
print(l)
|
||||||
|
x += 1
|
||||||
}
|
}
|
||||||
|
_ = try l.inserted(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create random Lines if the database is empty.
|
/// Create random Lines if the database is empty.
|
||||||
func initDatabase() throws {
|
func initDatabase() throws {
|
||||||
|
do {
|
||||||
try dbWriter.write { db in
|
try dbWriter.write { db in
|
||||||
|
|
||||||
if try Line.all().isEmpty(db) {
|
if try Line.all().isEmpty(db) {
|
||||||
|
|
||||||
try importJson("john_export.json", db)
|
try importJson("john_export.json", db)
|
||||||
try importJson("mark_export.json", db)
|
try importJson("mark_export.json", db)
|
||||||
_ = try Ribbon(id: 1, pos: 1, title: "John", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db)
|
_ = try Ribbon(id: 1, pos: 1, title: "John", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db)
|
||||||
|
@ -241,6 +252,11 @@ extension AppDatabase {
|
||||||
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db)
|
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error info: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,14 +214,13 @@ struct ContentView: View {
|
||||||
@State var readOffset = CGPoint()
|
@State var readOffset = CGPoint()
|
||||||
@State var dragOffset = CGFloat()
|
@State var dragOffset = CGFloat()
|
||||||
|
|
||||||
|
@Query(SegDenormRequest(book: "bible.john")) private var segs: [SegDenorm]
|
||||||
|
|
||||||
@State var draggedRibbon: Ribbon?
|
@State var draggedRibbon: Ribbon?
|
||||||
@State var isDragging = false
|
@State var isDragging = false
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
|
||||||
|
|
||||||
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
||||||
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
|
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
|
@ -273,7 +272,6 @@ struct ContentView: View {
|
||||||
VStack {
|
VStack {
|
||||||
// Top pane
|
// Top pane
|
||||||
Pane(paneConnector: paneConnector,
|
Pane(paneConnector: paneConnector,
|
||||||
segs: segs,
|
|
||||||
selectedRibbon: selectedRibbon,
|
selectedRibbon: selectedRibbon,
|
||||||
width: geometry.size.width - 50,
|
width: geometry.size.width - 50,
|
||||||
height: geometry.size.height / 2)
|
height: geometry.size.height / 2)
|
||||||
|
|
|
@ -1,39 +1,17 @@
|
||||||
import GRDB
|
import GRDB
|
||||||
/// The Line struct.
|
/// The Line struct.
|
||||||
///
|
|
||||||
/// Identifiable conformance supports SwiftUI list animations, and type-safe
|
|
||||||
/// GRDB primary key methods.
|
|
||||||
/// Equatable conformance supports tests.
|
|
||||||
struct Line: Identifiable, Equatable {
|
struct Line: Identifiable, Equatable {
|
||||||
/// The player id.
|
|
||||||
///
|
|
||||||
/// 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 id: Int64?
|
||||||
var chap: Int
|
var chap: Int
|
||||||
|
var line_id: Int // this is a line_id per book
|
||||||
var verse: Int
|
var verse: Int
|
||||||
var body: String
|
var body: String
|
||||||
var book: String
|
var book: String
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Line {
|
extension Line {
|
||||||
|
|
||||||
private static let books = [
|
private static let books = [
|
||||||
"John", "Matthew", "Imitation of Christ"]
|
"John", "Matthew", "Imitation of Christ"]
|
||||||
|
|
||||||
/// Creates a new player with empty name and zero score
|
|
||||||
// static func new() -> Line {
|
|
||||||
// Line(id: nil, chap: 1, body: "")
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Returns a random score
|
|
||||||
static func randomScore() -> Int {
|
|
||||||
10 * Int.random(in: 0...100)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func randomBook() -> String {
|
|
||||||
books.randomElement()!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Persistence
|
// MARK: - Persistence
|
||||||
|
|
|
@ -49,11 +49,12 @@ struct LineRequest: 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
|
||||||
// to test LineRequest.
|
// to test LineRequest.
|
||||||
func fetchValue(_ db: Database) throws -> [Line] {
|
func fetchValue(_ db: Database) throws -> [Line] {
|
||||||
if book == "" {
|
return try Line.filter(bookColumn == book).fetchAll(db)
|
||||||
return try Line.filter(bookColumn == Line.randomBook()).fetchAll(db)
|
// if book == "" {
|
||||||
} else {
|
// return try Line.filter(bookColumn == Line.randomBook()).fetchAll(db)
|
||||||
return try Line.filter(bookColumn == book).fetchAll(db)
|
// } else {
|
||||||
}
|
// return try Line.filter(bookColumn == book).fetchAll(db)
|
||||||
|
// }
|
||||||
// switch ordering {
|
// switch ordering {
|
||||||
// case .byScore:
|
// case .byScore:
|
||||||
// return try Line.all().fetchAll(db)
|
// return try Line.all().fetchAll(db)
|
||||||
|
|
|
@ -40,6 +40,7 @@ extension AppDatabase {
|
||||||
// // demo purpose.
|
// // demo purpose.
|
||||||
// try appDatabase.createRandomPlayersIfEmpty()
|
// try appDatabase.createRandomPlayersIfEmpty()
|
||||||
// }
|
// }
|
||||||
|
print("initing database")
|
||||||
try appDatabase.initDatabase()
|
try appDatabase.initDatabase()
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue