BrowserFunctions.swift (3381B)
1 // 2 // BrowserFunctions.swift 3 // Gemenon 4 // 5 // Created by figbert on 9/6/22. 6 // 7 8 import Foundation 9 import SwiftGemini 10 import SwiftGemtext 11 12 @MainActor 13 class BrowserData: ObservableObject { 14 @Published var tab = Tab() 15 @Published var loading = false 16 17 @Published var bookmarks: [Bookmark] = [] 18 19 @Published var currentView: GemenonView = .Capsule 20 @Published var views: [GemenonView] = [.Capsule, .History, .Bookmarks] 21 22 @Published var parser = SwiftGemtext.Gemtext() 23 @Published var engine = SwiftGemini.GeminiRequestor() 24 } 25 26 extension BrowserData { 27 func reload() async { 28 await self.openURL(self.tab.url!) 29 } 30 func goToStartPage() { 31 guard !self.tab.home else { return } 32 self.tab = Tab(prev: self.tab) 33 } 34 func goBack() async { 35 guard self.tab.prev != nil else { return } 36 if self.tab.prev?.response == nil { 37 self.loading = true 38 self.tab.prev?.response = try! await self.engine.request((self.tab.prev?.url)!) 39 self.loading = false 40 } 41 self.tab = self.tab.prev! 42 self.tab.next?.next?.next?.response = nil 43 } 44 func goForward() async { 45 guard self.tab.next != nil else { return } 46 if self.tab.next?.response == nil { 47 self.loading = true 48 self.tab.next?.response = try! await self.engine.request((self.tab.next?.url)!) 49 self.loading = false 50 } 51 self.tab = self.tab.next! 52 self.tab.prev?.prev?.prev?.response = nil 53 } 54 } 55 56 extension BrowserData { 57 func hasURLInBookmarks(_ url: URL) -> Bool { 58 guard !self.bookmarks.isEmpty else { return false } 59 return bookmarks.contains(where: { bookmark in 60 bookmark.url == url 61 }) 62 } 63 func addURLToBookmarks(_ url: URL, label: String, timestamp: Date) { 64 guard !self.hasURLInBookmarks(url) else { return } 65 self.bookmarks.append(Bookmark(url: url, name: label, timestamp: timestamp)) 66 } 67 func dropURLFromBookmarks(_ url: URL) { 68 guard self.hasURLInBookmarks(url) else { return } 69 self.bookmarks.removeAll(where: { bookmark in 70 bookmark.url == url 71 }) 72 } 73 } 74 75 extension BrowserData { 76 func openURL(_ url: URL) async { 77 self.loading = true 78 let response = try! await self.engine.request(url) 79 self.tab = Tab(url, prev: self.tab, response: response) 80 self.tab.prev?.next = self.tab 81 self.tab.prev?.prev?.prev?.response = nil 82 self.currentView = .Capsule 83 self.loading = false 84 } 85 } 86 87 class Tab: Identifiable { 88 let id = UUID() 89 let timestamp = Date.now 90 91 var home: Bool 92 var urlBar: String 93 var url: URL? 94 var next: Tab? 95 var prev: Tab? 96 var response: SwiftGemini.GeminiResponse? 97 98 init() { 99 self.home = true 100 self.urlBar = "" 101 } 102 init(prev: Tab) { 103 self.home = true 104 self.urlBar = "" 105 self.prev = prev 106 } 107 init(_ url: URL, prev: Tab, response: SwiftGemini.GeminiResponse) { 108 self.home = false 109 self.url = url 110 self.urlBar = url.absoluteString 111 self.prev = prev 112 self.response = response 113 } 114 } 115 116 struct Bookmark: Identifiable { 117 let id = UUID() 118 119 let url: URL 120 let name: String 121 let timestamp: Date 122 } 123 124 enum GemenonView { 125 case Capsule 126 case History 127 case Bookmarks 128 }