Skip to content

Commit

Permalink
Correctly view non-text files in single file window and Open Quickly (#…
Browse files Browse the repository at this point in the history
…1820)

* add `updateStatusBarInfo` view modifier

* fix QuickLook previews in single file window

* change `fileURL` type to `NSURL` in `AnyFileView`

* fix QuickLook previews in Open Quickly

Use `dismantleNSView` in `AnyFileView` to prevent crashes when using Open Quickly.
What crashes?
1. When using Open Quickly without the workaround in `AnyFileView`, search for a media file (.png, .gif, .mp4, etc)
2. Press escape to close Open Quickly
3. re-open Open Quickly. The media preview is gone
4. Attempt to navigate upwards or downwards using the arrow buttons
5. A crash occurs (QuickLook is attempting to reuse an already closed preview)

* add assertionFailure in `CodeEditWindowController.openQuickly` for when an editorManager or statusBarViewModel is unavailable

* make `UpdateStatusBarInfo.fileURL` an optional

* remove the need to pass environment objects to `NonTextFileView`

This also prevents Open Quickly previews from updating the status bar

* rename function parameters in `UpdateStatusBarInfo` view modifier

* remove `updateStatusBarInfo` view extension

* remove guard in `CodeEditWindowController.openQuickly`

editorManager and statusBarViewModel environment objects are not used in Open Quickly anymore

* merge #1822 fix into this branch

allow files with a utType that is neither image nor PDF to be previewed (#1822)
  • Loading branch information
plbstl authored Aug 21, 2024
1 parent 96c3165 commit 2e4bec8
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 51 deletions.
15 changes: 11 additions & 4 deletions CodeEdit/Features/Editor/Views/AnyFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,27 @@ import QuickLookUI
struct AnyFileView: NSViewRepresentable {

/// URL of the file to preview. You can pass in any file type.
private let fileURL: URL
private let fileURL: NSURL

init(_ fileURL: URL) {
self.fileURL = fileURL
self.fileURL = fileURL as NSURL
}

func makeNSView(context: Context) -> QLPreviewView {
let qlPreviewView = QLPreviewView()
qlPreviewView.previewItem = fileURL as any QLPreviewItem
qlPreviewView.previewItem = fileURL
qlPreviewView.shouldCloseWithWindow = false // Temp work around for something more reasonable.
return qlPreviewView
}

func updateNSView(_ qlPreviewView: QLPreviewView, context: Context) {
qlPreviewView.previewItem = fileURL as any QLPreviewItem
qlPreviewView.previewItem = fileURL
}

// Temp work around for something more reasonable.
// Open quickly should empty the results (but cache the query) when closed,
// and then re-search or recompute the results when re-opened.
static func dismantleNSView(_ qlPreviewView: QLPreviewView, coordinator: ()) {
qlPreviewView.close()
}
}
4 changes: 0 additions & 4 deletions CodeEdit/Features/Editor/Views/CodeFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ struct CodeFileView: View {
@Environment(\.colorScheme)
private var colorScheme

@EnvironmentObject private var editorManager: EditorManager

@ObservedObject private var themeModel: ThemeModel = .shared

private var cancellables = Set<AnyCancellable>()
Expand Down Expand Up @@ -105,8 +103,6 @@ struct CodeFileView: View {
@Environment(\.edgeInsets)
private var edgeInsets

@EnvironmentObject private var editor: Editor

var body: some View {
CodeEditSourceEditor(
codeFile.content ?? NSTextStorage(),
Expand Down
6 changes: 6 additions & 0 deletions CodeEdit/Features/Editor/Views/EditorAreaFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct EditorAreaFileView: View {

@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var editor: Editor
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

@Environment(\.edgeInsets)
private var edgeInsets
Expand All @@ -32,6 +33,11 @@ struct EditorAreaFileView: View {
NonTextFileView(fileDocument: document)
.padding(.top, edgeInsets.top - 1.74) // Use the magic number to fine-tune its appearance.
.padding(.bottom, StatusBarView.height + 1.26) // Use the magic number to fine-tune its appearance.
.modifier(UpdateStatusBarInfo(with: document.fileURL))
.onDisappear {
statusBarViewModel.dimensions = nil
statusBarViewModel.fileSize = nil
}
}

} else {
Expand Down
13 changes: 1 addition & 12 deletions CodeEdit/Features/Editor/Views/NonTextFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,26 @@ struct NonTextFileView: View {
/// The file document you wish to open.
let fileDocument: CodeFileDocument

@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel

var body: some View {
Group {
if let fileURL = fileDocument.fileURL {
if let utType = fileDocument.utType {

if let utType = fileDocument.utType {
if utType.conforms(to: .image) {
ImageFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))
} else if utType.conforms(to: .pdf) {
PDFFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))
} else {
AnyFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))
}
} else {
AnyFileView(fileURL)
.modifier(UpdateStatusBarInfo(withURL: fileURL))
}
} else {
ZStack {
Text("Cannot retrieve URL to the file you opened.")
}
}
}
.onDisappear {
statusBarViewModel.dimensions = nil
statusBarViewModel.fileSize = nil
}
}
}
17 changes: 4 additions & 13 deletions CodeEdit/Features/Editor/Views/WindowCodeFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,11 @@ import SwiftUI
struct WindowCodeFileView: View {
var codeFile: CodeFileDocument

@State var hasAppeared = false
@FocusState var focused: Bool

var body: some View {
Group {
if !hasAppeared {
Color.clear.onAppear {
hasAppeared = true
focused = true
}
} else {
CodeFileView(codeFile: codeFile)
.focused($focused)
}
if let utType = codeFile.utType, utType.conforms(to: .text) {
CodeFileView(codeFile: codeFile)
} else {
NonTextFileView(fileDocument: codeFile)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct OpenQuicklyPreviewView: View {
let doc = try? CodeFileDocument(
for: item.url,
withContentsOf: item.url,
ofType: "public.source-code"
ofType: item.contentType?.identifier ?? "public.source-code"
)
self._document = .init(wrappedValue: doc ?? .init())
}
Expand Down
42 changes: 25 additions & 17 deletions CodeEdit/Features/StatusBar/ViewModifiers/UpdateStatusBarInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import SwiftUI
struct UpdateStatusBarInfo: ViewModifier {

/// The URL of the file to compute information from.
let withURL: URL
let fileURL: URL?

init(with fileURL: URL?) {
self.fileURL = fileURL
}

@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var statusBarViewModel: StatusBarViewModel
Expand All @@ -27,17 +31,17 @@ struct UpdateStatusBarInfo: ViewModifier {
}

/// Compute information that can be used to update properties in ``StatusBarFileInfoView``.
/// - Parameter url: URL of the file to compute information from.
/// - Parameter with fileURL: URL of the file to compute information from.
/// - Returns: The file size and its image dimensions (if any).
private func computeStatusBarInfo(url: URL) -> ComputedStatusBarInfo? {
guard let resourceValues = try? url.resourceValues(forKeys: [.contentTypeKey, .fileSizeKey]),
private func computeStatusBarInfo(with fileURL: URL) -> ComputedStatusBarInfo? {
guard let resourceValues = try? fileURL.resourceValues(forKeys: [.contentTypeKey, .fileSizeKey]),
let contentType = resourceValues.contentType,
let fileSize = resourceValues.fileSize
else {
return nil
}

if contentType.conforms(to: .image), let imageReps = NSImage(contentsOf: url)?.representations.first {
if contentType.conforms(to: .image), let imageReps = NSImage(contentsOf: fileURL)?.representations.first {
let dimensions = ImageDimensions(width: imageReps.pixelsWide, height: imageReps.pixelsHigh)
return ComputedStatusBarInfo(fileSize: fileSize, dimensions: dimensions)
} else { // non-image file
Expand All @@ -46,18 +50,22 @@ struct UpdateStatusBarInfo: ViewModifier {
}

func body(content: Content) -> some View {
content
.onAppear {
let statusBarInfo = computeStatusBarInfo(url: withURL)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
.onChange(of: editorManager.activeEditor.selectedTab) { newTab in
guard let newTab else { return }
let statusBarInfo = computeStatusBarInfo(url: newTab.file.url)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
if let fileURL {
content
.onAppear {
let statusBarInfo = computeStatusBarInfo(with: fileURL)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
.onChange(of: editorManager.activeEditor.selectedTab) { newTab in
guard let newTab else { return }
let statusBarInfo = computeStatusBarInfo(with: newTab.file.url)
statusBarViewModel.fileSize = statusBarInfo?.fileSize
statusBarViewModel.dimensions = statusBarInfo?.dimensions
}
} else {
content
}
}

}

0 comments on commit 2e4bec8

Please sign in to comment.