gloss-ios/gloss/ContentView.swift

473 lines
17 KiB
Swift

//
// ContentView.swift
// gloss
//
// Created by Saint on 10/23/22.
//
import SwiftUI
import GRDB
import GRDBQuery
import Introspect
import os
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
// 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
}
}
struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.frame(width: 160)
.contentShape(Rectangle())
.foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.black)
.background(configuration.isPressed ? Color.purple.opacity(0.5) : Color.purple)
.listRowBackground(configuration.isPressed ? Color.blue.opacity(0.5) : Color.black)
}
}
struct SwitchButton : View {
var ribbon: Ribbon
// var selectedRibbon: SelectedRibbon
// @Binding var book : String
@Binding var scrollDelegate : ScrollViewHandler
@Binding var scrollView : UIScrollView?
@Binding var scrollUpdate : Bool
@Environment(\.appDatabase) private var appDatabase
@Query(SelectedRibbonRequest()) private var sr: [Ribbon]
@State var saveOffset = CGFloat()
var body: some View {
// ForEach(sr) { selectedRibbon in
Button(String(sr[0].id!) + " " + String(ribbon.id!) + " " + String(ribbon.scrollOffset),
// Button("meow",
action: {
Task {
var selectedRibbon = sr[0]
Print("SELECTED RIBBON", selectedRibbon)
var saveScrollOffset = scrollDelegate.scrollOffset
var editedRibbon = selectedRibbon
Print("ribbon offset saved")
scrollUpdate = true
if (selectedRibbon.id != ribbon.id!) {
Print("switching")
// book = ribbon.book
Print("applying offset", CGFloat(ribbon.scrollOffset))
// scrollOffset = CGFloat(ribbon.scrollOffset)
// scrollDelegate.scrollOffset = CGFloat(ribbon.scrollOffset)
scrollDelegate.scrollOffset = CGFloat(ribbon.scrollOffset)
// scrollView!.contentOffset.y = CGFloat(ribbon.scrollOffset)
// scrollOffset = CGFloat(1500)
var updateSelectRibbon = SelectedRibbon(id: Int64(1), ribbonId: ribbon.id!)
Print("Savingg")
Print(updateSelectRibbon)
do {
_ = try await appDatabase.saveSelectedRibbon(&updateSelectRibbon)
} catch {
Print("something wrong")
}
}
editedRibbon.scrollOffset = Int(saveScrollOffset)
_ = try await appDatabase.saveRibbon(&editedRibbon)
_ = Print("editedRibbon", editedRibbon)
_ = Print("ribbon", ribbon)
}
}
)
.buttonStyle(BlueButtonStyle())
}
// }
}
class ScrollViewHandler: NSObject {
public var scrollOffset = CGFloat(10)
}
extension ScrollViewHandler: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollOffset = CGFloat(scrollView.contentOffset.y)
// print("delegate", scrollView.contentOffset.y)
// print("delegate prop", self.scrollOffset)
}
}
class Verse: NSObject, Codable {
var body: String
var verse: Int
}
func makeVerseView(seg: SegDenorm) -> some View {
var retView = Text("")
var segSplit = seg.body.components(separatedBy: ";;")
// Text(segSplit[0].body)
// .id(seg.id)
// VStack {
// ForEach(segSplit.indices) { i in
let decoder = JSONDecoder()
segSplit.enumerated().forEach({ (index, item) in
let verse = try! decoder.decode(Verse.self, from: item.data(using: .utf8)!)
retView = retView + Text(String(verse.verse))
// Text(seg.body)
// .contentShape(Rectangle())
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
.baselineOffset(6.0)
.foregroundColor(Color.white)
retView = retView + Text(verse.body)
// .frame(maxWidth: .infinity, alignment: .leading)
// .contentShape(Rectangle())
.foregroundColor(Color.white)
.font(Font.custom("AveriaSerifLibre-Regular", size: 30))
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "body" + String(i))
// .id(seg.id)
//.onTapGesture {
// selectedLine = seg.id
// //Print(selectedLine)
//}
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "verse" + String(i))
// .id(seg.id)
//.onTapGesture {
// selectedLine = seg.id
// //Print(selectedLine)
//}
})
// }
return retView
}
private struct SegRow: View {
var seg: SegDenorm
var body: some View {
// makeVerseView(seg: seg)
var retView = Text("")
var segSplit = seg.body.components(separatedBy: ";;")
let decoder = JSONDecoder()
// Text(segSplit[0].body)
// .id(seg.id)
// VStack {
// ForEach(segSplit.indices) { i in
segSplit.enumerated().forEach({ (index, item) in
let verse = try! decoder.decode(Verse.self, from: item.data(using: .utf8)!)
retView = retView + Text(String(verse.verse))
// Text(seg.body)
// .contentShape(Rectangle())
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
.baselineOffset(6.0)
.foregroundColor(Color.white)
retView = retView + Text(verse.body)
// .frame(maxWidth: .infinity, alignment: .leading)
// .contentShape(Rectangle())
.foregroundColor(Color.white)
.font(Font.custom("AveriaSerifLibre-Regular", size: 30))
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "body" + String(i))
// .id(seg.id)
//.onTapGesture {
// selectedLine = seg.id
// //Print(selectedLine)
//}
// .listRowBackground(Color(red: 0.2, green: 0.8, blue: 0.2))
// .listRowInsets(EdgeInsets())
// .padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
// .listRowSeparator(.hidden)
// .id(String(seg.id) + "verse" + String(i))
// .id(seg.id)
//.onTapGesture {
// selectedLine = seg.id
// //Print(selectedLine)
//}
})
// }
return retView
}
}
struct ContentView: View {
@State var viewState = CGSize.zero
@State var pulledOut = CGSize.zero
@State var taskTitle : String = "FIRST DOGGG"
@State var curBook : String = "Matthew"
// @State var scrollTo1 : Int64?
@State var selectedLine : Int64?
@State var scrollOffset = CGFloat()
@State var thisScrollView : UIScrollView?
@State var scrollUpdate = false
@State var initLoad = false
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
@State var scrollDelegate: ScrollViewHandler
// @State var scrollDelegate = ScrollViewHandler()
// @State var selectedRibbon: Ribbon!,
// @State var selectedRibbon: Ribbon!
// @State var selectedRibbonId = Int64(UserDefaults.standard.optionalInt(forKey: "selectedRibbonId") ?? 1)
// ribbon
@Query(SelectedRibbonRequest()) private var selectedRibbon: [Ribbon]
@State var endedDrag = true
@State var readOffset = CGPoint()
@State var refresh: Bool = false
@Query(RibbonRequest()) private var ribbons: [Ribbon]
// @Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1))) private var selectedRibbon: [Ribbon]
init() {
UITableView.appearance().backgroundColor = UIColor(Color(red: 0.2, green: 0.2, blue: 0.2))
// _selectedRibbon = Query(RibbonRequest(id: Int64(UserDefaults.standard.optionalInt(forKey: "lastRibbonId") ?? 1)))
self._scrollDelegate = State(initialValue: ScrollViewHandler())
Print("initalizing")
}
var body: some View {
Print("rendering")
GeometryReader { geometry in
ZStack{
VStack{
VStack{
// // Star(corners: 6, smoothness: 0.85, initAngle:-CGFloat.pi / 4)
// .fill(.blue)
// .frame(width: 200, height: 200)
// .background(Color.gray.opacity(0.0))
// Star(corners: 6, smoothness: 0.85, initAngle:-CGFloat.pi / 2)
// .fill(.blue)
// .frame(width: 200, height: 200)
// .background(Color.gray.opacity(0.0))
// MyCustomShape().frame(width: 10, height: 10)
}
Text("MRK")
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
.foregroundColor(Color.white)
.background(Color(red: 0.3, green: 0.3, blue: 0.3))
.overlay( MyCustomShape().frame(width: 120, height: 100).foregroundColor(.white))
.frame(width: 120, height: 120)
Text("MTW")
.font(Font.custom("AveriaSerifLibre-Regular", size: 20))
.foregroundColor(Color.white)
.overlay( MyCustomShape().frame(width: 120, height: 100))
.frame(width: 120, height: 120)
// Text("cat" + String(selectedRibbon[0].id!))
ForEach(ribbons) { ribbon in
//ForEach(selectedRibbon) { sr in
SwitchButton(ribbon: ribbon,
scrollDelegate: $scrollDelegate,
scrollView:$thisScrollView,
scrollUpdate:$scrollUpdate
)
.buttonStyle(BlueButtonStyle())
//}
}
}
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading)
.background(Color(red: 0.1, green: 0.1, blue: 0.1))
ScrollViewReader { proxy in
VisibilityTrackingScrollView(action: handleVisibilityChanged) {
// ScrollView {
LazyVStack {
Text(refresh ? "Selected" : "not Selected")
Button("Jump to #8") {
proxy.scrollTo("5", anchor: .top)
DispatchQueue.main.async {
scrollOffset = 340
refresh.toggle()
}
}
ForEach(segs) { seg in
SegRow(seg: seg)
.id("\(seg.id)")
.padding(EdgeInsets(top: 10, leading: 20, bottom: 40, trailing: 20))
.trackVisibility(id: "\(seg.id)")
// .onChange(of: geometry.frame(in: .named("scrollView"))) { imageRect in
// Print(imageRect)
// Print(outerProxy)
// if isInView(innerRect: imageRect, isIn: outerProxy) {
// visibleIndex.insert(item)
// } else {
// visibleIndex.remove(item)
// }
// }
}
}
.background(Color(red: 0.2, green: 0.2, blue: 0.2))
}
.introspectScrollView { scrollView in
// Print("introspect")
scrollView.delegate = scrollDelegate
Print("Scroll delegate offset", scrollDelegate.scrollOffset)
if (scrollOffset != 0) {
Print("GOT THEHREHREH")
scrollView.contentOffset.y = scrollView.contentOffset.y + scrollOffset
DispatchQueue.main.async { scrollOffset = 0 }
}
if (thisScrollView == nil) {
Print("init scroll")
thisScrollView = scrollView
scrollView.contentOffset.y = CGFloat(selectedRibbon[0].scrollOffset)
}
}
.listStyle(PlainListStyle())
}
.background(Color(red: 0.2, green: 0.2, blue: 0.2))
.frame(width: geometry.size.width - 50)
.offset(x:30 , y:0)
.offset(x: pulledOut.width)
.offset(x: viewState.width, y: viewState.height)
.gesture(
DragGesture()
.onChanged { gesture in
if (endedDrag) {
endedDrag = false
scrollOffset = readOffset.y - 20
_ = Print("meow")
}
// logger.error("hello222")
// NSLog("hellooo")
//Print(viewState.width)
if (abs(gesture.translation.width) > 20) {
viewState.width = gesture.translation.width
}
//offset.y = gesture.translation.width
// logger.log("hello")
}
.onEnded { _ in
endedDrag = true
var pulledOutWidth = CGFloat(0)
if (viewState.width < 0) {
pulledOutWidth = CGFloat(0)
}
else if abs(viewState.width + pulledOut.width ) > 30 {
pulledOutWidth = CGFloat(200)
}
withAnimation(.spring(response: 0.2)) {
pulledOut.width = pulledOutWidth
viewState = .zero
}
}
)
}
}
}
func handleVisibilityChanged(_ id: String, change: VisibilityChange, tracker: VisibilityTracker<String>) {
switch change {
case .shown: print("\(id) shown")
case .hidden: print("\(id) hidden")
}
print(tracker.visibleViews)
}
}
private let itemFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .medium
return formatter
}()
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
ContentView().environment(\.appDatabase, .random())
}
}
extension View {
func Print(_ vars: Any...) -> some View {
for v in vars { print(v) }
return EmptyView()
}
}