Compare commits
No commits in common. "master" and "undo" have entirely different histories.
84
Pane.swift
84
Pane.swift
|
@ -14,63 +14,46 @@ import WrappingHStack
|
||||||
struct SegRow: View {
|
struct SegRow: View {
|
||||||
var seg: SegDenorm
|
var seg: SegDenorm
|
||||||
var ribbonId: Int64
|
var ribbonId: Int64
|
||||||
var width: CGFloat
|
|
||||||
@State var highlights = Set<Int>()
|
@State var highlights = Set<Int>()
|
||||||
@ObservedObject var showTitle: ShowTitle
|
|
||||||
|
|
||||||
|
|
||||||
let intraWordSpacing = CGFloat(1.6)
|
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: ";;")
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
var retView = VStack {
|
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
||||||
Text("\(seg.chap)")
|
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
||||||
.frame(width: width)
|
|
||||||
.padding(.vertical, 10)
|
|
||||||
|
|
||||||
.if(showTitle.chapVisible) { $0.foregroundColor(mainTextColor) }
|
let verse = try! decoder.decode(Verse.self, from: segSplit[segIndex].data(using: .utf8)!)
|
||||||
.if(!showTitle.chapVisible) { $0.foregroundColor(secondBackgroundColor) }
|
let arrayOfText = verse.body.components(separatedBy: " ")
|
||||||
|
|
||||||
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
let lineHeight = CGFloat(30)
|
||||||
.background(secondBackgroundColor)
|
let fontSize = CGFloat(18)
|
||||||
// .background(mainBackgroundColor)
|
let highlightColor = "470000"
|
||||||
.onTapGesture {
|
ForEach(0 ..< arrayOfText.count, id: \.self) { index in
|
||||||
showTitle.chapVisible.toggle()
|
HStack(spacing: 0) {
|
||||||
}
|
if index == 0 {
|
||||||
WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
Text("")
|
||||||
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
|
||||||
|
|
||||||
let verse = try! decoder.decode(Verse.self, from: segSplit[segIndex].data(using: .utf8)!)
|
|
||||||
let arrayOfText = verse.body.components(separatedBy: " ")
|
|
||||||
|
|
||||||
let lineHeight = CGFloat(30)
|
|
||||||
let fontSize = CGFloat(18)
|
|
||||||
let highlightColor = "470000"
|
|
||||||
ForEach(0 ..< arrayOfText.count, id: \.self) { index in
|
|
||||||
HStack(spacing: 0) {
|
|
||||||
if index == 0 {
|
|
||||||
Text("")
|
|
||||||
.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))
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
|
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
ZStack {
|
ZStack {
|
||||||
Text(" ")
|
Text(" ")
|
||||||
.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))
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
Text(String(verse.verse))
|
Text(String(verse.verse))
|
||||||
.font(Font.custom("AveriaSerifLibre-Regular", size: 10))
|
.font(Font.custom("AveriaSerifLibre-Regular", size: 10))
|
||||||
.padding(.horizontal, 0)
|
.padding(.horizontal, 0)
|
||||||
.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)))
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
}
|
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
|
||||||
}
|
}
|
||||||
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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))
|
||||||
|
|
||||||
|
@ -86,10 +69,9 @@ struct SegRow: View {
|
||||||
self.highlights.insert(verse.verse)
|
self.highlights.insert(verse.verse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.frame(height: 16) // intra line spacing
|
|
||||||
.padding(.vertical, 0)
|
|
||||||
}
|
}
|
||||||
|
.frame(height: 16) // intra line spacing
|
||||||
|
.padding(.vertical, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,31 +79,21 @@ struct SegRow: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShowTitle: NSObject, ObservableObject {
|
|
||||||
@Published var chapVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct Pane: View {
|
struct Pane: View {
|
||||||
@ObservedObject var paneConnector: PaneConnector
|
@ObservedObject var paneConnector: PaneConnector
|
||||||
@ObservedObject var scrollDelegate: ScrollDelegate
|
|
||||||
@StateObject var showTitle = ShowTitle()
|
|
||||||
|
|
||||||
// @State var chapVisible = false
|
|
||||||
|
|
||||||
@State var selectedRibbon: [Ribbon]
|
@State var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
@State var width: CGFloat
|
@State var width: CGFloat
|
||||||
@State var height: CGFloat
|
@State var height: CGFloat
|
||||||
|
|
||||||
|
|
||||||
var dragOffset = CGFloat()
|
var dragOffset = CGFloat()
|
||||||
|
|
||||||
@State var refresh: Bool = false
|
@State var refresh: Bool = false
|
||||||
|
|
||||||
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
||||||
|
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -132,13 +104,10 @@ struct Pane: View {
|
||||||
LazyVStack {
|
LazyVStack {
|
||||||
ForEach(segs) { seg in
|
ForEach(segs) { seg in
|
||||||
SegRow(seg: seg,
|
SegRow(seg: seg,
|
||||||
ribbonId: selectedRibbon[0].id!,
|
ribbonId: selectedRibbon[0].id!)
|
||||||
width: width,
|
|
||||||
showTitle: showTitle
|
|
||||||
)
|
|
||||||
.id("\(seg.id)")
|
.id("\(seg.id)")
|
||||||
.offset(x: -dragOffset)
|
.offset(x: -dragOffset)
|
||||||
.padding(EdgeInsets(top: 10, leading: 20, bottom: 20, trailing: 20))
|
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
|
||||||
.trackVisibility(id: "\(seg.id)")
|
.trackVisibility(id: "\(seg.id)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,11 +173,12 @@ struct Pane: View {
|
||||||
let reactive = self.refresh
|
let reactive = self.refresh
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollView.canCancelContentTouches = false
|
// if self.paneConnector != nil {
|
||||||
scrollView.delegate = scrollDelegate
|
// let reactive = self.paneConnector
|
||||||
|
// }
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if paneConnector.setScrollOffset != nil {
|
if paneConnector.setScrollOffset != nil {
|
||||||
scrollView.contentOffset.y = scrollView.contentOffset.y + paneConnector.setScrollOffset!
|
scrollView.contentOffset.y = scrollView.contentOffset.y + paneConnector.setScrollOffset!
|
||||||
paneConnector.setScrollOffset = nil
|
paneConnector.setScrollOffset = nil
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ struct SegDenorm: Identifiable, Equatable {
|
||||||
var body: String
|
var body: String
|
||||||
// var lineIds: [Int64]
|
// var lineIds: [Int64]
|
||||||
var book: String
|
var book: String
|
||||||
var chap: Int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SegDenorm {
|
extension SegDenorm {
|
||||||
|
|
|
@ -43,7 +43,7 @@ struct SegDenormRequest: Queryable {
|
||||||
var book = ret[0].book
|
var book = ret[0].book
|
||||||
|
|
||||||
var sql = """
|
var sql = """
|
||||||
select seg_id as id, line.chap as chap, seg.book as book, group_concat(line.body, ';;') as body from \
|
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 \
|
(select * from seg where seg.book = '\(book)') as seg \
|
||||||
join (select * from line where line.book = '\(book)') as line \
|
join (select * from line where line.book = '\(book)') as line \
|
||||||
on seg.line_id = line.line_id group by seg.seg_id
|
on seg.line_id = line.line_id group by seg.seg_id
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
85942EFE29B11C0B00307621 /* john_export.json in Resources */ = {isa = PBXBuildFile; fileRef = 85942EFC29B11C0A00307621 /* john_export.json */; };
|
85942EFE29B11C0B00307621 /* john_export.json in Resources */ = {isa = PBXBuildFile; fileRef = 85942EFC29B11C0A00307621 /* john_export.json */; };
|
||||||
85942EFF29B11C0B00307621 /* mark_export.json in Resources */ = {isa = PBXBuildFile; fileRef = 85942EFD29B11C0B00307621 /* mark_export.json */; };
|
85942EFF29B11C0B00307621 /* mark_export.json in Resources */ = {isa = PBXBuildFile; fileRef = 85942EFD29B11C0B00307621 /* mark_export.json */; };
|
||||||
8594ED982BF6845F001213F2 /* HexColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8594ED972BF6845F001213F2 /* HexColor.swift */; };
|
8594ED982BF6845F001213F2 /* HexColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8594ED972BF6845F001213F2 /* HexColor.swift */; };
|
||||||
85AAAF572C1A0BC700FCB723 /* acts_export.json in Resources */ = {isa = PBXBuildFile; fileRef = 85AAAF562C1A0BC700FCB723 /* acts_export.json */; };
|
|
||||||
85E00E7C29F34D2D00FF9E78 /* ScrollState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E00E7B29F34D2D00FF9E78 /* ScrollState.swift */; };
|
85E00E7C29F34D2D00FF9E78 /* ScrollState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E00E7B29F34D2D00FF9E78 /* ScrollState.swift */; };
|
||||||
85E00E7E29F34D3700FF9E78 /* ScrollStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E00E7D29F34D3700FF9E78 /* ScrollStateRequest.swift */; };
|
85E00E7E29F34D3700FF9E78 /* ScrollStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E00E7D29F34D3700FF9E78 /* ScrollStateRequest.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 */; };
|
||||||
|
@ -84,7 +83,6 @@
|
||||||
85942EFC29B11C0A00307621 /* john_export.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = john_export.json; sourceTree = "<group>"; };
|
85942EFC29B11C0A00307621 /* john_export.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = john_export.json; sourceTree = "<group>"; };
|
||||||
85942EFD29B11C0B00307621 /* mark_export.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = mark_export.json; sourceTree = "<group>"; };
|
85942EFD29B11C0B00307621 /* mark_export.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = mark_export.json; sourceTree = "<group>"; };
|
||||||
8594ED972BF6845F001213F2 /* HexColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexColor.swift; sourceTree = "<group>"; };
|
8594ED972BF6845F001213F2 /* HexColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HexColor.swift; sourceTree = "<group>"; };
|
||||||
85AAAF562C1A0BC700FCB723 /* acts_export.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = acts_export.json; sourceTree = "<group>"; };
|
|
||||||
85E00E7B29F34D2D00FF9E78 /* ScrollState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollState.swift; sourceTree = "<group>"; };
|
85E00E7B29F34D2D00FF9E78 /* ScrollState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollState.swift; sourceTree = "<group>"; };
|
||||||
85E00E7D29F34D3700FF9E78 /* ScrollStateRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollStateRequest.swift; sourceTree = "<group>"; };
|
85E00E7D29F34D3700FF9E78 /* ScrollStateRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollStateRequest.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>"; };
|
||||||
|
@ -189,7 +187,6 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
85942EFC29B11C0A00307621 /* john_export.json */,
|
85942EFC29B11C0A00307621 /* john_export.json */,
|
||||||
85AAAF562C1A0BC700FCB723 /* acts_export.json */,
|
|
||||||
85942EFD29B11C0B00307621 /* mark_export.json */,
|
85942EFD29B11C0B00307621 /* mark_export.json */,
|
||||||
);
|
);
|
||||||
path = json;
|
path = json;
|
||||||
|
@ -286,7 +283,6 @@
|
||||||
85F01DFB2978790400F317B4 /* xe-Dogma-Bold.ttf in Resources */,
|
85F01DFB2978790400F317B4 /* xe-Dogma-Bold.ttf in Resources */,
|
||||||
85F01DF82978787800F317B4 /* AveriaSerifLibre-Regular.ttf in Resources */,
|
85F01DF82978787800F317B4 /* AveriaSerifLibre-Regular.ttf in Resources */,
|
||||||
8514D5BC299EFB780054F185 /* store.db in Resources */,
|
8514D5BC299EFB780054F185 /* store.db in Resources */,
|
||||||
85AAAF572C1A0BC700FCB723 /* acts_export.json in Resources */,
|
|
||||||
85942EFF29B11C0B00307621 /* mark_export.json in Resources */,
|
85942EFF29B11C0B00307621 /* mark_export.json in Resources */,
|
||||||
85942EFE29B11C0B00307621 /* john_export.json in Resources */,
|
85942EFE29B11C0B00307621 /* john_export.json in Resources */,
|
||||||
85431A8D2905F4F600EE0760 /* Assets.xcassets in Resources */,
|
85431A8D2905F4F600EE0760 /* Assets.xcassets in Resources */,
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct AppDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change this to nuke/remake the database
|
// change this to nuke/remake the database
|
||||||
try db.create(table: "foo4") { t in
|
try db.create(table: "foo2") { t in
|
||||||
t.autoIncrementedPrimaryKey("id")
|
t.autoIncrementedPrimaryKey("id")
|
||||||
t.column("ribbonId", .integer).notNull()
|
t.column("ribbonId", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,6 @@ extension AppDatabase {
|
||||||
{
|
{
|
||||||
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 importJson("acts_export.json", db)
|
|
||||||
_ = try Ribbon(id: 1,
|
_ = try Ribbon(id: 1,
|
||||||
groupId: 1,
|
groupId: 1,
|
||||||
pos: 1,
|
pos: 1,
|
||||||
|
@ -407,7 +406,7 @@ extension AppDatabase {
|
||||||
currentLevel: 0,
|
currentLevel: 0,
|
||||||
minLevel: 0,
|
minLevel: 0,
|
||||||
maxLevel: 0,
|
maxLevel: 0,
|
||||||
title: "Gospel of John",
|
title: "John",
|
||||||
book: "bible.john",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
scrollOffset: 0).inserted(db)
|
scrollOffset: 0).inserted(db)
|
||||||
|
@ -419,7 +418,7 @@ extension AppDatabase {
|
||||||
currentLevel: 0,
|
currentLevel: 0,
|
||||||
minLevel: 0,
|
minLevel: 0,
|
||||||
maxLevel: 0,
|
maxLevel: 0,
|
||||||
title: "Gospel according to Mark",
|
title: "Gospel of Mark and other dogmatic works",
|
||||||
book: "bible.mark",
|
book: "bible.mark",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
scrollOffset: 300).inserted(db)
|
scrollOffset: 300).inserted(db)
|
||||||
|
@ -433,8 +432,8 @@ extension AppDatabase {
|
||||||
currentLevel: 2,
|
currentLevel: 2,
|
||||||
minLevel: 0,
|
minLevel: 0,
|
||||||
maxLevel: 2,
|
maxLevel: 2,
|
||||||
title: "Acts",
|
title: "bottom",
|
||||||
book: "bible.acts",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
scrollOffset: 0).inserted(db)
|
scrollOffset: 0).inserted(db)
|
||||||
|
|
||||||
|
@ -445,8 +444,8 @@ extension AppDatabase {
|
||||||
currentLevel: 2,
|
currentLevel: 2,
|
||||||
minLevel: 0,
|
minLevel: 0,
|
||||||
maxLevel: 2,
|
maxLevel: 2,
|
||||||
title: "Acts",
|
title: "topp",
|
||||||
book: "bible.acts",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
scrollOffset: 0).inserted(db)
|
scrollOffset: 0).inserted(db)
|
||||||
|
|
||||||
|
@ -457,8 +456,8 @@ extension AppDatabase {
|
||||||
currentLevel: 2,
|
currentLevel: 2,
|
||||||
minLevel: 0,
|
minLevel: 0,
|
||||||
maxLevel: 2,
|
maxLevel: 2,
|
||||||
title: "Acts",
|
title: "topp",
|
||||||
book: "bible.acts",
|
book: "bible.john",
|
||||||
scrollId: "1",
|
scrollId: "1",
|
||||||
scrollOffset: 0).inserted(db)
|
scrollOffset: 0).inserted(db)
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,6 @@ var currentOffset: CGFloat?
|
||||||
|
|
||||||
var disableDrop = false
|
var disableDrop = false
|
||||||
|
|
||||||
//TODO: move to globals file
|
|
||||||
let mainBackgroundColor = Color(red: 0.1, green: 0.1, blue: 0.1)
|
|
||||||
let mainTextColor = Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00))
|
|
||||||
let secondBackgroundColor = Color(red: 0.18, green: 0.18, blue: 0.18)
|
|
||||||
|
|
||||||
public extension UserDefaults {
|
public extension UserDefaults {
|
||||||
func optionalInt(forKey defaultName: String) -> Int? {
|
func optionalInt(forKey defaultName: String) -> Int? {
|
||||||
let defaults = self
|
let defaults = self
|
||||||
|
@ -215,7 +210,6 @@ func makeVerseView(seg: SegDenorm) -> some View {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaneConnector: NSObject, ObservableObject {
|
class PaneConnector: NSObject, ObservableObject {
|
||||||
|
|
||||||
var showOverlay: Bool = false
|
var showOverlay: Bool = false
|
||||||
@Published var refresh: Bool = false
|
@Published var refresh: Bool = false
|
||||||
@Published var vertSep = CGFloat(20)
|
@Published var vertSep = CGFloat(20)
|
||||||
|
@ -226,27 +220,9 @@ class PaneConnector: NSObject, ObservableObject {
|
||||||
@Published var scrollOffset = CGFloat()
|
@Published var scrollOffset = CGFloat()
|
||||||
@Published var hasMoved = false
|
@Published var hasMoved = false
|
||||||
var setScrollOffset: CGFloat?
|
var setScrollOffset: CGFloat?
|
||||||
@Published var disableScroll = false
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScrollDelegate: NSObject, ObservableObject, UIScrollViewDelegate {
|
|
||||||
@Published var isScrolling = false
|
|
||||||
|
|
||||||
func scrollViewWillBeginDragging(_: UIScrollView) {
|
|
||||||
print("pop started scroll")
|
|
||||||
isScrolling.toggle()
|
|
||||||
}
|
|
||||||
|
|
||||||
func scrollViewDidEndDragging(_: UIScrollView, willDecelerate _: Bool) {
|
|
||||||
print("pop ended scroll")
|
|
||||||
isScrolling.toggle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
// this is for the whole view swiping
|
// this is for the whole view swiping
|
||||||
@State var mainSwipe = CGSize.zero
|
@State var mainSwipe = CGSize.zero
|
||||||
|
@ -255,7 +231,6 @@ struct ContentView: View {
|
||||||
@State var selection = 0
|
@State var selection = 0
|
||||||
|
|
||||||
@StateObject var paneConnector = PaneConnector()
|
@StateObject var paneConnector = PaneConnector()
|
||||||
@StateObject var scrollDelegate = ScrollDelegate()
|
|
||||||
|
|
||||||
@State var refresh: Bool = false
|
@State var refresh: Bool = false
|
||||||
|
|
||||||
|
@ -268,23 +243,6 @@ struct ContentView: View {
|
||||||
|
|
||||||
@State var dragOffset = CGFloat(0)
|
@State var dragOffset = CGFloat(0)
|
||||||
|
|
||||||
@GestureState var dragGestureActive = CGSize.zero
|
|
||||||
|
|
||||||
enum SwipeStartState {
|
|
||||||
case center
|
|
||||||
case right
|
|
||||||
case left
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SwipeStartDir {
|
|
||||||
case left
|
|
||||||
case right
|
|
||||||
}
|
|
||||||
|
|
||||||
// @State var curSwipeState: SwipeState = .start
|
|
||||||
@State var startSwipeState: SwipeStartState?
|
|
||||||
@State var startSwipeDir: SwipeStartDir?
|
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
||||||
|
@ -293,13 +251,10 @@ struct ContentView: View {
|
||||||
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))
|
||||||
_selectedRibbon = Query(SelectedRibbonRequest())
|
_selectedRibbon = Query(SelectedRibbonRequest())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|
||||||
|
|
||||||
var fontSize = CGFloat(15)
|
var fontSize = CGFloat(15)
|
||||||
var scale = 0.65
|
var scale = 0.65
|
||||||
var height = CGFloat(50)
|
var height = CGFloat(50)
|
||||||
|
@ -352,7 +307,6 @@ struct ContentView: View {
|
||||||
// Top pane
|
// Top pane
|
||||||
|
|
||||||
Pane(paneConnector: paneConnector,
|
Pane(paneConnector: paneConnector,
|
||||||
scrollDelegate: scrollDelegate,
|
|
||||||
selectedRibbon: selectedRibbon,
|
selectedRibbon: selectedRibbon,
|
||||||
width: geometry.size.width - 15,
|
width: geometry.size.width - 15,
|
||||||
height: geometry.size.height + 20,
|
height: geometry.size.height + 20,
|
||||||
|
@ -366,7 +320,7 @@ struct ContentView: View {
|
||||||
// .onChanged { gesture in
|
// .onChanged { gesture in
|
||||||
// paneConnector.vertSep = paneConnector.vertSep - gesture.translation.height
|
// paneConnector.vertSep = paneConnector.vertSep - gesture.translation.height
|
||||||
// }
|
// }
|
||||||
//
|
// )
|
||||||
|
|
||||||
// // Bottom pane
|
// // Bottom pane
|
||||||
// ScrollViewReader { _ in
|
// ScrollViewReader { _ in
|
||||||
|
@ -397,187 +351,85 @@ struct ContentView: View {
|
||||||
}
|
}
|
||||||
.offset(x: 20, y: 0)
|
.offset(x: 20, y: 0)
|
||||||
.offset(x: pulledOut.width)
|
.offset(x: pulledOut.width)
|
||||||
.offset(x: mainSwipe.width)
|
.offset(x: mainSwipe.width, y: mainSwipe.height)
|
||||||
.highPriorityGesture(
|
.gesture(
|
||||||
DragGesture(minimumDistance: 20)
|
DragGesture()
|
||||||
.updating($dragGestureActive) { value, state, _ in
|
.onChanged { gesture in
|
||||||
print("pop here")
|
|
||||||
state = value.translation
|
|
||||||
}
|
|
||||||
.onChanged { value in
|
|
||||||
print("pop changed")
|
|
||||||
// Calculate the offset
|
|
||||||
|
|
||||||
let margin = CGFloat(30)
|
let margin = CGFloat(30)
|
||||||
|
let rightSwipeLimit = CGFloat(110)
|
||||||
|
let leftSwipeLimit = CGFloat(-200)
|
||||||
|
|
||||||
var newOffset = value.translation.width
|
print("mao mainSwipe :\(mainSwipe.width)")
|
||||||
if startSwipeState == nil {
|
print(pulledOut.width)
|
||||||
if pulledOut.width == 0 {
|
|
||||||
startSwipeState = .center
|
|
||||||
} else if pulledOut.width < 0 {
|
var swipeWidth = gesture.translation.width
|
||||||
startSwipeState = .left
|
var swipeActual = gesture.translation.width + pulledOut.width
|
||||||
} else {
|
|
||||||
startSwipeState = .right
|
// swiping right
|
||||||
|
if swipeWidth > 0 {
|
||||||
|
if swipeActual > rightSwipeLimit {
|
||||||
|
swipeWidth = rightSwipeLimit + pow(swipeActual - rightSwipeLimit, 0.8)
|
||||||
}
|
}
|
||||||
|
|
||||||
print("start swipe meow: \(startSwipeState)")
|
mainSwipe.width = swipeWidth - pulledOut.width
|
||||||
}
|
|
||||||
|
|
||||||
if newOffset > 0 {
|
// swiping right
|
||||||
startSwipeDir = .right
|
|
||||||
} else {
|
} else {
|
||||||
startSwipeDir = .left
|
if swipeActual < leftSwipeLimit {
|
||||||
|
swipeWidth = leftSwipeLimit - pow(-swipeActual + leftSwipeLimit, 0.8)
|
||||||
|
}
|
||||||
|
|
||||||
|
mainSwipe.width = swipeWidth - pulledOut.width
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply resistance if out of bounds
|
|
||||||
let maxRight: CGFloat = 140
|
|
||||||
let finalRight: CGFloat = 110
|
|
||||||
let rightDiff = maxRight - finalRight
|
|
||||||
var maxOffsetLeft: CGFloat = -200
|
|
||||||
|
|
||||||
if newOffset > maxRight , pulledOut.width == 0 {
|
|
||||||
// newOffset = maxRight + rubberBandEffect(newOffset)
|
|
||||||
newOffset = maxRight + rubberBandEffect(newOffset - maxRight)
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOffset > rightDiff, pulledOut.width > 0 {
|
|
||||||
newOffset = rightDiff + rubberBandEffect(newOffset - rightDiff)
|
|
||||||
}
|
|
||||||
|
|
||||||
if newOffset < maxOffsetLeft, pulledOut.width == 0 {
|
|
||||||
newOffset = maxOffsetLeft + rubberBandEffect(newOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mainSwipe.width = newOffset
|
|
||||||
|
|
||||||
// dragOffset is what is used to make the text be readable
|
// dragOffset is what is used to make the text be readable
|
||||||
// with the right pane being visible
|
// with the right pane being visible
|
||||||
|
|
||||||
if mainSwipe.width < -margin, pulledOut.width <= 0 {
|
// if mainSwipe.width < -margin && pulledOut.width <= 0 {
|
||||||
|
if mainSwipe.width < -margin && pulledOut.width <= 0 {
|
||||||
dragOffset = margin + mainSwipe.width + pulledOut.width
|
dragOffset = margin + mainSwipe.width + pulledOut.width
|
||||||
}
|
}
|
||||||
|
|
||||||
if mainSwipe.width > 0, pulledOut.width < 0 {
|
if mainSwipe.width > 0 && pulledOut.width < 0 {
|
||||||
dragOffset = margin + mainSwipe.width + pulledOut.width
|
dragOffset = margin + mainSwipe.width + pulledOut.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onEnded { _ in
|
.onEnded { _ in
|
||||||
onDragEnded()
|
let pulledOutRight = CGFloat(-200)
|
||||||
|
let pulledOutLeft = CGFloat(110)
|
||||||
|
let margin = CGFloat(30)
|
||||||
|
|
||||||
|
var setPulledOutWith = CGFloat(0)
|
||||||
|
var setDragOffset = CGFloat(0)
|
||||||
|
|
||||||
|
|
||||||
|
if mainSwipe.width < 0 && pulledOut.width > 0 {
|
||||||
|
setPulledOutWith = CGFloat(0)
|
||||||
|
} else if mainSwipe.width > 0 && pulledOut.width < 0 {
|
||||||
|
setPulledOutWith = CGFloat(0)
|
||||||
|
|
||||||
|
} else if (mainSwipe.width < 0 && pulledOut.width < 0) ||
|
||||||
|
(mainSwipe.width < 0 && pulledOut.width == 0) {
|
||||||
|
setPulledOutWith = pulledOutRight
|
||||||
|
setDragOffset = margin + setPulledOutWith
|
||||||
|
} else if abs(mainSwipe.width + pulledOut.width) > 30 {
|
||||||
|
setPulledOutWith = pulledOutLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
withAnimation(.spring(response: 0.2)) {
|
||||||
|
pulledOut.width = setPulledOutWith
|
||||||
|
dragOffset = setDragOffset
|
||||||
|
mainSwipe = .zero
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.onChange(of: scrollDelegate.isScrolling) { value in
|
|
||||||
print ("pop reset change")
|
|
||||||
// if scrollDelegate.isScrolling == true {
|
|
||||||
Task {
|
|
||||||
mainSwipe.width = 0
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func onDragEnded() {
|
|
||||||
print("pop ended")
|
|
||||||
paneConnector.disableScroll = false
|
|
||||||
var finalSwipe = CGFloat(0)
|
|
||||||
let swipeLeftFinal = CGFloat(-200)
|
|
||||||
let swipeRightFinal = CGFloat(110)
|
|
||||||
|
|
||||||
let margin = CGFloat(30)
|
|
||||||
var setDragOffset = CGFloat(0)
|
|
||||||
|
|
||||||
if startSwipeState == .center {
|
|
||||||
if startSwipeDir == .right {
|
|
||||||
finalSwipe = swipeRightFinal
|
|
||||||
} else {
|
|
||||||
finalSwipe = swipeLeftFinal
|
|
||||||
setDragOffset = margin + swipeLeftFinal
|
|
||||||
}
|
|
||||||
} else if startSwipeState == .right {
|
|
||||||
finalSwipe = .zero
|
|
||||||
|
|
||||||
if startSwipeDir == .left {
|
|
||||||
finalSwipe = .zero
|
|
||||||
} else {
|
|
||||||
finalSwipe = swipeRightFinal
|
|
||||||
}
|
|
||||||
} else if startSwipeState == .left {
|
|
||||||
if startSwipeDir == .left {
|
|
||||||
finalSwipe = swipeLeftFinal
|
|
||||||
setDragOffset = margin + swipeLeftFinal
|
|
||||||
} else {
|
|
||||||
finalSwipe = .zero
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startSwipeState = nil
|
|
||||||
startSwipeDir = nil
|
|
||||||
|
|
||||||
print("foo")
|
|
||||||
|
|
||||||
// if mainSwipe.width < 0 && pulledOut.width > 0 {
|
|
||||||
// setPulledOutWith = CGFloat(0)
|
|
||||||
// } else if mainSwipe.width > 0 && pulledOut.width < 0 {
|
|
||||||
// setPulledOutWith = CGFloat(0)
|
|
||||||
|
|
||||||
// } else if (mainSwipe.width < 0 && pulledOut.width < 0) ||
|
|
||||||
// (mainSwipe.width < 0 && pulledOut.width == 0) {
|
|
||||||
// setPulledOutWith = pulledOutRight
|
|
||||||
// setDragOffset = margin + setPulledOutWith
|
|
||||||
// } else if abs(mainSwipe.width + pulledOut.width) > 30 {
|
|
||||||
// setPulledOutWith = pulledOutLeft
|
|
||||||
// }
|
|
||||||
|
|
||||||
withAnimation(.spring(response: 0.2)) {
|
|
||||||
pulledOut.width = finalSwipe
|
|
||||||
dragOffset = setDragOffset
|
|
||||||
mainSwipe = .zero
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// let hackyPinch = MagnificationGesture(minimumScaleDelta: 0.0)
|
|
||||||
// .onChanged({ delta in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
// .onEnded({ delta in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
|
|
||||||
// let hackyRotation = RotationGesture(minimumAngleDelta: Angle(degrees: 0.0))
|
|
||||||
// .onChanged({ delta in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
// .onEnded({ delta in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
|
|
||||||
// let hackyPress = LongPressGesture(minimumDuration: 0.0, maximumDistance: 0.0)
|
|
||||||
// .onChanged({ _ in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
// .onEnded({ delta in
|
|
||||||
// onDragEnded()
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func handleVisibilityChanged2(_: String, change _: VisibilityChange, tracker _: VisibilityTracker<String>) {}
|
func handleVisibilityChanged2(_: String, change _: VisibilityChange, tracker _: VisibilityTracker<String>) {}
|
||||||
|
|
||||||
|
|
||||||
func rubberBandEffect(_ offset: CGFloat) -> CGFloat {
|
|
||||||
let resistance: CGFloat = 0.05
|
|
||||||
return 6 * log(offset + 1)
|
|
||||||
// return resistance * pow(abs(offset), 1) * (offset < 0 ? -1 : 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func dragCancelled() {
|
|
||||||
print("pop dragCancelled")
|
|
||||||
mainSwipe = .zero
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private let itemFormatter: DateFormatter = {
|
private let itemFormatter: DateFormatter = {
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue