Skip to content

Commit 2be0e72

Browse files
committed
Edit new file names
When a new file or folder is added, its new (generic) label is right put into an editing state right away. Fixes #12
1 parent 8411ba7 commit 2be0e72

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

NavigatorDemo/ContentView.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,14 @@ struct FolderContextMenu: View {
7070
Button {
7171
withAnimation {
7272
let newFile = FileOrFolder<File<Payload>, Payload>(file: File(contents: Payload(text: "")))
73-
viewContext.add(item: newFile, $to: $folder, withPreferredName: "Text.txt")
74-
viewContext.viewState.selection = newFile.id
73+
if let newName = viewContext.add(item: newFile, $to: $folder, withPreferredName: "Text.txt") {
74+
75+
viewContext.viewState.selection = newFile.id
76+
Task { @MainActor in
77+
viewContext.viewState.editedLabel = FileNavigatorViewState.EditedLabel(id: newFile.id, text: newName)
78+
}
79+
80+
}
7581
}
7682
} label: {
7783
Label("New file", systemImage: "doc.badge.plus")
@@ -80,8 +86,14 @@ struct FolderContextMenu: View {
8086
Button {
8187
withAnimation {
8288
let newFolder = FileOrFolder<File<Payload>, Payload>(folder: Folder(children: [:]))
83-
viewContext.add(item: newFolder, $to: $folder, withPreferredName: "Folder")
84-
viewContext.viewState.selection = newFolder.id
89+
if let newName = viewContext.add(item: newFolder, $to: $folder, withPreferredName: "Folder") {
90+
91+
viewContext.viewState.selection = newFolder.id
92+
Task { @MainActor in
93+
viewContext.viewState.editedLabel = FileNavigatorViewState.EditedLabel(id: newFolder.id, text: newName)
94+
}
95+
96+
}
8597
}
8698
} label: {
8799
Label("New folder", systemImage: "folder.badge.plus")
@@ -267,10 +279,10 @@ struct Navigator: View {
267279
// environment. Hence, the SwiftUI document system is not informed of changes to the text by the
268280
// `TextEditor`. As a consequence, (auto)saving does not work.
269281
//
270-
// The following codes works around this issues by explicitly registering text changes with the undo
271-
// manager provided by the SwiftUI document system. This is only a work around and not a proper solution
272-
// as it will also undo changes made to the text outside of the `TextEditor`. (This is not a problem
273-
// in this little demo app.)
282+
// The following code works around this issues by explicitly registering text changes with the undo
283+
// manager provided by the SwiftUI document system. This is only a work around and not a proper
284+
// solution as it will also undo changes made to the text outside of the `TextEditor`. (This is not a
285+
// problem in this little demo app, but generally not desirable.)
274286
undoManager?.registerUndo(withTarget: model) { [weak undoManager] _ in
275287
$text.wrappedValue = oldValue
276288
changeByUndoManager = true

NavigatorDemo/ViewContext.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,22 @@ extension ViewContext {
6969
/// - item: The item to add.
7070
/// - to: The folder to which the item is to be added.
7171
/// - preferredName: The preferred name of the given item.
72+
/// - Returns:If successful, the actual name under which the item was added.
7273
///
7374
/// If the preferred name is already taken, an alternative name, derived from the preferred name, will be used.
7475
///
7576
/// If needed the dominant folder is being refreshed accordingly.
7677
///
77-
func add(item: FullFileOrFolder<Payload>, @Binding to folder: ProxyFolder<Payload>, withPreferredName preferredName: String) {
78-
79-
registerUndo {
80-
folder.add(item: item, withPreferredName: preferredName)
78+
@discardableResult
79+
func add(item: FullFileOrFolder<Payload>,
80+
@Binding to folder: ProxyFolder<Payload>,
81+
withPreferredName preferredName: String)
82+
-> String?
83+
{
84+
return registerUndo {
85+
let newName = folder.add(item: item, withPreferredName: preferredName)
8186
viewState.refreshDominantFolder(updatedFolder: Binding($folder))
87+
return newName
8288
}
8389
}
8490

@@ -106,19 +112,20 @@ extension ViewContext {
106112
///
107113
/// During undo, register a redo in a symmetric manner.
108114
///
109-
private func registerUndo(action: () -> Void) {
115+
private func registerUndo<Result>(action: () -> Result) -> Result {
110116

111117
// Preserve old value for undo
112118
let oldTextsCopy = FileTree<Payload>(fileTree: model.document.texts)
113119

114120
// Perform action
115-
action()
121+
let result = action()
116122

117123
// Register undoing the change
118124
undoManager?.registerUndo(withTarget: model) { ourModel in
119125
registerUndo {
120126
ourModel.document.texts.set(to: oldTextsCopy)
121127
}
122128
}
129+
return result
123130
}
124131
}

Sources/Files/FileOperations.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ extension Folder {
2323
/// 100 attempts, the item will not be inserted.
2424
/// - index: Optional index at which to insert the new item into the ordered set of children. If no index is given,
2525
/// the new child will be added at the first position where it fits alphabetically.
26+
/// - Returns:If successful, the name under which the item was added.
2627
///
2728
/// This function only works on folders in proxy trees. (It would be easy to provide a corresponding version on
2829
/// folders containing full files.)
2930
///
31+
@discardableResult
3032
public mutating func add(item: FullFileOrFolder<Contents>,
3133
withPreferredName preferredName: String,
3234
at index: Int? = nil)
35+
-> String?
3336
where FileType == File<Contents>.Proxy
3437
{
3538
// Folders in proxy tree must have a file tree set.
3639
guard let fileTree else {
3740
logger.error("Folder.add(item:withPreferredName:at:) in a proxy tree without having a file tree set")
38-
return
41+
return nil
3942
}
4043

4144
let ext = (preferredName as NSString).pathExtension,
@@ -67,6 +70,7 @@ extension Folder {
6770
// ...in case the caller passes an out of range index
6871

6972
}
73+
return finalName
7074
}
7175

7276
/// Remove the item with the given name from the a folder.

0 commit comments

Comments
 (0)