diff --git a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+TabToolbarDelegate.swift b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+TabToolbarDelegate.swift index 83242020e3dc..2427e76c9e2d 100644 --- a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+TabToolbarDelegate.swift +++ b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+TabToolbarDelegate.swift @@ -430,4 +430,8 @@ extension BrowserViewController: ToolBarActionMenuDelegate, UIDocumentPickerDele documentPicker.modalPresentationStyle = .formSheet showViewController(viewController: documentPicker) } + + func showEditBookmark() { + openBookmarkEditPanel() + } } diff --git a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift index a7ca670cb1c1..c4254a3145f0 100644 --- a/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift +++ b/firefox-ios/Client/Frontend/Browser/BrowserViewController/Views/BrowserViewController.swift @@ -1690,35 +1690,57 @@ class BrowserViewController: UIViewController, } /// This function will open a view separate from the bookmark edit panel found in the - /// Library Panel - Bookmarks section. In order to get the correct information, it needs - /// to fetch the last added bookmark in the mobile folder, which is the default - /// location for all bookmarks added on mobile. + /// Library Panel - Bookmarks section. internal func openBookmarkEditPanel() { - TelemetryWrapper.recordEvent( - category: .action, - method: .change, - object: .bookmark, - value: .addBookmarkToast - ) - if profile.isShutdown { return } - profile.places.getBookmarksTree( - rootGUID: BookmarkRoots.MobileFolderGUID, - recursive: false - ).uponQueue(.main) { result in - guard let bookmarkFolder = result.successValue as? BookmarkFolderData, - let bookmarkNode = bookmarkFolder.children?.first as? FxBookmarkNode - else { return } + guard !profile.isShutdown else { return } + + // Open refactored bookmark edit view + if isBookmarkRefactorEnabled { + guard let url = tabManager.selectedTab?.url else { return } + profile.places.getBookmarksWithURL(url: url.absoluteString).uponQueue(.main) { result in + guard let bookmarkItem = result.successValue?.first, + let parentGuid = bookmarkItem.parentGUID else { return } + self.profile.places.getBookmark(guid: parentGuid).uponQueue(.main) { result in + guard let parentFolder = result.successValue as? BookmarkFolderData else { return } + let viewModel = EditBookmarkViewModel(parentFolder: parentFolder, + node: bookmarkItem, + profile: self.profile) + let controller = EditBookmarkViewController(viewModel: viewModel, + windowUUID: self.windowUUID) + let navigationController = DismissableNavigationViewController(rootViewController: controller) + self.present(navigationController, animated: true, completion: nil) + } + } + // Open legacy bookmark edit view + } else { + TelemetryWrapper.recordEvent( + category: .action, + method: .change, + object: .bookmark, + value: .addBookmarkToast + ) - let detailController = LegacyBookmarkDetailPanel(profile: self.profile, - windowUUID: self.windowUUID, - bookmarkNode: bookmarkNode, - parentBookmarkFolder: bookmarkFolder, - presentedFromToast: true) { [weak self] in - self?.showBookmarkToast(action: .remove) + // Fetch the last added bookmark in the mobile folder, which is the default location for all bookmarks + // added on mobile when the bookmark refactor is not enabled + profile.places.getBookmarksTree( + rootGUID: BookmarkRoots.MobileFolderGUID, + recursive: false + ).uponQueue(.main) { result in + guard let bookmarkFolder = result.successValue as? BookmarkFolderData, + let bookmarkNode = bookmarkFolder.children?.first as? FxBookmarkNode + else { return } + + let detailController = LegacyBookmarkDetailPanel(profile: self.profile, + windowUUID: self.windowUUID, + bookmarkNode: bookmarkNode, + parentBookmarkFolder: bookmarkFolder, + presentedFromToast: true) { [weak self] in + self?.showBookmarkToast(action: .remove) + } + let controller: DismissableNavigationViewController + controller = DismissableNavigationViewController(rootViewController: detailController) + self.present(controller, animated: true, completion: nil) } - let controller: DismissableNavigationViewController - controller = DismissableNavigationViewController(rootViewController: detailController) - self.present(controller, animated: true, completion: nil) } } diff --git a/firefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swift b/firefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swift index 46465ea93f50..e3947bd68487 100644 --- a/firefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swift +++ b/firefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swift @@ -27,6 +27,7 @@ protocol ToolBarActionMenuDelegate: AnyObject { func showCreditCardSettings() func showSignInView(fxaParameters: FxASignInViewParameters) func showFilePicker(fileURL: URL) + func showEditBookmark() } extension ToolBarActionMenuDelegate { @@ -56,7 +57,8 @@ enum MenuButtonToastAction { class MainMenuActionHelper: PhotonActionSheetProtocol, FeatureFlaggable, CanRemoveQuickActionBookmark, - AppVersionUpdateCheckerProtocol { + AppVersionUpdateCheckerProtocol, + BookmarksRefactorFeatureFlagProvider { typealias SendToDeviceDelegate = InstructionsViewDelegate & DevicePickerViewControllerDelegate private let isHomePage: Bool @@ -720,7 +722,8 @@ class MainMenuActionHelper: PhotonActionSheetProtocol, } private func getBookmarkAction() -> SingleActionViewModel { - return isBookmarked ? getRemoveBookmarkAction() : getAddBookmarkAction() + guard isBookmarked else { return getAddBookmarkAction() } + return isBookmarkRefactorEnabled ? getEditBookmarkAction() : getRemoveBookmarkAction() } private func getAddBookmarkAction() -> SingleActionViewModel { @@ -764,6 +767,13 @@ class MainMenuActionHelper: PhotonActionSheetProtocol, } } + private func getEditBookmarkAction() -> SingleActionViewModel { + return SingleActionViewModel(title: .LegacyAppMenu.EditBookmarkLabel, + iconString: StandardImageIdentifiers.Large.bookmarkFill) { _ in + self.delegate?.showEditBookmark() + } + } + // MARK: Shortcut private func getShortcutAction() -> PhotonRowActions { diff --git a/firefox-ios/Client/Frontend/Library/Bookmarks/Edit Bookmark/EditBookmarkViewController.swift b/firefox-ios/Client/Frontend/Library/Bookmarks/Edit Bookmark/EditBookmarkViewController.swift index e2702f42e163..5712182a8d4d 100644 --- a/firefox-ios/Client/Frontend/Library/Bookmarks/Edit Bookmark/EditBookmarkViewController.swift +++ b/firefox-ios/Client/Frontend/Library/Bookmarks/Edit Bookmark/EditBookmarkViewController.swift @@ -41,6 +41,17 @@ class EditBookmarkViewController: UIViewController, size: CGSize(width: 0, height: UX.bookmarkCellTopPadding))) view.tableHeaderView = headerSpacerView } + + private lazy var saveBarButton: UIBarButtonItem = { + let button = UIBarButtonItem( + title: String.Bookmarks.Menu.EditBookmarkSave, + style: .done, + target: self, + action: #selector(saveButtonAction) + ) + return button + }() + var onViewWillDisappear: (() -> Void)? var onViewWillAppear: (() -> Void)? private let viewModel: EditBookmarkViewModel @@ -68,6 +79,8 @@ class EditBookmarkViewController: UIViewController, viewModel.onFolderStatusUpdate = { [weak self] in self?.tableView.reloadSections(IndexSet(integer: Section.folder.rawValue), with: .automatic) } + + navigationItem.rightBarButtonItem = saveBarButton // The back button title sometimes doesn't allign with the chevron, force navigation bar layout navigationController?.navigationBar.layoutIfNeeded() setupSubviews() @@ -95,8 +108,11 @@ class EditBookmarkViewController: UIViewController, if let isDragging = transitionCoordinator?.isInteractive, !isDragging { navigationController?.setNavigationBarHidden(true, animated: true) } + // Save when popping the view off the navigation stack + if isMovingFromParent { + viewModel.saveBookmark() + } onViewWillDisappear?() - viewModel.saveBookmark() } // MARK: - Setup @@ -111,6 +127,20 @@ class EditBookmarkViewController: UIViewController, ]) } + // MARK: - Actions + + @objc + func saveButtonAction() { + // Check if this is the root view controller so we can save before dismissing + if navigationController?.viewControllers.first == self { + viewModel.saveBookmark() + self.dismiss(animated: true) + } else { + // Save will happen in viewWillDisappear + navigationController?.popViewController(animated: true) + } + } + // MARK: - Themeable func applyTheme() {