Skip to content

Commit

Permalink
Merge branch 'main' into source-control-settings
Browse files Browse the repository at this point in the history
  • Loading branch information
austincondiff authored Nov 2, 2024
2 parents 52b03ef + ffb0f8b commit 528fe57
Show file tree
Hide file tree
Showing 10 changed files with 391 additions and 103 deletions.
8 changes: 8 additions & 0 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; };
3E0196732A3921AC002648D8 /* codeedit_shell_integration_rc.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196722A3921AC002648D8 /* codeedit_shell_integration_rc.zsh */; };
3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */; };
4A6F0DB52CBA462B00499627 /* ProjectNavigatorMenuActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A6F0DB42CBA462B00499627 /* ProjectNavigatorMenuActions.swift */; };
4E7F066629602E7B00BB3C12 /* CodeEditSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7F066529602E7B00BB3C12 /* CodeEditSplitViewController.swift */; };
4EE96ECB2960565E00FFBEA8 /* DocumentsUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE96ECA2960565E00FFBEA8 /* DocumentsUnitTests.swift */; };
4EE96ECE296059E000FFBEA8 /* NSHapticFeedbackPerformerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE96ECD296059E000FFBEA8 /* NSHapticFeedbackPerformerMock.swift */; };
Expand Down Expand Up @@ -590,6 +591,7 @@
B6D7EA592971078500301FAC /* InspectorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D7EA582971078500301FAC /* InspectorSection.swift */; };
B6D7EA5C297107DD00301FAC /* InspectorField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D7EA5B297107DD00301FAC /* InspectorField.swift */; };
B6E38E022CD3E63A00F4E65A /* GitConfigClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E38E012CD3E62E00F4E65A /* GitConfigClient.swift */; };
B6DCDAC62CCDE2B90099FBF9 /* InstantPopoverModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DCDAC52CCDE2B90099FBF9 /* InstantPopoverModifier.swift */; };
B6E41C7029DD157F0088F9F4 /* AccountsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E41C6F29DD157F0088F9F4 /* AccountsSettingsView.swift */; };
B6E41C7429DD40010088F9F4 /* View+HideSidebarToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E41C7329DD40010088F9F4 /* View+HideSidebarToggle.swift */; };
B6E41C7929DE02800088F9F4 /* AccountSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E41C7829DE02800088F9F4 /* AccountSelectionView.swift */; };
Expand Down Expand Up @@ -778,6 +780,7 @@
30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorSidebarViewModel.swift; sourceTree = "<group>"; };
3E0196722A3921AC002648D8 /* codeedit_shell_integration_rc.zsh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codeedit_shell_integration_rc.zsh; sourceTree = "<group>"; };
3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.bash; sourceTree = "<group>"; };
4A6F0DB42CBA462B00499627 /* ProjectNavigatorMenuActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectNavigatorMenuActions.swift; sourceTree = "<group>"; };
4E7F066529602E7B00BB3C12 /* CodeEditSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeEditSplitViewController.swift; sourceTree = "<group>"; };
4EE96ECA2960565E00FFBEA8 /* DocumentsUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsUnitTests.swift; sourceTree = "<group>"; };
4EE96ECD296059E000FFBEA8 /* NSHapticFeedbackPerformerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSHapticFeedbackPerformerMock.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1258,6 +1261,7 @@
B6D7EA582971078500301FAC /* InspectorSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorSection.swift; sourceTree = "<group>"; };
B6D7EA5B297107DD00301FAC /* InspectorField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorField.swift; sourceTree = "<group>"; };
B6E38E012CD3E62E00F4E65A /* GitConfigClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitConfigClient.swift; sourceTree = "<group>"; };
B6DCDAC52CCDE2B90099FBF9 /* InstantPopoverModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPopoverModifier.swift; sourceTree = "<group>"; };
B6E41C6F29DD157F0088F9F4 /* AccountsSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsSettingsView.swift; sourceTree = "<group>"; };
B6E41C7329DD40010088F9F4 /* View+HideSidebarToggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+HideSidebarToggle.swift"; sourceTree = "<group>"; };
B6E41C7829DE02800088F9F4 /* AccountSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSelectionView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1471,6 +1475,7 @@
6CC17B502C43311900834E2C /* ProjectNavigatorViewController+NSOutlineViewDataSource.swift */,
285FEC6F27FE4B9800E57D53 /* ProjectNavigatorTableViewCell.swift */,
285FEC7127FE4EEF00E57D53 /* ProjectNavigatorMenu.swift */,
4A6F0DB42CBA462B00499627 /* ProjectNavigatorMenuActions.swift */,
D7DC4B75298FFBE900D6C83D /* ProjectNavigatorViewController+OutlineTableViewCellDelegate.swift */,
EC0870F62A455F6400EB8692 /* ProjectNavigatorViewController+NSMenuDelegate.swift */,
);
Expand Down Expand Up @@ -2075,6 +2080,7 @@
6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */,
587B9D8C29300ABD00AC7927 /* SettingsTextEditor.swift */,
587B9D8F29300ABD00AC7927 /* ToolbarBranchPicker.swift */,
B6DCDAC52CCDE2B90099FBF9 /* InstantPopoverModifier.swift */,
2897E1C62979A29200741E32 /* TrackableScrollView.swift */,
B60718302B15A9A3009CDAB4 /* CEOutlineGroup.swift */,
);
Expand Down Expand Up @@ -4045,6 +4051,7 @@
6CFF967429BEBCC300182D6F /* FindCommands.swift in Sources */,
587B9E6529301D8F00AC7927 /* GitLabGroupAccess.swift in Sources */,
6C91D57229B176FF0059A90D /* EditorManager.swift in Sources */,
B6DCDAC62CCDE2B90099FBF9 /* InstantPopoverModifier.swift in Sources */,
6C82D6BC29C00CD900495C54 /* FirstResponderPropertyWrapper.swift in Sources */,
58D01C9B293167DC00C5B6B4 /* CodeEditKeychainConstants.swift in Sources */,
B640A99E29E2184700715F20 /* SettingsForm.swift in Sources */,
Expand Down Expand Up @@ -4308,6 +4315,7 @@
587B9DA629300ABD00AC7927 /* ToolbarBranchPicker.swift in Sources */,
6C6BD6F629CD145F00235D17 /* ExtensionInfo.swift in Sources */,
04BA7C202AE2D92B00584E1C /* GitClient+Status.swift in Sources */,
4A6F0DB52CBA462B00499627 /* ProjectNavigatorMenuActions.swift in Sources */,
58F2EB05292FB2B0004A9BDE /* Settings.swift in Sources */,
6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */,
30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct SchemeDropDownView: View {
.onHover(perform: { hovering in
self.isHoveringScheme = hovering
})
.popover(isPresented: $isSchemePopOverPresented, arrowEdge: .bottom) {
.instantPopover(isPresented: $isSchemePopOverPresented, arrowEdge: .bottom) {
VStack(alignment: .leading, spacing: 0) {
WorkspaceMenuItemView(
workspaceFileManager: workspaceFileManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct TaskDropDownView: View {
.onHover { hovering in
self.isHoveringTasks = hovering
}
.popover(isPresented: $isTaskPopOverPresented, arrowEdge: .bottom) {
.instantPopover(isPresented: $isTaskPopOverPresented, arrowEdge: .bottom) {
taskPopoverContent
}
.onTapGesture {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@ extension CEWorkspaceFileManager {
}
}

/// This function deletes multiple files or folders from the current project by erasing immediately.
/// - Parameters:
/// - files: The files to delete
/// - confirmDelete: True to present an alert to confirm the delete.
public func batchDelete(files: Set<CEWorkspaceFile>, confirmDelete: Bool = true) {
let deleteConfirmation = NSAlert()
deleteConfirmation.messageText = "Are you sure you want to delete the \(files.count) selected items?"
// swiftlint:disable:next line_length
deleteConfirmation.informativeText = "\(files.count) items will be deleted immediately. You cannot undo this action."
deleteConfirmation.alertStyle = .critical
deleteConfirmation.addButton(withTitle: "Delete")
deleteConfirmation.buttons.last?.hasDestructiveAction = true
deleteConfirmation.addButton(withTitle: "Cancel")
if !confirmDelete || deleteConfirmation.runModal() == .alertFirstButtonReturn {
for file in files where fileManager.fileExists(atPath: file.url.path) {
do {
try fileManager.removeItem(at: file.url)
} catch {
print(error.localizedDescription)
}
}
}
}

/// This function duplicates the item or folder
/// - Parameter file: The file to duplicate
/// - Authors: Mattijs Eikelenboom, KaiTheRedNinja. *Moved from 7c27b1e*
Expand Down
132 changes: 132 additions & 0 deletions CodeEdit/Features/CodeEditUI/Views/InstantPopoverModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// InstantPopoverModifier.swift
// CodeEdit
//
// Created by Kihron on 10/26/24.
//

import SwiftUI

struct InstantPopoverModifier<PopoverContent: View>: ViewModifier {
@Binding var isPresented: Bool
let arrowEdge: Edge
let popoverContent: PopoverContent

func body(content: Content) -> some View {
content
.background(
PopoverPresenter(
isPresented: $isPresented,
arrowEdge: arrowEdge,
contentView: popoverContent
)
)
}
}

struct PopoverPresenter<ContentView: View>: NSViewRepresentable {
@Binding var isPresented: Bool
let arrowEdge: Edge
let contentView: ContentView

func makeNSView(context: Context) -> NSView { NSView() }

func updateNSView(_ nsView: NSView, context: Context) {
if isPresented, context.coordinator.popover == nil {
let popover = NSPopover()
popover.animates = false
let hostingController = NSHostingController(rootView: contentView)

hostingController.view.layoutSubtreeIfNeeded()
let contentSize = hostingController.view.fittingSize
popover.contentSize = contentSize

popover.contentViewController = hostingController
popover.delegate = context.coordinator
popover.behavior = .semitransient

let nsRectEdge = edgeToNSRectEdge(arrowEdge)
popover.show(relativeTo: nsView.bounds, of: nsView, preferredEdge: nsRectEdge)
context.coordinator.popover = popover

if let parentWindow = nsView.window {
context.coordinator.startObservingWindow(parentWindow)
}
} else if !isPresented, let popover = context.coordinator.popover {
popover.close()
context.coordinator.popover = nil
}
}

func makeCoordinator() -> Coordinator {
Coordinator(isPresented: $isPresented)
}

class Coordinator: NSObject, NSPopoverDelegate {
@Binding var isPresented: Bool
var popover: NSPopover?

init(isPresented: Binding<Bool>) {
_isPresented = isPresented
super.init()
}

func startObservingWindow(_ window: NSWindow) {
/// Observe when the window loses focus
NotificationCenter.default.addObserver(
forName: NSWindow.didResignKeyNotification,
object: window,
queue: .main
) { [weak self] _ in
guard let self = self else { return }
/// The parent window is no longer focused, close the popover
DispatchQueue.main.async {
self.isPresented = false
self.popover?.close()
}
}
}

func popoverWillClose(_ notification: Notification) {
DispatchQueue.main.async {
self.isPresented = false
}
}

func popoverDidClose(_ notification: Notification) {
popover = nil
}
}

private func edgeToNSRectEdge(_ edge: Edge) -> NSRectEdge {
switch edge {
case .top: return .minY
case .leading: return .minX
case .bottom: return .maxY
case .trailing: return .maxX
}
}
}

extension View {

/// A custom view modifier that presents a popover attached to the view with no animation.
/// - Parameters:
/// - isPresented: A binding to whether the popover is presented.
/// - arrowEdge: The edge of the view that the popover points to. Defaults to `.bottom`.
/// - content: A closure returning the content of the popover.
/// - Returns: A view that presents a popover when `isPresented` is `true`.
func instantPopover<Content: View>(
isPresented: Binding<Bool>,
arrowEdge: Edge = .bottom,
@ViewBuilder content: () -> Content
) -> some View {
self.modifier(
InstantPopoverModifier(
isPresented: isPresented,
arrowEdge: arrowEdge,
popoverContent: content()
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ struct HistoryInspectorItemView: View {
} set: { newValue in
if newValue {
selection = commit
} else {
} else if selection == commit {
selection = nil
}
}
}

var body: some View {
CommitListItemView(commit: commit, showRef: false)
.popover(isPresented: showPopup, arrowEdge: .leading) {
.instantPopover(isPresented: showPopup, arrowEdge: .leading) {
HistoryPopoverView(commit: commit)
}
}
Expand Down
Loading

0 comments on commit 528fe57

Please sign in to comment.