Scroll settings hint to import controls
This commit is contained in:
parent
c5ae8dc9eb
commit
d369778f7f
7 changed files with 77 additions and 11 deletions
|
|
@ -8944,6 +8944,7 @@ private final class FeedbackComposerMessageEditorView: NSView {
|
|||
}
|
||||
|
||||
private enum SidebarHelpMenuAction {
|
||||
case importBrowserData
|
||||
case keyboardShortcuts
|
||||
case docs
|
||||
case changelog
|
||||
|
|
@ -9514,6 +9515,12 @@ private struct SidebarHelpMenuButton: View {
|
|||
accessibilityIdentifier: "SidebarHelpMenuOptionKeyboardShortcuts",
|
||||
isExternalLink: false
|
||||
)
|
||||
helpOptionButton(
|
||||
title: String(localized: "menu.view.importFromBrowser", defaultValue: "Import From Browser…"),
|
||||
action: .importBrowserData,
|
||||
accessibilityIdentifier: "SidebarHelpMenuOptionImportBrowserData",
|
||||
isExternalLink: false
|
||||
)
|
||||
if docsURL != nil {
|
||||
helpOptionButton(
|
||||
title: String(localized: "about.docs", defaultValue: "Docs"),
|
||||
|
|
@ -9618,6 +9625,11 @@ private struct SidebarHelpMenuButton: View {
|
|||
|
||||
private func perform(_ action: SidebarHelpMenuAction) {
|
||||
switch action {
|
||||
case .importBrowserData:
|
||||
isPopoverPresented = false
|
||||
DispatchQueue.main.async {
|
||||
BrowserDataImportCoordinator.shared.presentImportDialog()
|
||||
}
|
||||
case .keyboardShortcuts:
|
||||
isPopoverPresented = false
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.12) {
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ enum BrowserImportHintSettings {
|
|||
static let variantKey = "browserImportHintVariant"
|
||||
static let showOnBlankTabsKey = "browserImportHintShowOnBlankTabs"
|
||||
static let dismissedKey = "browserImportHintDismissed"
|
||||
static let defaultVariant: BrowserImportHintVariant = .inlineStrip
|
||||
static let defaultVariant: BrowserImportHintVariant = .toolbarChip
|
||||
static let defaultShowOnBlankTabs = true
|
||||
static let defaultDismissed = false
|
||||
|
||||
|
|
|
|||
|
|
@ -873,6 +873,14 @@ struct BrowserPanelView: View {
|
|||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
Button {
|
||||
presentImportDialogFromProfileMenu()
|
||||
} label: {
|
||||
Text(String(localized: "menu.view.importFromBrowser", defaultValue: "Import From Browser…"))
|
||||
.font(.system(size: 12))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
if browserProfileStore.canRenameProfile(id: panel.profileID) {
|
||||
Button {
|
||||
isBrowserProfileMenuPresented = false
|
||||
|
|
@ -1470,6 +1478,16 @@ struct BrowserPanelView: View {
|
|||
|
||||
private func presentImportDialogFromHint() {
|
||||
isBrowserImportHintPopoverPresented = false
|
||||
// Let the popover fully dismiss before entering the modal import flow.
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.12) {
|
||||
BrowserDataImportCoordinator.shared.presentImportDialog(
|
||||
defaultDestinationProfileID: panel.profileID
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func presentImportDialogFromProfileMenu() {
|
||||
isBrowserProfileMenuPresented = false
|
||||
DispatchQueue.main.async {
|
||||
BrowserDataImportCoordinator.shared.presentImportDialog(
|
||||
defaultDestinationProfileID: panel.profileID
|
||||
|
|
@ -1479,7 +1497,7 @@ struct BrowserPanelView: View {
|
|||
|
||||
private func openBrowserImportSettings() {
|
||||
isBrowserImportHintPopoverPresented = false
|
||||
AppDelegate.presentPreferencesWindow(navigationTarget: .browser)
|
||||
AppDelegate.presentPreferencesWindow(navigationTarget: .browserImport)
|
||||
}
|
||||
|
||||
private func dismissBrowserImportHint() {
|
||||
|
|
|
|||
|
|
@ -2252,6 +2252,7 @@ final class SettingsWindowController: NSWindowController, NSWindowDelegate {
|
|||
|
||||
enum SettingsNavigationTarget: String {
|
||||
case browser
|
||||
case browserImport
|
||||
case keyboardShortcuts
|
||||
}
|
||||
|
||||
|
|
@ -4659,6 +4660,7 @@ struct SettingsView: View {
|
|||
}
|
||||
.buttonStyle(.bordered)
|
||||
.controlSize(.small)
|
||||
.accessibilityIdentifier("SettingsBrowserImportChooseButton")
|
||||
|
||||
Button(String(localized: "settings.browser.import.refresh", defaultValue: "Refresh")) {
|
||||
refreshDetectedImportBrowsers()
|
||||
|
|
@ -4680,6 +4682,8 @@ struct SettingsView: View {
|
|||
.foregroundStyle(.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
.id(SettingsNavigationTarget.browserImport)
|
||||
.accessibilityIdentifier("SettingsBrowserImportSection")
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 10)
|
||||
|
||||
|
|
|
|||
|
|
@ -2550,6 +2550,24 @@ final class AppDelegateShortcutRoutingTests: XCTestCase {
|
|||
XCTAssertEqual(activateApplicationCallCount, 1)
|
||||
}
|
||||
|
||||
func testPresentPreferencesWindowForwardsBrowserImportNavigationTarget() {
|
||||
var receivedNavigationTarget: SettingsNavigationTarget?
|
||||
var activateApplicationCallCount = 0
|
||||
|
||||
AppDelegate.presentPreferencesWindow(
|
||||
navigationTarget: .browserImport,
|
||||
showFallbackSettingsWindow: { navigationTarget in
|
||||
receivedNavigationTarget = navigationTarget
|
||||
},
|
||||
activateApplication: {
|
||||
activateApplicationCallCount += 1
|
||||
}
|
||||
)
|
||||
|
||||
XCTAssertEqual(receivedNavigationTarget, .browserImport)
|
||||
XCTAssertEqual(activateApplicationCallCount, 1)
|
||||
}
|
||||
|
||||
private func makeKeyDownEvent(
|
||||
key: String,
|
||||
modifiers: NSEvent.ModifierFlags,
|
||||
|
|
|
|||
|
|
@ -144,14 +144,15 @@ final class BrowserImportMappingTests: XCTestCase {
|
|||
XCTAssertTrue(manyProfilesPresentation.showsHelpText)
|
||||
}
|
||||
|
||||
func testBrowserImportHintPresentationDefaultsToInlineStrip() {
|
||||
let presentation = BrowserImportHintPresentation(
|
||||
variant: .inlineStrip,
|
||||
showOnBlankTabs: true,
|
||||
isDismissed: false
|
||||
)
|
||||
func testBrowserImportHintSettingsDefaultToToolbarChip() throws {
|
||||
let suiteName = "BrowserImportHintDefaults-\(UUID().uuidString)"
|
||||
let defaults = try XCTUnwrap(UserDefaults(suiteName: suiteName))
|
||||
defaults.removePersistentDomain(forName: suiteName)
|
||||
defer { defaults.removePersistentDomain(forName: suiteName) }
|
||||
|
||||
XCTAssertEqual(presentation.blankTabPlacement, .inlineStrip)
|
||||
let presentation = BrowserImportHintSettings.presentation(defaults: defaults)
|
||||
|
||||
XCTAssertEqual(presentation.blankTabPlacement, .toolbarChip)
|
||||
XCTAssertEqual(presentation.settingsStatus, .visible)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,9 +119,22 @@ final class BrowserImportProfilesUITests: XCTestCase {
|
|||
XCTAssertTrue(settingsButton.waitForExistence(timeout: 5.0))
|
||||
settingsButton.click()
|
||||
|
||||
let importSection = app.otherElements["SettingsBrowserImportSection"]
|
||||
XCTAssertTrue(
|
||||
app.switches["SettingsBrowserImportHintToggle"].waitForExistence(timeout: 5.0),
|
||||
"Expected Browser Settings to open from the blank-tab import hint"
|
||||
importSection.waitForExistence(timeout: 5.0),
|
||||
"Expected Browser Settings to scroll to the import section"
|
||||
)
|
||||
|
||||
let chooseButton = app.buttons["SettingsBrowserImportChooseButton"]
|
||||
XCTAssertTrue(
|
||||
chooseButton.waitForExistence(timeout: 5.0),
|
||||
"Expected Browser Settings to expose the import actions"
|
||||
)
|
||||
XCTAssertTrue(
|
||||
browserImportPollUntil(timeout: 5.0) {
|
||||
importSection.isHittable && chooseButton.isHittable
|
||||
},
|
||||
"Expected Browser Settings to scroll directly to the import controls"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue