// // TableOfContentsView.swift // Gemini-iOS // // Created by Shadowfacts on 12/20/20. // import SwiftUI import GeminiFormat struct TableOfContentsView: View { private let entries: [Entry] private let close: (Int?) -> Void init(document: Document, close: @escaping (Int?) -> Void) { let toc = TableOfContents(document: document) self.entries = toc.entries.flatMap { TableOfContentsView.flattenToCEntry($0) } self.close = close } private static func flattenToCEntry(_ e: TableOfContents.Entry, depth: Int = 0) -> [Entry] { guard case let .heading(text, level: _) = e.line else { fatalError() } var entries = e.children.flatMap { flattenToCEntry($0, depth: depth + 1) } entries.insert(Entry(title: text, lineIndex: e.lineIndex, depth: depth), at: 0) return entries } var body: some View { NavigationView { List(Array(entries.enumerated()), id: \.0) { (a) in Button { close(a.1.lineIndex) } label: { HStack(spacing: 0) { Spacer() .frame(width: CGFloat(a.1.depth * 25)) Text(verbatim: a.1.title) } } } .listStyle(PlainListStyle()) .navigationBarTitle("Table of Contents", displayMode: .inline) .navigationBarItems(trailing: Button("Done", action: { close(nil) })) } } } extension TableOfContentsView { struct Entry { let title: String let lineIndex: Int let depth: Int } } struct TableOfContentsView_Previews: PreviewProvider { static var previews: some View { TableOfContentsView(document: Document(url: URL(string: "gemini://example.com")!, lines: [])) { (_) in } } }