Skip to content

Commit

Permalink
Red close button unsaved indicator (#1457)
Browse files Browse the repository at this point in the history
red close unsaved indicator
  • Loading branch information
avinizhanov authored Oct 19, 2023
1 parent 2cf0170 commit c5eeb44
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
6 changes: 3 additions & 3 deletions CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ final class CEWorkspaceFile: Codable, Comparable, Hashable, Identifiable, Editor
/// If the item already is the top-level ``CEWorkspaceFile`` this returns `nil`.
var parent: CEWorkspaceFile?

private let fileDocumentSubject = PassthroughSubject<Void, Never>()
private let fileDocumentSubject = PassthroughSubject<CodeFileDocument?, Never>()

var fileDocument: CodeFileDocument? {
didSet {
fileDocumentSubject.send()
fileDocumentSubject.send(fileDocument)
}
}

/// Publisher for fileDocument property
var fileDocumentPublisher: AnyPublisher<Void, Never> {
var fileDocumentPublisher: AnyPublisher<CodeFileDocument?, Never> {
fileDocumentSubject.eraseToAnyPublisher()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Cocoa
import SwiftUI
import Combine

final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, ObservableObject {
static let minSidebarWidth: CGFloat = 242
Expand All @@ -23,6 +24,8 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs

var splitViewController: NSSplitViewController!

internal var cancellables = [AnyCancellable]()

init(window: NSWindow, workspace: WorkspaceDocument) {
super.init(window: window)
self.workspace = workspace
Expand All @@ -47,6 +50,10 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
registerCommands()
}

deinit {
cancellables.forEach({ $0.cancel() })
}

@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
Expand Down Expand Up @@ -106,6 +113,7 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
splitVC.addSplitViewItem(inspector)

self.splitViewController = splitVC
self.listenToDocumentEdited(workspace: workspace)
}

private func setupToolbar() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import Combine

extension CodeEditWindowController {
@objc
Expand Down Expand Up @@ -63,6 +64,53 @@ extension CodeEditWindowController {
command: CommandClosureWrapper(closure: { self.toggleLastPanel() })
)
}

// Listen to changes in all tabs/files
internal func listenToDocumentEdited(workspace: WorkspaceDocument) {
workspace.editorManager.$activeEditor
.flatMap({ editor in
editor.$tabs
})
.compactMap({ tab in
Publishers.MergeMany(tab.elements.compactMap({ $0.fileDocumentPublisher }))
})
.switchToLatest()
.compactMap({ fileDocument in
fileDocument?.isDocumentEditedPublisher
})
.flatMap({ $0 })
.sink { isDocumentEdited in
if isDocumentEdited {
self.setDocumentEdited(true)
return
}

self.updateDocumentEdited(workspace: workspace)
}
.store(in: &cancellables)

// Listen to change of tabs, if closed tab without saving content,
// we also need to recalculate isDocumentEdited
workspace.editorManager.$activeEditor
.flatMap({ editor in
editor.$tabs
})
.sink { _ in
self.updateDocumentEdited(workspace: workspace)
}
.store(in: &cancellables)
}

// Recalculate documentEdited by checking if any tab/file is edited
private func updateDocumentEdited(workspace: WorkspaceDocument) {
let hasEditedDocuments = !workspace
.editorManager
.editorLayout
.gatherOpenFiles()
.filter({ $0.fileDocument?.isDocumentEdited == true })
.isEmpty
self.setDocumentEdited(hasEditedDocuments)
}
}

extension NSToolbarItem.Identifier {
Expand Down

0 comments on commit c5eeb44

Please sign in to comment.