working on undo - does not build rn

undo
saint 2024-05-27 22:28:13 -04:00
parent 4dfc93ea90
commit efd05ce33b
7 changed files with 151 additions and 45 deletions

59
RibbonGroup.swift Normal file
View File

@ -0,0 +1,59 @@
//
// RibbonGroup.swift
// gloss
//
// Created by Saint on 2/24/23.
//
import GRDB
/// The Line struct.
///
/// Identifiable conformance supports SwiftUI list animations, and type-safe
/// GRDB primary key methods.
/// Equatable conformance supports tests.
struct RibbonGroup: 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 pos: Int
var title: String
var current_undo_level: Int
var min_level: Int
var max_level: Int
}
extension RibbonGroup {
}
// MARK: - Persistence
/// Make Line a Codable Record.
///
/// See <https://github.com/groue/GRDB.swift/blob/master/README.md#records>
extension RibbonGroup: Codable, FetchableRecord, MutablePersistableRecord {
// Define database columns from CodingKeys
fileprivate enum Columns {
static let id = Column(CodingKeys.id)
static let pos = Column(CodingKeys.pos)
static let book = Column(CodingKeys.book)
static let title = Column(CodingKeys.title)
static let scrollOffset = Column(CodingKeys.scrollOffset)
}
/// Updates a player id after it has been inserted in the database.
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
// MARK: - Line Database Requests
/// Define some player requests used by the application.
///
/// See <https://github.com/groue/GRDB.swift/blob/master/README.md#requests>
/// See <https://github.com/groue/GRDB.swift/blob/master/Documentation/GoodPracticesForDesigningRecordTypes.md>
extension DerivableRequest<RibbonGroup> {
}

26
SegmentedSelector.swift Normal file
View File

@ -0,0 +1,26 @@
@State var selection = 0
var body: some View {
HStack {
BackArrow()
.frame(width: CGFloat(30), height: CGFloat(30))
.foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.if(selection == 0) { $0.background(Color.white) }
.if(selection != 0) { $0.background(Color.black) }
.onTapGesture {
withAnimation(.spring(response: 0.5)) {
self.selection = 0
}
}
ForwardArrow()
.frame(width: CGFloat(30), height: CGFloat(30))
.foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.if(selection == 1) { $0.background(Color.white) }
.if(selection != 1) { $0.background(Color.black) }
.onTapGesture {
withAnimation(.spring(response: 0.5)) {
self.selection = 1
}
}
}
}

View File

@ -17,7 +17,7 @@ struct SelectedRibbon: Identifiable, Equatable {
/// Int64 is the recommended type for auto-incremented database ids. /// Int64 is the recommended type for auto-incremented database ids.
/// Use nil for players that are not inserted yet in the database. /// Use nil for players that are not inserted yet in the database.
var id: Int64? var id: Int64?
var ribbonId: Int64 var ribbonGroupId: Int64
} }
extension SelectedRibbon { extension SelectedRibbon {
@ -34,7 +34,7 @@ extension SelectedRibbon: Codable, FetchableRecord, MutablePersistableRecord {
static let id = Column(CodingKeys.id) static let id = Column(CodingKeys.id)
static let ribbonId = Column(CodingKeys.ribbonId) static let ribbonId = Column(CodingKeys.ribbonId)
} }
/// Updates a player id after it has been inserted in the database. /// Updates a player id after it has been inserted in the database.
mutating func didInsert(_ inserted: InsertionSuccess) { mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID id = inserted.rowID

View File

@ -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 */; };
851259B42C05788800BE70F8 /* RibbonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851259B32C05788800BE70F8 /* RibbonGroup.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>"; };
851259B32C05788800BE70F8 /* RibbonGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RibbonGroup.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>"; };
@ -129,6 +131,7 @@
8528897B29BD69B2003F2E16 /* VisibilityTracker.swift */, 8528897B29BD69B2003F2E16 /* VisibilityTracker.swift */,
8528897A29BD69B1003F2E16 /* VisibilityTrackingModifier.swift */, 8528897A29BD69B1003F2E16 /* VisibilityTrackingModifier.swift */,
8528897929BD69B1003F2E16 /* VisibilityTrackingScrollView.swift */, 8528897929BD69B1003F2E16 /* VisibilityTrackingScrollView.swift */,
851259B32C05788800BE70F8 /* RibbonGroup.swift */,
8590D96A29A8374B001EF84F /* json */, 8590D96A29A8374B001EF84F /* json */,
8514D5BA299EF2EC0054F185 /* db */, 8514D5BA299EF2EC0054F185 /* db */,
85F01DF9297878B400F317B4 /* fonts */, 85F01DF9297878B400F317B4 /* fonts */,
@ -301,6 +304,7 @@
8590D96729A183EE001EF84F /* AppDatabase.swift in Sources */, 8590D96729A183EE001EF84F /* AppDatabase.swift in Sources */,
8590D96929A18A6D001EF84F /* LineRequest.swift in Sources */, 8590D96929A18A6D001EF84F /* LineRequest.swift in Sources */,
852774C129A150B100458CA7 /* Line.swift in Sources */, 852774C129A150B100458CA7 /* Line.swift in Sources */,
851259B42C05788800BE70F8 /* RibbonGroup.swift in Sources */,
85942EEF29AEA18300307621 /* SelectedRibbonRequest.swift in Sources */, 85942EEF29AEA18300307621 /* SelectedRibbonRequest.swift in Sources */,
8590D96C29A92146001EF84F /* JsonImport.swift in Sources */, 8590D96C29A92146001EF84F /* JsonImport.swift in Sources */,
85942EED29AEA04200307621 /* SelectedRibbon.swift in Sources */, 85942EED29AEA04200307621 /* SelectedRibbon.swift in Sources */,

View File

@ -51,10 +51,19 @@ struct AppDatabase {
t.column("book", .text).notNull() t.column("book", .text).notNull()
} }
try db.create(table: "Ribbon") { t in try db.create(table: "RibbonGroup") { t in
t.autoIncrementedPrimaryKey("id") t.autoIncrementedPrimaryKey("id")
t.column("currentUndoLevel", .integer).notNull()
t.column("minLevel", .integer).notNull()
t.column("maxLevel", .text).notNull()
t.column("pos", .integer).notNull() t.column("pos", .integer).notNull()
t.column("title", .text).notNull() t.column("title", .text).notNull()
}
try db.create(table: "Ribbon") { t in
t.autoIncrementedPrimaryKey("id")
t.column("group", .integer).notNull()
t.column("undoLevel", .integer).notNull()
t.column("book", .text).notNull() t.column("book", .text).notNull()
t.column("scrollOffset", .integer).notNull() t.column("scrollOffset", .integer).notNull()
t.column("scrollId", .text) t.column("scrollId", .text)
@ -62,7 +71,7 @@ struct AppDatabase {
try db.create(table: "SelectedRibbon") { t in try db.create(table: "SelectedRibbon") { t in
t.autoIncrementedPrimaryKey("id") t.autoIncrementedPrimaryKey("id")
t.column("ribbonId", .integer).notNull() t.column("ribbonGroupId", .integer).notNull()
} }
try db.create(table: "ScrollState") { t in try db.create(table: "ScrollState") { t in
@ -246,10 +255,50 @@ extension AppDatabase {
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: 2, pos: 2, title: "Gospel of Mark", book: "bible.mark", scrollId: "1", scrollOffset: 300).inserted(db) _ = try RibbonGroup(id: 1,
_ = try Ribbon(id: 3, pos: 3, title: "John 2", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db) pos: 1,
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db) title: "John",
current_undo_level: 1,
min_level: 1,
max_level: 1).inserted(db)
_ = try Ribbon(id: 1,
group: 1,
undoLevel: 1,
book: "bible.john",
scrollId: "1",
scrollOffset: 0).inserted(db)
_ = try RibbonGroup(id: 2,
pos: 2,
title: "Second",
current_undo_level: 1,
min_level: 1,
max_level: 1).inserted(db)
_ = try Ribbon(id: 2,
group: 2,
undoLevel: 1,
book: "bible.mark",
scrollId: "1",
scrollOffset: 0).inserted(db)
_ = try RibbonGroup(id: 3,
pos: 3,
title: "Another one",
current_undo_level: 1,
min_level: 1,
max_level: 1).inserted(db)
_ = try Ribbon(id: 3,
group: 3,
undoLevel: 1,
book: "bible.john",
scrollId: "1",
scrollOffset: 0).inserted(db)
_ = try SelectedRibbon(id: 1, ribbonGroupId: 1).inserted(db)
} }
} }
} catch { } catch {

View File

@ -272,46 +272,14 @@ struct ContentView: View {
HStack { HStack {
BackArrow() BackArrow()
.frame(width: CGFloat(30), height: CGFloat(30)) .frame(width: CGFloat(30), height: CGFloat(30))
.scaledToFit() .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))) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.tag(0)
ForwardArrow() ForwardArrow()
.frame(width: CGFloat(30), height: CGFloat(30)) .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))) .foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.tag(1)
Text("cat")
.foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.tag(2)
} }
.cornerRadius(15)
HStack {
BackArrow()
.frame(width: CGFloat(30), height: CGFloat(30))
.foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.if(selection == 0) { $0.background(Color.white) }
.if(selection != 0) { $0.background(Color.black) }
.onTapGesture {
withAnimation(.spring(response: 0.2)) {
self.selection = 0
}
}
ForwardArrow()
.frame(width: CGFloat(30), height: CGFloat(30))
.foregroundColor(Color(UIColor(red: 0.30, green: 0.30, blue: 0.30, alpha: 0.4)))
.if(selection == 1) { $0.background(Color.white) }
.if(selection != 1) { $0.background(Color.black) }
.onTapGesture {
withAnimation(.spring(response: 0.2)) {
self.selection = 1
}
}
}
.background(Color.black)
.cornerRadius(5) .cornerRadius(5)
} }
.offset(x: geometry.size.width - 300) .offset(x: geometry.size.width - 300)

View File

@ -17,8 +17,8 @@ struct Ribbon: Identifiable, Equatable {
/// Int64 is the recommended type for auto-incremented database ids. /// Int64 is the recommended type for auto-incremented database ids.
/// Use nil for players that are not inserted yet in the database. /// Use nil for players that are not inserted yet in the database.
var id: Int64? var id: Int64?
var pos: Int var group: Int
var title: String var undoLevel: Int
var book: String var book: String
var scrollId: String var scrollId: String
var scrollOffset: Int var scrollOffset: Int
@ -41,7 +41,7 @@ extension Ribbon: Codable, FetchableRecord, MutablePersistableRecord {
static let title = Column(CodingKeys.title) static let title = Column(CodingKeys.title)
static let scrollOffset = Column(CodingKeys.scrollOffset) static let scrollOffset = Column(CodingKeys.scrollOffset)
} }
/// Updates a player id after it has been inserted in the database. /// Updates a player id after it has been inserted in the database.
mutating func didInsert(_ inserted: InsertionSuccess) { mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID id = inserted.rowID