gemenon

[ACTIVE] The Safari of the Gemini ecosystem
git clone git://git.figbert.com/gemenon.git
Log | Files | Refs

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 }