sort of workoing
parent
de0a17fc9b
commit
65563f84fc
|
@ -15,6 +15,8 @@ import GRDBQuery
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
|
||||||
|
|
||||||
|
var idColumn = Column("id")
|
||||||
struct RibbonRequest: Queryable {
|
struct RibbonRequest: Queryable {
|
||||||
// enum Ordering {
|
// enum Ordering {
|
||||||
// case byScore
|
// case byScore
|
||||||
|
@ -23,7 +25,7 @@ struct RibbonRequest: Queryable {
|
||||||
|
|
||||||
/// The ordering used by the player request.
|
/// The ordering used by the player request.
|
||||||
// var ordering: Ordering
|
// var ordering: Ordering
|
||||||
// var book: String
|
var id: Int64!
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Queryable Implementation
|
// MARK: - Queryable Implementation
|
||||||
|
@ -47,7 +49,11 @@ 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] {
|
||||||
return try Ribbon.fetchAll(db)
|
if (id == nil) {
|
||||||
|
return try Ribbon.fetchAll(db)
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Ribbon.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 SelectedRibbon: 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 ribbonId: Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SelectedRibbon {
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Persistence
|
||||||
|
|
||||||
|
/// Make Line a Codable Record.
|
||||||
|
///
|
||||||
|
/// See <https://github.com/groue/GRDB.swift/blob/master/README.md#records>
|
||||||
|
extension SelectedRibbon: Codable, FetchableRecord, MutablePersistableRecord {
|
||||||
|
// Define database columns from CodingKeys
|
||||||
|
fileprivate enum Columns {
|
||||||
|
static let id = Column(CodingKeys.id)
|
||||||
|
static let ribbonId = Column(CodingKeys.ribbonId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<SelectedRibbon> {
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
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(SelectedRibbonRequest(ordering: .byName)) private var players: [SelectedRibbon]
|
||||||
|
///
|
||||||
|
/// var body: some View {
|
||||||
|
/// List(players) { player in ... )
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
|
||||||
|
struct SelectedRibbonRequest: Queryable {
|
||||||
|
// enum Ordering {
|
||||||
|
// case byScore
|
||||||
|
// case byName
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// The ordering used by the player request.
|
||||||
|
// var ordering: Ordering
|
||||||
|
var id: Int64!
|
||||||
|
|
||||||
|
// MARK: - Queryable Implementation
|
||||||
|
|
||||||
|
static var defaultValue: [SelectedRibbon] { [] }
|
||||||
|
|
||||||
|
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[SelectedRibbon], Error> {
|
||||||
|
// Build the publisher from the general-purpose read-only access
|
||||||
|
// granted by `appDatabase.reader`.
|
||||||
|
// Some apps will prefer to call a dedicated method of `appDatabase`.
|
||||||
|
ValueObservation
|
||||||
|
.tracking(fetchValue(_:))
|
||||||
|
.publisher(
|
||||||
|
in: appDatabase.reader,
|
||||||
|
// The `.immediate` scheduling feeds the view right on
|
||||||
|
// subscription, and avoids an undesired animation when the
|
||||||
|
// application starts.
|
||||||
|
scheduling: .immediate)
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is not required by Queryable, but it makes it easier
|
||||||
|
func fetchValue(_ db: Database) throws -> [SelectedRibbon] {
|
||||||
|
if (id == nil) {
|
||||||
|
return try SelectedRibbon.fetchAll(db)
|
||||||
|
} else {
|
||||||
|
return try SelectedRibbon.filter(idColumn == id).fetchAll(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if book == "" {
|
||||||
|
// return try SelectedRibbon.filter(bookColumn == SelectedRibbon.randomBook()).fetchAll(db)
|
||||||
|
// } else {
|
||||||
|
// return try SelectedRibbon.filter(bookColumn == book).fetchAll(db)
|
||||||
|
// }
|
||||||
|
// switch ordering {
|
||||||
|
// case .byScore:
|
||||||
|
// return try SelectedRibbon.all().fetchAll(db)
|
||||||
|
// case .byName:
|
||||||
|
// // return try SelectedRibbon.all().orderedByName().fetchAll(db)
|
||||||
|
// return try SelectedRibbon.all().fetchAll(db)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,8 @@
|
||||||
85942EE729AD083600307621 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 85942EE629AD083600307621 /* Introspect */; };
|
85942EE729AD083600307621 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 85942EE629AD083600307621 /* Introspect */; };
|
||||||
85942EE929AD51A100307621 /* Ribbon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EE829AD51A100307621 /* Ribbon.swift */; };
|
85942EE929AD51A100307621 /* Ribbon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EE829AD51A100307621 /* Ribbon.swift */; };
|
||||||
85942EEB29AD55A400307621 /* RibbonRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EEA29AD55A400307621 /* RibbonRequest.swift */; };
|
85942EEB29AD55A400307621 /* RibbonRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EEA29AD55A400307621 /* RibbonRequest.swift */; };
|
||||||
|
85942EED29AEA04200307621 /* SelectedRibbon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EEC29AEA04200307621 /* SelectedRibbon.swift */; };
|
||||||
|
85942EEF29AEA18300307621 /* SelectedRibbonRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */; };
|
||||||
85F01DF82978787800F317B4 /* AveriaSerifLibre-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F01DF72978787800F317B4 /* AveriaSerifLibre-Regular.ttf */; };
|
85F01DF82978787800F317B4 /* AveriaSerifLibre-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F01DF72978787800F317B4 /* AveriaSerifLibre-Regular.ttf */; };
|
||||||
85F01DFB2978790400F317B4 /* xe-Dogma-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F01DFA2978790400F317B4 /* xe-Dogma-Bold.ttf */; };
|
85F01DFB2978790400F317B4 /* xe-Dogma-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 85F01DFA2978790400F317B4 /* xe-Dogma-Bold.ttf */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
@ -50,6 +52,8 @@
|
||||||
85942EE329ACF54A00307621 /* ScrollableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableView.swift; sourceTree = "<group>"; };
|
85942EE329ACF54A00307621 /* ScrollableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableView.swift; sourceTree = "<group>"; };
|
||||||
85942EE829AD51A100307621 /* Ribbon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ribbon.swift; sourceTree = "<group>"; };
|
85942EE829AD51A100307621 /* Ribbon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ribbon.swift; sourceTree = "<group>"; };
|
||||||
85942EEA29AD55A400307621 /* RibbonRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RibbonRequest.swift; sourceTree = "<group>"; };
|
85942EEA29AD55A400307621 /* RibbonRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RibbonRequest.swift; sourceTree = "<group>"; };
|
||||||
|
85942EEC29AEA04200307621 /* SelectedRibbon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedRibbon.swift; sourceTree = "<group>"; };
|
||||||
|
85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedRibbonRequest.swift; sourceTree = "<group>"; };
|
||||||
85F01DF72978787800F317B4 /* AveriaSerifLibre-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AveriaSerifLibre-Regular.ttf"; sourceTree = "<group>"; };
|
85F01DF72978787800F317B4 /* AveriaSerifLibre-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AveriaSerifLibre-Regular.ttf"; sourceTree = "<group>"; };
|
||||||
85F01DFA2978790400F317B4 /* xe-Dogma-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "xe-Dogma-Bold.ttf"; sourceTree = "<group>"; };
|
85F01DFA2978790400F317B4 /* xe-Dogma-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "xe-Dogma-Bold.ttf"; sourceTree = "<group>"; };
|
||||||
85F01DFC29787B3500F317B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
85F01DFC29787B3500F317B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
@ -83,6 +87,8 @@
|
||||||
85431A7C2905F4F500EE0760 = {
|
85431A7C2905F4F500EE0760 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
85942EEC29AEA04200307621 /* SelectedRibbon.swift */,
|
||||||
|
85942EEE29AEA18300307621 /* SelectedRibbonRequest.swift */,
|
||||||
85942EEA29AD55A400307621 /* RibbonRequest.swift */,
|
85942EEA29AD55A400307621 /* RibbonRequest.swift */,
|
||||||
85942EE329ACF54A00307621 /* ScrollableView.swift */,
|
85942EE329ACF54A00307621 /* ScrollableView.swift */,
|
||||||
8590D96A29A8374B001EF84F /* json */,
|
8590D96A29A8374B001EF84F /* json */,
|
||||||
|
@ -251,7 +257,9 @@
|
||||||
8590D96929A18A6D001EF84F /* LineRequest.swift in Sources */,
|
8590D96929A18A6D001EF84F /* LineRequest.swift in Sources */,
|
||||||
8590D96E29A927CF001EF84F /* Seg.swift in Sources */,
|
8590D96E29A927CF001EF84F /* Seg.swift in Sources */,
|
||||||
852774C129A150B100458CA7 /* Line.swift in Sources */,
|
852774C129A150B100458CA7 /* Line.swift in Sources */,
|
||||||
|
85942EEF29AEA18300307621 /* SelectedRibbonRequest.swift in Sources */,
|
||||||
8590D96C29A92146001EF84F /* JsonImport.swift in Sources */,
|
8590D96C29A92146001EF84F /* JsonImport.swift in Sources */,
|
||||||
|
85942EED29AEA04200307621 /* SelectedRibbon.swift in Sources */,
|
||||||
85431A892905F4F500EE0760 /* glossApp.swift in Sources */,
|
85431A892905F4F500EE0760 /* glossApp.swift in Sources */,
|
||||||
85431A9C2905F5D800EE0760 /* SwiftUIView.swift in Sources */,
|
85431A9C2905F5D800EE0760 /* SwiftUIView.swift in Sources */,
|
||||||
85942EE429ACF54A00307621 /* ScrollableView.swift in Sources */,
|
85942EE429ACF54A00307621 /* ScrollableView.swift in Sources */,
|
||||||
|
|
Binary file not shown.
|
@ -48,6 +48,11 @@ struct AppDatabase {
|
||||||
t.column("book", .text).notNull()
|
t.column("book", .text).notNull()
|
||||||
t.column("scrollOffset", .integer).notNull()
|
t.column("scrollOffset", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try db.create(table: "SelectedRibbon") { t in
|
||||||
|
t.autoIncrementedPrimaryKey("id")
|
||||||
|
t.column("ribbonId", .integer).notNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +92,24 @@ func load<T: Decodable>(_ filename: String) -> T {
|
||||||
|
|
||||||
extension AppDatabase {
|
extension AppDatabase {
|
||||||
|
|
||||||
|
func saveRibbon(_ ribbon: inout Ribbon) async throws {
|
||||||
|
// if ribbon.name.isEmpty {
|
||||||
|
// throw ValidationError.missingName
|
||||||
|
// }
|
||||||
|
ribbon = try await dbWriter.write { [ribbon] db in
|
||||||
|
try ribbon.saved(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveSelectedRibbon(_ selectedRibbon: inout SelectedRibbon) async throws {
|
||||||
|
// if selectedRibbon.name.isEmpty {
|
||||||
|
// throw ValidationError.missingName
|
||||||
|
// }
|
||||||
|
selectedRibbon = try await dbWriter.write { [selectedRibbon] db in
|
||||||
|
try selectedRibbon.saved(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create random Lines if the database is empty.
|
/// Create random Lines if the database is empty.
|
||||||
func createRandomLinesIfEmpty() throws {
|
func createRandomLinesIfEmpty() throws {
|
||||||
|
|
||||||
|
@ -103,6 +126,7 @@ extension AppDatabase {
|
||||||
// try createRandomLines(db)
|
// try createRandomLines(db)
|
||||||
_ = try Ribbon(id: nil, book: "bible.john", scrollOffset: 0).inserted(db)
|
_ = try Ribbon(id: nil, book: "bible.john", scrollOffset: 0).inserted(db)
|
||||||
_ = try Ribbon(id: nil, book: "bible.john", scrollOffset: 2000).inserted(db)
|
_ = try Ribbon(id: nil, book: "bible.john", scrollOffset: 2000).inserted(db)
|
||||||
|
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +159,7 @@ extension AppDatabase {
|
||||||
|
|
||||||
// MARK: - Database Access: Reads
|
// MARK: - Database Access: Reads
|
||||||
|
|
||||||
// This demo app does not provide any specific reading method, and instead
|
// This demo app does not provide any specific reading method, and insteadKK
|
||||||
// gives an unrestricted read-only access to the rest of the application.
|
// gives an unrestricted read-only access to the rest of the application.
|
||||||
// In your app, you are free to choose another path, and define focused
|
// In your app, you are free to choose another path, and define focused
|
||||||
// reading methods.
|
// reading methods.
|
||||||
|
|
|
@ -14,6 +14,25 @@ let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network
|
||||||
|
|
||||||
// var curBook = "John"
|
// var curBook = "John"
|
||||||
|
|
||||||
|
extension UserDefaults {
|
||||||
|
|
||||||
|
public func optionalInt(forKey defaultName: String) -> Int? {
|
||||||
|
let defaults = self
|
||||||
|
if let value = defaults.value(forKey: defaultName) {
|
||||||
|
return value as? Int
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public func optionalBool(forKey defaultName: String) -> Bool? {
|
||||||
|
let defaults = self
|
||||||
|
if let value = defaults.value(forKey: defaultName) {
|
||||||
|
return value as? Bool
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension UINavigationController {
|
extension UINavigationController {
|
||||||
override open func viewDidLoad() {
|
override open func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
@ -46,23 +65,132 @@ struct BlueButtonStyle: ButtonStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PositionObservingView<Content: View>: View {
|
||||||
struct SwitchButton : View {
|
var coordinateSpace: CoordinateSpace
|
||||||
var ribbon: Ribbon
|
@Binding var position: CGPoint
|
||||||
@Binding var selectedRibbon : Ribbon?
|
@ViewBuilder var content: () -> Content
|
||||||
@Binding var book : String
|
|
||||||
@Binding var scrollOffset : CGFloat
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button("meow") {
|
content()
|
||||||
book = ribbon.book
|
.background(GeometryReader { geometry in
|
||||||
selectedRibbon = ribbon
|
Color.clear.preference(
|
||||||
Print(ribbon.scrollOffset)
|
key: PreferenceKey.self,
|
||||||
Print(scrollOffset)
|
value: geometry.frame(in: coordinateSpace).origin
|
||||||
scrollOffset = CGFloat(ribbon.scrollOffset)
|
)
|
||||||
//Print("hellosdf dddd")
|
})
|
||||||
|
.onPreferenceChange(PreferenceKey.self) { position in
|
||||||
|
self.position = position
|
||||||
|
// Print(self.position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private extension PositionObservingView {
|
||||||
|
struct PreferenceKey: SwiftUI.PreferenceKey {
|
||||||
|
static var defaultValue: CGPoint { .zero }
|
||||||
|
|
||||||
|
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) {
|
||||||
|
// No-op
|
||||||
}
|
}
|
||||||
.buttonStyle(BlueButtonStyle())
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OffsetObservingScrollView<Content: View>: View {
|
||||||
|
var axes: Axis.Set = [.vertical]
|
||||||
|
var showsIndicators = true
|
||||||
|
@Binding var offset: CGPoint
|
||||||
|
@ViewBuilder var content: () -> Content
|
||||||
|
|
||||||
|
// The name of our coordinate space doesn't have to be
|
||||||
|
// stable between view updates (it just needs to be
|
||||||
|
// consistent within this view), so we'll simply use a
|
||||||
|
// plain UUID for it:
|
||||||
|
private let coordinateSpaceName = UUID()
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView(axes, showsIndicators: showsIndicators) {
|
||||||
|
PositionObservingView(
|
||||||
|
coordinateSpace: .named(coordinateSpaceName),
|
||||||
|
position: Binding(
|
||||||
|
get: { offset },
|
||||||
|
set: { newOffset in
|
||||||
|
offset = CGPoint(
|
||||||
|
x: -newOffset.x,
|
||||||
|
y: -newOffset.y
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
content: content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.coordinateSpace(name: coordinateSpaceName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct SwitchButton : View {
|
||||||
|
@State var ribbon: Ribbon
|
||||||
|
// @State var selectedRibbon: SelectedRibbon
|
||||||
|
@Binding var book : String
|
||||||
|
@Binding var scrollOffset : CGFloat
|
||||||
|
@Binding var readOffset: CGPoint
|
||||||
|
|
||||||
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
|
|
||||||
|
@Query(SelectedRibbonRequest()) private var sr: [SelectedRibbon]
|
||||||
|
|
||||||
|
@State var saveOffset = CGFloat()
|
||||||
|
var body: some View {
|
||||||
|
// ForEach(sr) { selectedRibbon in
|
||||||
|
Button("meow",
|
||||||
|
action: {
|
||||||
|
Task {
|
||||||
|
var selectedRibbon = sr[0]
|
||||||
|
|
||||||
|
saveOffset = CGFloat(readOffset.y)
|
||||||
|
Print("save/read offset", readOffset.y)
|
||||||
|
|
||||||
|
Print("START")
|
||||||
|
_ = Print(ribbon)
|
||||||
|
_ = Print(selectedRibbon)
|
||||||
|
Print("START2")
|
||||||
|
|
||||||
|
if (selectedRibbon.ribbonId != ribbon.id!) {
|
||||||
|
Print(ribbon.id!)
|
||||||
|
Print("switching")
|
||||||
|
book = ribbon.book
|
||||||
|
scrollOffset = CGFloat(ribbon.scrollOffset)
|
||||||
|
// scrollOffset = CGFloat(1500)
|
||||||
|
Print("setted offset value", scrollOffset)
|
||||||
|
selectedRibbon.ribbonId = ribbon.id!
|
||||||
|
_ = try await appDatabase.saveSelectedRibbon(&selectedRibbon)
|
||||||
|
_ = Print(selectedRibbon)
|
||||||
|
}
|
||||||
|
var editedRibbon = ribbon
|
||||||
|
editedRibbon.scrollOffset = Int(saveOffset)
|
||||||
|
Print("current ribbon offset after potential switch", editedRibbon.scrollOffset)
|
||||||
|
|
||||||
|
_ = try await appDatabase.saveRibbon(&editedRibbon)
|
||||||
|
_ = Print(editedRibbon)
|
||||||
|
|
||||||
|
Print("ribbon offset saved")
|
||||||
|
|
||||||
|
Print("set offset value", scrollOffset)
|
||||||
|
Print("read offset value", readOffset.y)
|
||||||
|
|
||||||
|
|
||||||
|
Print("END")
|
||||||
|
_ = Print(ribbon)
|
||||||
|
_ = Print(selectedRibbon)
|
||||||
|
Print("END2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
.buttonStyle(BlueButtonStyle())
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,32 +203,47 @@ struct ContentView: View {
|
||||||
// @State var scrollTo1 : Int64?
|
// @State var scrollTo1 : Int64?
|
||||||
@State var selectedLine : Int64?
|
@State var selectedLine : Int64?
|
||||||
@State var scrollOffset = CGFloat()
|
@State var scrollOffset = CGFloat()
|
||||||
@State var selectedRibbon: Ribbon!
|
|
||||||
|
// @State var selectedRibbon: Ribbon!,
|
||||||
|
// @State var selectedRibbon: Ribbon!
|
||||||
|
|
||||||
|
// @State var selectedRibbonId = Int64(UserDefaults.standard.optionalInt(forKey: "selectedRibbonId") ?? 1)
|
||||||
|
|
||||||
|
|
||||||
|
@Query(SelectedRibbonRequest()) private var selectedRibbon: [SelectedRibbon]
|
||||||
|
|
||||||
|
@State var endedDrag = true
|
||||||
|
|
||||||
|
@State var readOffset = CGPoint()
|
||||||
|
|
||||||
@Query(LineRequest(ordering: .byScore, book: "bible.john")) private var lines: [Line]
|
@Query(LineRequest(ordering: .byScore, book: "bible.john")) private var lines: [Line]
|
||||||
|
|
||||||
|
|
||||||
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
||||||
|
|
||||||
// @Query<LineRequest> private var lines: [Line]
|
// @Query*RibbonRequest> private var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
|
// @Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1))) private var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
UITableView.appearance().backgroundColor = UIColor(Color(red: 0.2, green: 0.2, blue: 0.2))
|
UITableView.appearance().backgroundColor = UIColor(Color(red: 0.2, green: 0.2, blue: 0.2))
|
||||||
// _lines = Query(LineRequest(ordering: .byScore, book: curBook))
|
// _selectedRibbon = Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Environment(\.managedObjectContext) private var viewContext
|
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { geometry in
|
GeometryReader { geometry in
|
||||||
ZStack{
|
ZStack{
|
||||||
VStack{
|
VStack{
|
||||||
ForEach(ribbons) { ribbon in
|
ForEach(ribbons) { ribbon in
|
||||||
SwitchButton(ribbon: ribbon,
|
ForEach(selectedRibbon) { sr in
|
||||||
selectedRibbon: $selectedRibbon,
|
SwitchButton(ribbon: ribbon,
|
||||||
book: $lines.book,
|
// selectedRibbon:sr,
|
||||||
scrollOffset: $scrollOffset)
|
book: $lines.book,
|
||||||
.buttonStyle(BlueButtonStyle())
|
scrollOffset: $scrollOffset,
|
||||||
|
readOffset: $readOffset
|
||||||
|
)
|
||||||
|
.buttonStyle(BlueButtonStyle())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading)
|
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading)
|
||||||
|
@ -109,7 +252,8 @@ struct ContentView: View {
|
||||||
// VStack (spacing: 0){
|
// VStack (spacing: 0){
|
||||||
ScrollViewReader { proxy in
|
ScrollViewReader { proxy in
|
||||||
//ScrollableView($offset, animationDuration: 0) {
|
//ScrollableView($offset, animationDuration: 0) {
|
||||||
ScrollView {
|
OffsetObservingScrollView(offset: $readOffset)
|
||||||
|
{
|
||||||
// List {
|
// List {
|
||||||
LazyVStack {
|
LazyVStack {
|
||||||
ForEach(lines) { line in
|
ForEach(lines) { line in
|
||||||
|
@ -143,7 +287,10 @@ struct ContentView: View {
|
||||||
.introspectScrollView { scrollView in
|
.introspectScrollView { scrollView in
|
||||||
//let width = scrollView.contentSize.width - scrollView.frame.width
|
//let width = scrollView.contentSize.width - scrollView.frame.width
|
||||||
//Print(scrollView.contentOffset.x)
|
//Print(scrollView.contentOffset.x)
|
||||||
scrollView.contentOffset.y = scrollOffset
|
// Print("here")
|
||||||
|
if (scrollOffset != scrollView.contentOffset.y) {
|
||||||
|
scrollView.contentOffset.y = scrollOffset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.listStyle(PlainListStyle())
|
.listStyle(PlainListStyle())
|
||||||
|
|
||||||
|
@ -154,15 +301,15 @@ struct ContentView: View {
|
||||||
.offset(x:30 , y:0)
|
.offset(x:30 , y:0)
|
||||||
.offset(x: pulledOut.width)
|
.offset(x: pulledOut.width)
|
||||||
.offset(x: viewState.width, y: viewState.height)
|
.offset(x: viewState.width, y: viewState.height)
|
||||||
.onAppear {
|
|
||||||
if (selectedRibbon != nil) {
|
|
||||||
Print(selectedRibbon)
|
|
||||||
//scrollOffset.y = scrollOffset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.gesture(
|
.gesture(
|
||||||
DragGesture()
|
DragGesture()
|
||||||
.onChanged { gesture in
|
.onChanged { gesture in
|
||||||
|
|
||||||
|
if (endedDrag) {
|
||||||
|
endedDrag = false
|
||||||
|
scrollOffset = readOffset.y - 20
|
||||||
|
_ = Print("meow")
|
||||||
|
}
|
||||||
// logger.error("hello222")
|
// logger.error("hello222")
|
||||||
// NSLog("hellooo")
|
// NSLog("hellooo")
|
||||||
//Print(viewState.width)
|
//Print(viewState.width)
|
||||||
|
@ -171,6 +318,7 @@ struct ContentView: View {
|
||||||
// logger.log("hello")
|
// logger.log("hello")
|
||||||
}
|
}
|
||||||
.onEnded { _ in
|
.onEnded { _ in
|
||||||
|
endedDrag = true
|
||||||
var pulledOutWidth = CGFloat(0)
|
var pulledOutWidth = CGFloat(0)
|
||||||
if (viewState.width < 0) {
|
if (viewState.width < 0) {
|
||||||
pulledOutWidth = CGFloat(0)
|
pulledOutWidth = CGFloat(0)
|
||||||
|
|
|
@ -49,44 +49,5 @@ extension Ribbon: Codable, FetchableRecord, MutablePersistableRecord {
|
||||||
///
|
///
|
||||||
/// See <https://github.com/groue/GRDB.swift/blob/master/README.md#requests>
|
/// See <https://github.com/groue/GRDB.swift/blob/master/README.md#requests>
|
||||||
/// See <https://github.com/groue/GRDB.swift/blob/master/Documentation/GoodPracticesForDesigningRecordTypes.md>
|
/// See <https://github.com/groue/GRDB.swift/blob/master/Documentation/GoodPracticesForDesigningRecordTypes.md>
|
||||||
extension DerivableRequest<Line> {
|
extension DerivableRequest<Ribbon> {
|
||||||
/// A request of players ordered by name.
|
|
||||||
///
|
|
||||||
/// For example:
|
|
||||||
///
|
|
||||||
/// let players: [Line] = try dbWriter.read { db in
|
|
||||||
/// try Line.all().orderedByName().fetchAll(db)
|
|
||||||
/// }
|
|
||||||
//func orderedByName() -> Self {
|
|
||||||
// // Sort by name in a localized case insensitive fashion
|
|
||||||
// // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison
|
|
||||||
// order(Line.Columns.name.collating(.localizedCaseInsensitiveCompare))
|
|
||||||
//}
|
|
||||||
|
|
||||||
///// A request of players ordered by score.
|
|
||||||
/////
|
|
||||||
///// For example:
|
|
||||||
/////
|
|
||||||
///// let players: [Line] = try dbWriter.read { db in
|
|
||||||
///// try Line.all().orderedByScore().fetchAll(db)
|
|
||||||
///// }
|
|
||||||
///// let bestLine: Line? = try dbWriter.read { db in
|
|
||||||
///// try Line.all().orderedByScore().fetchOne(db)
|
|
||||||
///// }
|
|
||||||
//func orderedByScore() -> Self {
|
|
||||||
// // Sort by descending score, and then by name, in a
|
|
||||||
// // localized case insensitive fashion
|
|
||||||
// // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison
|
|
||||||
// order(
|
|
||||||
// Line.Columns.score.desc,
|
|
||||||
// Line.Columns.name.collating(.localizedCaseInsensitiveCompare))
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ribbon.swift
|
|
||||||
// gloss
|
|
||||||
//
|
|
||||||
// Created by Saint on 2/27/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
Loading…
Reference in New Issue