Adding Component Duplication to Lona

As you might know, I’ve decided to proceed with making more contributions to Lona, and earlier this week I had an opportunity to add a new feature to this app. Here is an overview of my contribution:

Feature request ⚙️

Users often create new components based on the existing ones, and the only way to do it was to go to Finder and copy & paste a component file. So, there was a feature request to add component duplication support to the File Navigator.

First, let’s take a look at the context menu of the file in File Navigator:

My task was to add a new option called “Duplicate As…” to the context menu, and once the option was selected, it should display the Save dialog. After the user typed a file name, selected location for it and pressed “Save”, the program should open a newly created component in the Component Editor.

Link to the issue:

Implementation ⚒

There is a function menuForFile, which creates a context menu, in the FileNavigator class, and that’s the place, where I needed to place my new code:

// Check if selected file has a ".component" extension
if
NSURL(fileURLWithPath: path).pathExtension == "component" {
menu.addItem(NSMenuItem(title: "Duplicate As...", onClick: {
var saveURL: String
// Show Save Dialog
let dialog = NSSavePanel()
dialog.title = "Save .component file"
dialog.showsResizeIndicator = true
dialog.showsHiddenFiles = false
dialog.canCreateDirectories = true
dialog.allowedFileTypes = ["component"]
dialog.directoryURL = URL(fileURLWithPath: path).deletingLastPathComponent()
        // User canceled the save. Don't swap out the document.
if dialog.runModal() != NSApplication.ModalResponse.OK {
return
}
        guard let url = dialog.url else { return }
saveURL = url.path
// Try to copy file. If successful, open the file in the Component Editor. Otherwise, display an alert with an appropriate message.
do
{
try FileManager.default.copyItem(atPath: path, toPath: saveURL)
} catch {
let alert = NSAlert()
alert.messageText = "Couldn't copy component to \(saveURL)"
alert.addButton(withTitle: "OK")
alert.runModal()
return
}
self.onAction?(saveURL)
}))
}

Result

Component Duplication demo

Link to PR:


Enjoyed this post? Feel free to give this post a few claps so others can enjoy it 👏👏👏