Repository navigation
Fix open unsupported Documents, support for open image files #679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5f07476
1e1a4cd
61b8ec8
2d11854
650b44b
64e9610
2e08efa
1e5ecb3
f5ac190
6e6e4f9
88aa2e1
32f25d9
0246c85
a79c57b
228d4e4
f46ea19
3c46eef
04f65c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import WorkspaceClient | |
| import StatusBar | ||
| import Breadcrumbs | ||
| import AppPreferences | ||
| import UniformTypeIdentifiers | ||
|
|
||
| struct WorkspaceCodeFileView: View { | ||
| var windowController: NSWindowController | ||
|
|
@@ -30,26 +31,67 @@ struct WorkspaceCodeFileView: View { | |
| } | ||
| return file.tabID == workspace.selectionState.selectedId | ||
| }) { | ||
| if let codeFile = workspace.selectionState.openedCodeFiles[item] { | ||
| CodeFileView(codeFile: codeFile) | ||
| .safeAreaInset(edge: .top, spacing: 0) { | ||
| VStack(spacing: 0) { | ||
| BreadcrumbsView(file: item, tappedOpenFile: workspace.openTab(item:)) | ||
| Divider() | ||
| } | ||
| } | ||
| } else { | ||
| Text("No Editor") | ||
| .font(.system(size: 17)) | ||
| .foregroundColor(.secondary) | ||
| .frame(minHeight: 0) | ||
| .clipped() | ||
| if let fileItem = workspace.selectionState.openedCodeFiles[item] { | ||
| if fileItem.typeOfFile == .text { | ||
| codeFileView(fileItem, for: item) | ||
| } else { | ||
| otherFileView(fileItem, for: item) | ||
| } | ||
| } | ||
| } else { | ||
| Text("No Editor") | ||
| .font(.system(size: 17)) | ||
| .foregroundColor(.secondary) | ||
| .frame(minHeight: 0) | ||
| .clipped() | ||
| } | ||
| } | ||
| .frame(maxWidth: .infinity, maxHeight: .infinity) | ||
| } | ||
|
|
||
| @ViewBuilder | ||
| private func codeFileView( | ||
| _ codeFile: CodeFileDocument, | ||
| for item: WorkspaceClient.FileItem | ||
| ) -> some View { | ||
| CodeFileView(codeFile: codeFile) | ||
| .safeAreaInset(edge: .top, spacing: 0) { | ||
| VStack(spacing: 0) { | ||
| BreadcrumbsView(file: item, tappedOpenFile: workspace.openTab(item:)) | ||
| Divider() | ||
| } | ||
| } | ||
|
Comment on lines
+57
to
+63
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed that in the other two methods, instead of I'm wondering if we can make those three views more consistent.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fully agree with you, and I think we should use only
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shibotong @Matejkob We need to use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you @austincondiff I have changed these views to |
||
| } | ||
|
|
||
| @ViewBuilder | ||
| private func otherFileView( | ||
| _ otherFile: CodeFileDocument, | ||
| for item: WorkspaceClient.FileItem | ||
| ) -> some View { | ||
| ZStack { | ||
| if let url = otherFile.previewItemURL, | ||
| let image = NSImage(contentsOf: url), | ||
| otherFile.typeOfFile == .image { | ||
| GeometryReader { proxy in | ||
| if image.size.width > proxy.size.width || image.size.height > proxy.size.height { | ||
| OtherFileView(otherFile) | ||
| } else { | ||
| OtherFileView(otherFile) | ||
| .frame(width: image.size.width, height: image.size.height) | ||
| .position(x: proxy.frame(in: .local).midX, y: proxy.frame(in: .local).midY) | ||
| } | ||
| } | ||
| } else { | ||
| OtherFileView(otherFile) | ||
| } | ||
| }.safeAreaInset(edge: .top, spacing: 0) { | ||
| VStack(spacing: 0) { | ||
| BreadcrumbsView(file: item, tappedOpenFile: workspace.openTab(item:)) | ||
| Divider() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| var body: some View { | ||
| codeView | ||
| .frame(maxWidth: .infinity, maxHeight: .infinity) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,17 +8,51 @@ | |
| import AppKit | ||
| import Foundation | ||
| import SwiftUI | ||
| import UniformTypeIdentifiers | ||
| import QuickLookUI | ||
|
|
||
| public enum CodeFileError: Error { | ||
| case failedToDecode | ||
| case failedToEncode | ||
| case fileTypeError | ||
| } | ||
|
|
||
| @objc(CodeFileDocument) | ||
| public final class CodeFileDocument: NSDocument, ObservableObject { | ||
| public final class CodeFileDocument: NSDocument, ObservableObject, QLPreviewItem { | ||
|
|
||
| @Published | ||
| var content = "" | ||
|
|
||
| /* | ||
| This is the main type of the document. | ||
| For example, if the file is end with '.png', it will be an image, | ||
| if the file is end with '.py', it will be a text file. | ||
| If text content is not empty, return text | ||
| If its neither image or text, this could be nil. | ||
| */ | ||
| public var typeOfFile: UTType? { | ||
| if !self.content.isEmpty { | ||
| return UTType.text | ||
| } | ||
| guard let fileType = fileType, let type = UTType(filenameExtension: fileType) else { | ||
| return nil | ||
| } | ||
| if type.conforms(to: UTType.image) { | ||
| return UTType.image | ||
| } | ||
| if type.conforms(to: UTType.text) { | ||
| return UTType.text | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| /* | ||
| This is the QLPreviewItemURL | ||
| */ | ||
| public var previewItemURL: URL? { | ||
| fileURL | ||
| } | ||
|
|
||
| // MARK: - NSDocument | ||
|
|
||
| override public class var autosavesInPlace: Bool { | ||
|
|
@@ -44,8 +78,10 @@ public final class CodeFileDocument: NSDocument, ObservableObject { | |
| return data | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
|
|
||
| /// This fuction is used for decoding files. | ||
| /// It should not throw error as unsupported files can still be opened by QLPreviewView. | ||
| override public func read(from data: Data, ofType _: String) throws { | ||
| guard let content = String(data: data, encoding: .utf8) else { throw CodeFileError.failedToDecode } | ||
| guard let content = String(data: data, encoding: .utf8) else { return } | ||
| self.content = content | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // | ||
| // OtherFileView.swift | ||
| // | ||
| // | ||
| // Created by Shibo Tong on 10/7/2022. | ||
| // | ||
|
|
||
| import SwiftUI | ||
| import QuickLookUI | ||
|
|
||
| /// A SwiftUI Wrapper for `QLPreviewView` | ||
| /// Mainly used for other unsupported files | ||
| /// ## Usage | ||
| /// ```swift | ||
| /// OtherFileView(otherFile) | ||
| /// ``` | ||
| public struct OtherFileView: NSViewRepresentable { | ||
|
|
||
| private var otherFile: CodeFileDocument | ||
|
|
||
| /// Initialize the OtherFileView | ||
| /// - Parameter otherFile: a file which contains URL to show preview | ||
| public init( | ||
| _ otherFile: CodeFileDocument | ||
| ) { | ||
| self.otherFile = otherFile | ||
| } | ||
|
|
||
| public func makeNSView(context: Context) -> QLPreviewView { | ||
| let qlPreviewView = QLPreviewView() | ||
| if let previewItemURL = otherFile.previewItemURL { | ||
| qlPreviewView.previewItem = previewItemURL as QLPreviewItem | ||
| } | ||
| return qlPreviewView | ||
| } | ||
|
|
||
| /// Update preview file when file changed | ||
| public func updateNSView(_ nsView: QLPreviewView, context: Context) { | ||
| if let previewItemURL = otherFile.previewItemURL { | ||
| nsView.previewItem = previewItemURL as QLPreviewItem | ||
| } | ||
|
|
||
| } | ||
|
|
||
| } |

Uh oh!
There was an error while loading. Please reload this page.