SPB Git

spb/prisme Public MIT

Navigateur iOS intelligent — chaque page comprise localement avant d'être affichée. SwiftUI · WebKit · Foundation Models, 100% on-device.

Swift 96.7% JavaScript 3.3%
1.9 KB · 65 lines swift
Raw Blame History
1//2//  Tab.swift3//  Prisme4//5//  Author: Simon-Pierre Boucher <contact@spboucher.ai>6//78import Foundation9import Observation1011/// What Prisme understood of the current page, deterministically and12/// instantly — the visible proof that the browser read the page. The13/// digest enriches it when the local model delivers.14struct PageInsight: Equatable, Sendable {15    let url: URL16    let approxWords: Int17    let sectionCount: Int1819    var readingMinutes: Int { max(1, approxWords / 200) }20}2122/// A browsing tab. Holds no `WKWebView` of its own — web views live in the23/// pool (CLAUDE.md §8) and are attached only while the tab is on screen.24/// Page state survives detachment through `interactionState`, which25/// preserves the back/forward history and scroll position.26@MainActor27@Observable28final class Tab: Identifiable {29    let id = UUID()30    let containerID: IdentityContainer.ID3132    /// URL to load when the tab first gets a web view. Nil = start page.33    var initialURL: URL?3435    /// Live navigation state and commands, bridged from the engine.36    let page = WebPageProxy()3738    /// Opaque WebKit session state, captured when the tab goes off screen.39    @ObservationIgnored var interactionState: Any?4041    /// Set after each settled load; drives the understanding strip.42    var insight: PageInsight?43    /// The user dismissed the strip for the current page.44    var insightDismissed = false4546    let createdAt = Date()47    var lastActivatedAt = Date()4849    init(initialURL: URL?, containerID: IdentityContainer.ID) {50        self.initialURL = initialURL51        self.containerID = containerID52    }5354    var displayTitle: String {55        if !page.title.isEmpty { return page.title }56        if let host = (page.url ?? initialURL)?.host() { return host }57        return "Nouvel onglet"58    }5960    /// True while the tab has nothing to render — show the start page.61    var isBlank: Bool {62        page.url == nil && initialURL == nil && interactionState == nil63    }64}65