Repository: CodeEditApp/CodeEdit
File: CodeEdit/Features/NavigatorSidebar/NavigatorSidebarToolbarBottom.swift (Swift)

Code before:

    @EnvironmentObject
    var workspace: WorkspaceDocument

    var body: some View {
        HStack(spacing: 10) {
            addNewFileButton
            Spacer()
            sortButton
        }
        .frame(height: 29, alignment: .center)
        .frame(maxWidth: .infinity)
        .padding(.horizontal, 4)
        .overlay(alignment: .top) {
            Divider()
        }
    }

    private var addNewFileButton: some View {
        Menu {
            Button("Add File") {
                guard let folderURL = workspace.workspaceClient?.folderURL() else { return }
                guard let root = try? workspace.workspaceClient?.getFileItem(folderURL.path) else { return }
                let newFile = root.addFile(fileName: "untitled") // TODO: use currently selected file instead of root

                DispatchQueue.global(qos: .background).async {
                    DispatchQueue.main.sync {
                        guard let newFileItem = try? workspace.workspaceClient?.getFileItem(newFile) else {
                            return
                        }
                        workspace.openTab(item: newFileItem)
                    }
                }

            }
            Button("Add Folder") {
                guard let folderURL = workspace.workspaceClient?.folderURL() else { return }
                guard let root = try? workspace.workspaceClient?.getFileItem(folderURL.path) else { return }
                root.addFolder(folderName: "untitled") // TODO: use currently selected file instead of root
            }
        } label: {
            Image(systemName: "plus")
        }
        .menuStyle(.borderlessButton)
        .menuIndicator(.hidden)
        .frame(maxWidth: 30)
        .opacity(activeState == .inactive ? 0.45 : 1)
    }

    private var sortButton: some View {
        Menu {

Review comment (suggestion):
This nested dispatch should be changed to a single `DispatchQueue.main.async`. `DispatchQueue.main.async` will queue the completion for the next render loop, so there's no need to do two context switches.

Code after:

    @EnvironmentObject
    var workspace: WorkspaceDocument

    var body: some View {
        HStack(spacing: 10) {
            addNewFileButton
            Spacer()
            sortButton
        }
        .frame(height: 29, alignment: .center)
        .frame(maxWidth: .infinity)
        .padding(.horizontal, 4)
        .overlay(alignment: .top) {
            Divider()
        }
    }

    private var addNewFileButton: some View {
        Menu {
            Button("Add File") {
                guard let folderURL = workspace.workspaceClient?.folderURL() else { return }
                guard let root = try? workspace.workspaceClient?.getFileItem(folderURL.path) else { return }
                let newFile = root.addFile(fileName: "untitled") // TODO: use currently selected file instead of root

                DispatchQueue.main.async {
                    guard let newFileItem = try? workspace.workspaceClient?.getFileItem(newFile) else {
                        return
                    }
                    workspace.openTab(item: newFileItem)
                }

            }
            Button("Add Folder") {
                guard let folderURL = workspace.workspaceClient?.folderURL() else { return }
                guard let root = try? workspace.workspaceClient?.getFileItem(folderURL.path) else { return }
                root.addFolder(folderName: "untitled") // TODO: use currently selected file instead of root
            }
        } label: {
            Image(systemName: "plus")
        }
        .menuStyle(.borderlessButton)
        .menuIndicator(.hidden)
        .frame(maxWidth: 30)
        .opacity(activeState == .inactive ? 0.45 : 1)
    }

    private var sortButton: some View {
        Menu {
            Button {
                workspace.sortFoldersOnTop.toggle()