aboutsummaryrefslogtreecommitdiff
path: root/QuickLook/PreviewViewController.swift
blob: 8a3467f580103207b9c2a7dd6bde2574e4156333 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import Cocoa
import Quartz
import SwiftUI
import WmapParser

class PreviewViewController: NSViewController, QLPreviewingController {

  override var nibName: NSNib.Name? {
    return NSNib.Name("PreviewViewController")
  }

  override func loadView() {
    super.loadView()
  }

  func preparePreviewOfFile(at url: URL) async throws {
    // Read the .wmap file content
    let content = try String(contentsOf: url, encoding: .utf8)

    // Get the user's preview style preference from shared UserDefaults
    let sharedDefaults =
      UserDefaults(suiteName: "group.systems.tranquil.Map") ?? UserDefaults.standard
    let previewStyleString =
      sharedDefaults.string(forKey: "quickLookPreviewStyle") ?? QuickLookPreviewStyle.map.rawValue
    let previewStyle = QuickLookPreviewStyle(rawValue: previewStyleString) ?? .map

    await MainActor.run {
      // Clear any existing subviews and force cleanup
      for subview in view.subviews {
        if let hostingView = subview as? NSHostingView<AnyView> {
          hostingView.rootView = AnyView(EmptyView())
        }
        subview.removeFromSuperview()
      }

      // Force memory cleanup
      autoreleasepool {
        let previewContent: AnyView

        switch previewStyle {
        case .plainText:
          previewContent = AnyView(createPlainTextView(content: content))

        case .highlightedText:
          previewContent = AnyView(
            createHighlightedTextView(content: content))

        case .map:
          let parsedMap = WmapParser.parse(content)
          previewContent = AnyView(MapPreviewView(parsedMap: parsedMap))
        }

        let hostingView = NSHostingView(rootView: previewContent)

        hostingView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(hostingView)

        NSLayoutConstraint.activate([
          hostingView.topAnchor.constraint(equalTo: view.topAnchor),
          hostingView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
          hostingView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
          hostingView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])

        view.needsLayout = true
        view.layoutSubtreeIfNeeded()
      }  // autoreleasepool
    }
  }

  private func createPlainTextView(content: String) -> some View {
    ScrollView([.horizontal, .vertical]) {
      Text(content)
        .font(.monospaced(.body)())
        .multilineTextAlignment(.leading)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
        .padding()
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color.white)
  }

  private func createHighlightedTextView(content: String) -> some View {
    QuickLookTextEditor(content: content)
      .frame(maxWidth: .infinity, maxHeight: .infinity)
      .background(Color.white)
  }

  deinit {
    // Cleanup when view controller is deallocated
    for subview in view.subviews {
      if let hostingView = subview as? NSHostingView<AnyView> {
        hostingView.rootView = AnyView(EmptyView())
      }
      subview.removeFromSuperview()
    }
  }
}