| ... | ... | @@ -91,14 +91,16 @@ enum Arranging { |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | /// Puts the pages of `section` in `order`, page `id` the one moved, as one edit. |
| 94 | | static func arrange(_ section: Section, _ order: [Placed], moving id: String) { |
| 95 | | guard available() else { return } |
| 94 | @discardableResult |
| 95 | static func arrange(_ section: Section, _ order: [Placed], moving id: String) -> Bool { |
| 96 | guard available() else { return false } |
| 96 | 97 | let before = section.rows.map { Placed(id: $0.id, level: $0.level) } |
| 97 | | guard order != before, section.arrange(order, moving: id) else { return } |
| 98 | guard order != before, section.arrange(order, moving: id) else { return false } |
| 98 | 99 | let (notebook, path) = (section.notebook, section.tab.path) |
| 99 | 100 | done("Move Page") { |
| 100 | 101 | opening(path, of: notebook) { arrange($0, before, moving: id) } |
| 101 | 102 | } |
| 103 | return true |
| 102 | 104 | } |
| 103 | 105 | |
| 104 | 106 | /// Gives page `id` of `section` `level` where it stands, as Make Subpage and Promote |
| ... | ... | @@ -393,10 +395,13 @@ extension PagesViewController: UITableViewDragDelegate, UITableViewDropDelegate |
| 393 | 395 | } |
| 394 | 396 | |
| 395 | 397 | /// Page `id` moved to `index` of the section's pages. |
| 396 | | private func move(_ id: String, to index: Int) { |
| 397 | | guard let section else { return } |
| 398 | | Arranging.arrange(section, Arranging.order(section.rows, moving: id, to: index), moving: id) |
| 398 | @discardableResult |
| 399 | private func move(_ id: String, to index: Int) -> Bool { |
| 400 | guard let section else { return false } |
| 401 | let order = Arranging.order(section.rows, moving: id, to: index) |
| 402 | guard order.first?.level == 1, Arranging.arrange(section, order, moving: id) else { return false } |
| 399 | 403 | becomeFirstResponder() |
| 404 | return true |
| 400 | 405 | } |
| 401 | 406 | |
| 402 | 407 | /// Page `id` a level deeper or shallower, where it stays. |
| ... | ... | @@ -449,15 +454,26 @@ extension PagesViewController: UITableViewDragDelegate, UITableViewDropDelegate |
| 449 | 454 | |
| 450 | 455 | /// VoiceOver's ways to move a page without dragging it. |
| 451 | 456 | func arrangeActions(_ item: Item) -> [UIAccessibilityCustomAction]? { |
| 452 | | guard !Arranging.busy, item.version == nil, let rows = section?.rows, let at = rows.firstIndex(where: { $0.id == item.row.id }) |
| 457 | guard !Arranging.busy, item.version == nil, let section, |
| 458 | let at = section.rows.firstIndex(where: { $0.id == item.row.id }) |
| 453 | 459 | else { return nil } |
| 460 | let rows = section.rows |
| 454 | 461 | let id = item.row.id |
| 455 | 462 | var actions: [UIAccessibilityCustomAction] = [] |
| 463 | for (name, direction) in [("Move Up", -1), ("Move Down", 1)] { |
| 464 | guard rows.indices.contains(at + direction), |
| 465 | at > 0 || direction < 0 || rows[1].level == 1 |
| 466 | else { continue } |
| 467 | actions.append(UIAccessibilityCustomAction(name: name) { [weak self] _ in |
| 468 | guard let self, self.section === section, |
| 469 | let at = section.rows.firstIndex(where: { $0.id == id }), section.rows.indices.contains(at + direction) |
| 470 | else { return false } |
| 471 | return move(id, to: at + direction) |
| 472 | }) |
| 473 | } |
| 456 | 474 | let add = { (name: String, act: @escaping () -> Void) in |
| 457 | 475 | actions.append(UIAccessibilityCustomAction(name: name) { _ in act(); return true }) |
| 458 | 476 | } |
| 459 | | if at > 0 { add("Move Up") { [weak self] in self?.move(id, to: at - 1) } } |
| 460 | | if at < rows.count - 1 { add("Move Down") { [weak self] in self?.move(id, to: at + 1) } } |
| 461 | 477 | if indentable(rows, at) { add("Make Subpage") { [weak self] in self?.indent(id, by: 1) } } |
| 462 | 478 | if rows[at].level > 1 { add("Promote Subpage") { [weak self] in self?.indent(id, by: -1) } } |
| 463 | 479 | if !moveActions(item).isEmpty { |