Gemini/Gemini-iOS/TableOfContentsView.swift

66 lines
1.9 KiB
Swift
Raw Normal View History

2020-12-20 18:45:22 +00:00
//
// 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(leading: Button("Cancel", action: {
2020-12-20 18:45:22 +00:00
close(nil)
}))
}
2020-12-20 19:09:18 +00:00
.navigationViewStyle(StackNavigationViewStyle())
2020-12-20 18:45:22 +00:00
}
}
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 }
}
}