Refine browser import minimal UI
This commit is contained in:
parent
d369778f7f
commit
c4742a4ba1
6 changed files with 648 additions and 7 deletions
|
|
@ -805,6 +805,193 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"debug.menu.browserToolbarButtonSpacing": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Browser Toolbar Button Spacing"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "ブラウザーツールバーのボタン間隔"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.menu.browserProfilePopoverDebug": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Browser Profile Popover Debug…"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "ブラウザープロファイルポップオーバーのデバッグ…"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.windows.browserProfilePopover.title": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Browser Profile Popover Debug"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "ブラウザープロファイルポップオーバーのデバッグ"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.heading": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Browser Profile Popover"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "ブラウザープロファイルポップオーバー"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.note": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Tune the profile popover padding live while comparing it against the browser toolbar menu."
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "ブラウザーツールバーのメニューと見比べながら、プロファイルポップオーバーの余白をライブで調整します。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.group.padding": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Padding"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "余白"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.label.horizontal": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Horizontal"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "水平"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.label.vertical": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Vertical"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "垂直"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.group.preview": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Preview"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "プレビュー"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.reset": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Reset"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "リセット"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.browserProfilePopover.liveNote": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Changes apply live to the browser profile popover."
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "変更はブラウザープロファイルポップオーバーにライブで反映されます。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug.devBuildBanner.title": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
|
|
|
|||
|
|
@ -8384,6 +8384,21 @@ final class BrowserDataImportCoordinator {
|
|||
return wizard.runModal()
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
func debugMakeImportWizardWindow(
|
||||
browsers: [InstalledBrowserCandidate],
|
||||
destinationProfiles: [BrowserProfileDefinition]? = nil,
|
||||
defaultDestinationProfileID: UUID? = nil
|
||||
) -> NSWindow {
|
||||
let wizard = ImportWizardWindowController(
|
||||
browsers: browsers,
|
||||
destinationProfiles: destinationProfiles,
|
||||
defaultDestinationProfileID: defaultDestinationProfileID
|
||||
)
|
||||
return wizard.debugPanelWindow
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
private struct CapturedImportSelection: Encodable {
|
||||
struct Entry: Encodable {
|
||||
|
|
@ -8555,6 +8570,10 @@ final class BrowserDataImportCoordinator {
|
|||
return selection
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
var debugPanelWindow: NSWindow { panel }
|
||||
#endif
|
||||
|
||||
func windowWillClose(_ notification: Notification) {
|
||||
finishModal(with: .cancel)
|
||||
}
|
||||
|
|
@ -8864,7 +8883,9 @@ final class BrowserDataImportCoordinator {
|
|||
sourceProfilesScrollView.contentView.postsBoundsChangedNotifications = true
|
||||
sourceProfilesScrollHeightConstraint = sourceProfilesScrollView.heightAnchor.constraint(equalToConstant: 76)
|
||||
sourceProfilesScrollHeightConstraint?.isActive = true
|
||||
sourceProfilesScrollView.widthAnchor.constraint(equalTo: sourceProfilesContainer.widthAnchor).isActive = true
|
||||
let sourceProfilesScrollWidthConstraint = sourceProfilesScrollView.widthAnchor.constraint(
|
||||
equalTo: sourceProfilesContainer.widthAnchor
|
||||
)
|
||||
|
||||
sourceProfilesHelpLabel.font = NSFont.systemFont(ofSize: 11)
|
||||
sourceProfilesHelpLabel.textColor = .secondaryLabelColor
|
||||
|
|
@ -8882,6 +8903,7 @@ final class BrowserDataImportCoordinator {
|
|||
sourceProfilesContainer.addArrangedSubview(sourceProfilesTitle)
|
||||
sourceProfilesContainer.addArrangedSubview(sourceProfilesScrollView)
|
||||
sourceProfilesContainer.addArrangedSubview(sourceProfilesHelpLabel)
|
||||
sourceProfilesScrollWidthConstraint.isActive = true
|
||||
sourceProfilesContainer.setHuggingPriority(.defaultLow, for: .vertical)
|
||||
sourceProfilesContainer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,45 @@ enum BrowserDevToolsButtonDebugSettings {
|
|||
}
|
||||
}
|
||||
|
||||
enum BrowserToolbarAccessorySpacingDebugSettings {
|
||||
static let key = "browserToolbarAccessorySpacing"
|
||||
static let defaultSpacing = 2
|
||||
static let supportedValues = [0, 2, 4, 6, 8]
|
||||
|
||||
static func resolved(_ rawValue: Int) -> Int {
|
||||
supportedValues.contains(rawValue) ? rawValue : defaultSpacing
|
||||
}
|
||||
|
||||
static func current(defaults: UserDefaults = .standard) -> Int {
|
||||
resolved(defaults.object(forKey: key) as? Int ?? defaultSpacing)
|
||||
}
|
||||
}
|
||||
|
||||
enum BrowserProfilePopoverDebugSettings {
|
||||
static let horizontalPaddingKey = "browserProfilePopoverHorizontalPadding"
|
||||
static let verticalPaddingKey = "browserProfilePopoverVerticalPadding"
|
||||
static let defaultHorizontalPadding = 12.0
|
||||
static let defaultVerticalPadding = 10.0
|
||||
static let horizontalPaddingRange = 8.0...20.0
|
||||
static let verticalPaddingRange = 4.0...14.0
|
||||
|
||||
static func resolvedHorizontalPadding(_ rawValue: Double) -> Double {
|
||||
horizontalPaddingRange.contains(rawValue) ? rawValue : defaultHorizontalPadding
|
||||
}
|
||||
|
||||
static func resolvedVerticalPadding(_ rawValue: Double) -> Double {
|
||||
verticalPaddingRange.contains(rawValue) ? rawValue : defaultVerticalPadding
|
||||
}
|
||||
|
||||
static func currentHorizontalPadding(defaults: UserDefaults = .standard) -> Double {
|
||||
resolvedHorizontalPadding((defaults.object(forKey: horizontalPaddingKey) as? NSNumber)?.doubleValue ?? defaultHorizontalPadding)
|
||||
}
|
||||
|
||||
static func currentVerticalPadding(defaults: UserDefaults = .standard) -> Double {
|
||||
resolvedVerticalPadding((defaults.object(forKey: verticalPaddingKey) as? NSNumber)?.doubleValue ?? defaultVerticalPadding)
|
||||
}
|
||||
}
|
||||
|
||||
struct OmnibarInlineCompletion: Equatable {
|
||||
let typedText: String
|
||||
let displayText: String
|
||||
|
|
@ -249,6 +288,11 @@ struct BrowserPanelView: View {
|
|||
@AppStorage(BrowserSearchSettings.searchSuggestionsEnabledKey) private var searchSuggestionsEnabledStorage = BrowserSearchSettings.defaultSearchSuggestionsEnabled
|
||||
@AppStorage(BrowserDevToolsButtonDebugSettings.iconNameKey) private var devToolsIconNameRaw = BrowserDevToolsButtonDebugSettings.defaultIcon.rawValue
|
||||
@AppStorage(BrowserDevToolsButtonDebugSettings.iconColorKey) private var devToolsIconColorRaw = BrowserDevToolsButtonDebugSettings.defaultColor.rawValue
|
||||
@AppStorage(BrowserToolbarAccessorySpacingDebugSettings.key) private var browserToolbarAccessorySpacingRaw = BrowserToolbarAccessorySpacingDebugSettings.defaultSpacing
|
||||
@AppStorage(BrowserProfilePopoverDebugSettings.horizontalPaddingKey)
|
||||
private var browserProfilePopoverHorizontalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultHorizontalPadding
|
||||
@AppStorage(BrowserProfilePopoverDebugSettings.verticalPaddingKey)
|
||||
private var browserProfilePopoverVerticalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultVerticalPadding
|
||||
@AppStorage(BrowserThemeSettings.modeKey) private var browserThemeModeRaw = BrowserThemeSettings.defaultMode.rawValue
|
||||
@AppStorage(BrowserImportHintSettings.variantKey) private var browserImportHintVariantRaw = BrowserImportHintSettings.defaultVariant.rawValue
|
||||
@AppStorage(BrowserImportHintSettings.showOnBlankTabsKey) private var showBrowserImportHintOnBlankTabs = BrowserImportHintSettings.defaultShowOnBlankTabs
|
||||
|
|
@ -337,6 +381,18 @@ struct BrowserPanelView: View {
|
|||
)
|
||||
}
|
||||
|
||||
private var browserToolbarAccessorySpacing: CGFloat {
|
||||
CGFloat(BrowserToolbarAccessorySpacingDebugSettings.resolved(browserToolbarAccessorySpacingRaw))
|
||||
}
|
||||
|
||||
private var browserProfilePopoverHorizontalPadding: CGFloat {
|
||||
CGFloat(BrowserProfilePopoverDebugSettings.resolvedHorizontalPadding(browserProfilePopoverHorizontalPaddingRaw))
|
||||
}
|
||||
|
||||
private var browserProfilePopoverVerticalPadding: CGFloat {
|
||||
CGFloat(BrowserProfilePopoverDebugSettings.resolvedVerticalPadding(browserProfilePopoverVerticalPaddingRaw))
|
||||
}
|
||||
|
||||
private var browserChromeBackground: Color {
|
||||
Color(nsColor: browserChromeStyle.backgroundColor)
|
||||
}
|
||||
|
|
@ -475,6 +531,9 @@ struct BrowserPanelView: View {
|
|||
UserDefaults.standard.register(defaults: [
|
||||
BrowserSearchSettings.searchEngineKey: BrowserSearchSettings.defaultSearchEngine.rawValue,
|
||||
BrowserSearchSettings.searchSuggestionsEnabledKey: BrowserSearchSettings.defaultSearchSuggestionsEnabled,
|
||||
BrowserToolbarAccessorySpacingDebugSettings.key: BrowserToolbarAccessorySpacingDebugSettings.defaultSpacing,
|
||||
BrowserProfilePopoverDebugSettings.horizontalPaddingKey: BrowserProfilePopoverDebugSettings.defaultHorizontalPadding,
|
||||
BrowserProfilePopoverDebugSettings.verticalPaddingKey: BrowserProfilePopoverDebugSettings.defaultVerticalPadding,
|
||||
BrowserThemeSettings.modeKey: BrowserThemeSettings.defaultMode.rawValue,
|
||||
])
|
||||
refreshBrowserChromeStyle()
|
||||
|
|
@ -487,6 +546,18 @@ struct BrowserPanelView: View {
|
|||
if browserImportHintVariantRaw != resolvedHintVariant.rawValue {
|
||||
browserImportHintVariantRaw = resolvedHintVariant.rawValue
|
||||
}
|
||||
let resolvedToolbarAccessorySpacing = BrowserToolbarAccessorySpacingDebugSettings.resolved(browserToolbarAccessorySpacingRaw)
|
||||
if browserToolbarAccessorySpacingRaw != resolvedToolbarAccessorySpacing {
|
||||
browserToolbarAccessorySpacingRaw = resolvedToolbarAccessorySpacing
|
||||
}
|
||||
let resolvedProfilePopoverHorizontalPadding = BrowserProfilePopoverDebugSettings.resolvedHorizontalPadding(browserProfilePopoverHorizontalPaddingRaw)
|
||||
if browserProfilePopoverHorizontalPaddingRaw != resolvedProfilePopoverHorizontalPadding {
|
||||
browserProfilePopoverHorizontalPaddingRaw = resolvedProfilePopoverHorizontalPadding
|
||||
}
|
||||
let resolvedProfilePopoverVerticalPadding = BrowserProfilePopoverDebugSettings.resolvedVerticalPadding(browserProfilePopoverVerticalPaddingRaw)
|
||||
if browserProfilePopoverVerticalPaddingRaw != resolvedProfilePopoverVerticalPadding {
|
||||
browserProfilePopoverVerticalPaddingRaw = resolvedProfilePopoverVerticalPadding
|
||||
}
|
||||
panel.refreshAppearanceDrivenColors()
|
||||
panel.setBrowserThemeMode(browserThemeMode)
|
||||
applyPendingAddressBarFocusRequestIfNeeded()
|
||||
|
|
@ -641,12 +712,14 @@ struct BrowserPanelView: View {
|
|||
.accessibilityIdentifier("BrowserOmnibarPill")
|
||||
.accessibilityLabel("Browser omnibar")
|
||||
|
||||
if shouldShowToolbarImportHintChip {
|
||||
browserImportHintToolbarChip
|
||||
HStack(spacing: browserToolbarAccessorySpacing) {
|
||||
if shouldShowToolbarImportHintChip {
|
||||
browserImportHintToolbarChip
|
||||
}
|
||||
browserProfileButton
|
||||
browserThemeModeButton
|
||||
developerToolsButton
|
||||
}
|
||||
browserProfileButton
|
||||
browserThemeModeButton
|
||||
developerToolsButton
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, addressBarVerticalPadding)
|
||||
|
|
@ -892,7 +965,8 @@ struct BrowserPanelView: View {
|
|||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
.padding(8)
|
||||
.padding(.horizontal, browserProfilePopoverHorizontalPadding)
|
||||
.padding(.vertical, browserProfilePopoverVerticalPadding)
|
||||
.frame(minWidth: 208)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ struct cmuxApp: App {
|
|||
@AppStorage(KeyboardShortcutSettings.Action.prevSidebarTab.defaultsKey) private var prevWorkspaceShortcutData = Data()
|
||||
@AppStorage(KeyboardShortcutSettings.Action.splitRight.defaultsKey) private var splitRightShortcutData = Data()
|
||||
@AppStorage(KeyboardShortcutSettings.Action.splitDown.defaultsKey) private var splitDownShortcutData = Data()
|
||||
@AppStorage(BrowserToolbarAccessorySpacingDebugSettings.key) private var browserToolbarAccessorySpacingRaw = BrowserToolbarAccessorySpacingDebugSettings.defaultSpacing
|
||||
@AppStorage(KeyboardShortcutSettings.Action.toggleBrowserDeveloperTools.defaultsKey)
|
||||
private var toggleBrowserDeveloperToolsShortcutData = Data()
|
||||
@AppStorage(KeyboardShortcutSettings.Action.showBrowserJavaScriptConsole.defaultsKey)
|
||||
|
|
@ -39,6 +40,10 @@ struct cmuxApp: App {
|
|||
@AppStorage(KeyboardShortcutSettings.Action.closeWorkspace.defaultsKey) private var closeWorkspaceShortcutData = Data()
|
||||
@NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
|
||||
|
||||
private var browserToolbarAccessorySpacing: Int {
|
||||
BrowserToolbarAccessorySpacingDebugSettings.resolved(browserToolbarAccessorySpacingRaw)
|
||||
}
|
||||
|
||||
init() {
|
||||
if SocketControlSettings.shouldBlockUntaggedDebugLaunch() {
|
||||
Self.terminateForMissingLaunchTag()
|
||||
|
|
@ -341,6 +346,15 @@ struct cmuxApp: App {
|
|||
BrowserImportHintDebugWindowController.shared.show()
|
||||
}
|
||||
|
||||
Button(
|
||||
String(
|
||||
localized: "debug.menu.browserProfilePopoverDebug",
|
||||
defaultValue: "Browser Profile Popover Debug…"
|
||||
)
|
||||
) {
|
||||
BrowserProfilePopoverDebugWindowController.shared.show()
|
||||
}
|
||||
|
||||
Button("Settings/About Titlebar Debug…") {
|
||||
SettingsAboutTitlebarDebugWindowController.shared.show()
|
||||
}
|
||||
|
|
@ -365,6 +379,29 @@ struct cmuxApp: App {
|
|||
}
|
||||
}
|
||||
|
||||
Menu(
|
||||
String(
|
||||
localized: "debug.menu.browserToolbarButtonSpacing",
|
||||
defaultValue: "Browser Toolbar Button Spacing"
|
||||
)
|
||||
) {
|
||||
ForEach(BrowserToolbarAccessorySpacingDebugSettings.supportedValues, id: \.self) { spacing in
|
||||
Button {
|
||||
browserToolbarAccessorySpacingRaw = spacing
|
||||
} label: {
|
||||
if browserToolbarAccessorySpacing == spacing {
|
||||
Label {
|
||||
Text(verbatim: "\(spacing)")
|
||||
} icon: {
|
||||
Image(systemName: "checkmark")
|
||||
}
|
||||
} else {
|
||||
Text(verbatim: "\(spacing)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Toggle("Always Show Shortcut Hints", isOn: $alwaysShowShortcutHints)
|
||||
Toggle(
|
||||
String(localized: "debug.devBuildBanner.show", defaultValue: "Show Dev Build Banner"),
|
||||
|
|
@ -1065,6 +1102,7 @@ struct cmuxApp: App {
|
|||
|
||||
private func openAllDebugWindows() {
|
||||
BrowserImportHintDebugWindowController.shared.show()
|
||||
BrowserProfilePopoverDebugWindowController.shared.show()
|
||||
SettingsAboutTitlebarDebugWindowController.shared.show()
|
||||
SidebarDebugWindowController.shared.show()
|
||||
BackgroundDebugWindowController.shared.show()
|
||||
|
|
@ -1698,6 +1736,14 @@ private struct DebugWindowControlsView: View {
|
|||
Button("Browser Import Hint Debug…") {
|
||||
BrowserImportHintDebugWindowController.shared.show()
|
||||
}
|
||||
Button(
|
||||
String(
|
||||
localized: "debug.menu.browserProfilePopoverDebug",
|
||||
defaultValue: "Browser Profile Popover Debug…"
|
||||
)
|
||||
) {
|
||||
BrowserProfilePopoverDebugWindowController.shared.show()
|
||||
}
|
||||
Button("Settings/About Titlebar Debug…") {
|
||||
SettingsAboutTitlebarDebugWindowController.shared.show()
|
||||
}
|
||||
|
|
@ -1712,6 +1758,7 @@ private struct DebugWindowControlsView: View {
|
|||
}
|
||||
Button("Open All Debug Windows") {
|
||||
BrowserImportHintDebugWindowController.shared.show()
|
||||
BrowserProfilePopoverDebugWindowController.shared.show()
|
||||
SettingsAboutTitlebarDebugWindowController.shared.show()
|
||||
SidebarDebugWindowController.shared.show()
|
||||
BackgroundDebugWindowController.shared.show()
|
||||
|
|
@ -1949,6 +1996,205 @@ private final class BrowserImportHintDebugWindowController: NSWindowController,
|
|||
}
|
||||
}
|
||||
|
||||
private final class BrowserProfilePopoverDebugWindowController: NSWindowController, NSWindowDelegate {
|
||||
static let shared = BrowserProfilePopoverDebugWindowController()
|
||||
|
||||
private init() {
|
||||
let window = NSPanel(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 360, height: 340),
|
||||
styleMask: [.titled, .closable, .utilityWindow],
|
||||
backing: .buffered,
|
||||
defer: false
|
||||
)
|
||||
window.title = String(
|
||||
localized: "debug.windows.browserProfilePopover.title",
|
||||
defaultValue: "Browser Profile Popover Debug"
|
||||
)
|
||||
window.titleVisibility = .visible
|
||||
window.titlebarAppearsTransparent = false
|
||||
window.isMovableByWindowBackground = true
|
||||
window.isReleasedWhenClosed = false
|
||||
window.identifier = NSUserInterfaceItemIdentifier("cmux.browserProfilePopoverDebug")
|
||||
window.center()
|
||||
window.contentView = NSHostingView(rootView: BrowserProfilePopoverDebugView())
|
||||
AppDelegate.shared?.applyWindowDecorations(to: window)
|
||||
super.init(window: window)
|
||||
window.delegate = self
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func show() {
|
||||
window?.center()
|
||||
window?.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
}
|
||||
|
||||
private struct BrowserProfilePopoverDebugView: View {
|
||||
@AppStorage(BrowserProfilePopoverDebugSettings.horizontalPaddingKey)
|
||||
private var horizontalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultHorizontalPadding
|
||||
@AppStorage(BrowserProfilePopoverDebugSettings.verticalPaddingKey)
|
||||
private var verticalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultVerticalPadding
|
||||
|
||||
private var horizontalPaddingBinding: Binding<Double> {
|
||||
Binding(
|
||||
get: { BrowserProfilePopoverDebugSettings.resolvedHorizontalPadding(horizontalPaddingRaw) },
|
||||
set: { horizontalPaddingRaw = BrowserProfilePopoverDebugSettings.resolvedHorizontalPadding($0) }
|
||||
)
|
||||
}
|
||||
|
||||
private var verticalPaddingBinding: Binding<Double> {
|
||||
Binding(
|
||||
get: { BrowserProfilePopoverDebugSettings.resolvedVerticalPadding(verticalPaddingRaw) },
|
||||
set: { verticalPaddingRaw = BrowserProfilePopoverDebugSettings.resolvedVerticalPadding($0) }
|
||||
)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(alignment: .leading, spacing: 14) {
|
||||
Text(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.heading",
|
||||
defaultValue: "Browser Profile Popover"
|
||||
)
|
||||
)
|
||||
.font(.headline)
|
||||
|
||||
Text(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.note",
|
||||
defaultValue: "Tune the profile popover padding live while comparing it against the browser toolbar menu."
|
||||
)
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
GroupBox(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.group.padding",
|
||||
defaultValue: "Padding"
|
||||
)
|
||||
) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
sliderRow(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.label.horizontal",
|
||||
defaultValue: "Horizontal"
|
||||
),
|
||||
value: horizontalPaddingBinding,
|
||||
range: BrowserProfilePopoverDebugSettings.horizontalPaddingRange
|
||||
)
|
||||
sliderRow(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.label.vertical",
|
||||
defaultValue: "Vertical"
|
||||
),
|
||||
value: verticalPaddingBinding,
|
||||
range: BrowserProfilePopoverDebugSettings.verticalPaddingRange
|
||||
)
|
||||
}
|
||||
.padding(.top, 2)
|
||||
}
|
||||
|
||||
GroupBox(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.group.preview",
|
||||
defaultValue: "Preview"
|
||||
)
|
||||
) {
|
||||
profilePopoverPreview
|
||||
.padding(.top, 2)
|
||||
}
|
||||
|
||||
HStack(spacing: 12) {
|
||||
Button(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.reset",
|
||||
defaultValue: "Reset"
|
||||
)
|
||||
) {
|
||||
horizontalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultHorizontalPadding
|
||||
verticalPaddingRaw = BrowserProfilePopoverDebugSettings.defaultVerticalPadding
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
String(
|
||||
localized: "debug.browserProfilePopover.liveNote",
|
||||
defaultValue: "Changes apply live to the browser profile popover."
|
||||
)
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
.padding(16)
|
||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||
}
|
||||
|
||||
private var profilePopoverPreview: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(String(localized: "browser.profile.menu.title", defaultValue: "Profiles"))
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.foregroundStyle(.secondary)
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "checkmark")
|
||||
.font(.system(size: 10, weight: .semibold))
|
||||
.frame(width: 12, alignment: .center)
|
||||
Text(String(localized: "browser.profile.default", defaultValue: "Default"))
|
||||
.font(.system(size: 12))
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.frame(height: 24)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 6, style: .continuous)
|
||||
.fill(Color.primary.opacity(0.12))
|
||||
)
|
||||
}
|
||||
|
||||
Divider()
|
||||
|
||||
Text(String(localized: "browser.profile.new", defaultValue: "New Profile..."))
|
||||
.font(.system(size: 12))
|
||||
|
||||
Text(String(localized: "menu.view.importFromBrowser", defaultValue: "Import From Browser…"))
|
||||
.font(.system(size: 12))
|
||||
}
|
||||
.padding(.horizontal, BrowserProfilePopoverDebugSettings.resolvedHorizontalPadding(horizontalPaddingRaw))
|
||||
.padding(.vertical, BrowserProfilePopoverDebugSettings.resolvedVerticalPadding(verticalPaddingRaw))
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 16, style: .continuous)
|
||||
.fill(Color(nsColor: .windowBackgroundColor))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 16, style: .continuous)
|
||||
.stroke(Color.primary.opacity(0.08))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private func sliderRow(_ label: String, value: Binding<Double>, range: ClosedRange<Double>) -> some View {
|
||||
HStack(spacing: 8) {
|
||||
Text(label)
|
||||
Slider(value: value, in: range, step: 1)
|
||||
Text(String(format: "%.0f", value.wrappedValue))
|
||||
.font(.caption)
|
||||
.monospacedDigit()
|
||||
.frame(width: 32, alignment: .trailing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct BrowserImportHintDebugView: View {
|
||||
@AppStorage(BrowserImportHintSettings.variantKey)
|
||||
private var variantRaw = BrowserImportHintSettings.defaultVariant.rawValue
|
||||
|
|
@ -3369,6 +3615,7 @@ struct SettingsView: View {
|
|||
@AppStorage("sidebarTintHexLight") private var sidebarTintHexLight: String?
|
||||
@AppStorage("sidebarTintHexDark") private var sidebarTintHexDark: String?
|
||||
@AppStorage("sidebarTintOpacity") private var sidebarTintOpacity = SidebarTintDefaults.opacity
|
||||
|
||||
@ObservedObject private var notificationStore = TerminalNotificationStore.shared
|
||||
@State private var shortcutResetToken = UUID()
|
||||
@State private var topBlurOpacity: Double = 0
|
||||
|
|
|
|||
|
|
@ -284,6 +284,39 @@ final class BrowserImportMappingTests: XCTestCase {
|
|||
XCTAssertTrue(lines.contains("Created cmux profiles: You, austin"))
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testImportWizardCanBeConstructedForSettingsChoosePath() {
|
||||
let destinationProfiles = [
|
||||
BrowserProfileDefinition(
|
||||
id: UUID(uuidString: "52B43C05-4A1D-45D3-8FD5-9EF94952E445")!,
|
||||
displayName: "Default",
|
||||
createdAt: .distantPast,
|
||||
isBuiltInDefault: true
|
||||
)
|
||||
]
|
||||
let browser = makeInstalledBrowserCandidate(
|
||||
descriptorID: "google-chrome",
|
||||
displayName: "Chrome",
|
||||
profiles: [
|
||||
makeSourceProfile(displayName: "Default", path: "/tmp/browser-import-chrome-default", isDefault: true),
|
||||
makeSourceProfile(displayName: "Profile 1", path: "/tmp/browser-import-chrome-profile-1", isDefault: false),
|
||||
]
|
||||
)
|
||||
|
||||
let window = BrowserDataImportCoordinator.shared.debugMakeImportWizardWindow(
|
||||
browsers: [browser],
|
||||
destinationProfiles: destinationProfiles,
|
||||
defaultDestinationProfileID: destinationProfiles[0].id
|
||||
)
|
||||
defer {
|
||||
window.orderOut(nil)
|
||||
window.close()
|
||||
}
|
||||
|
||||
XCTAssertEqual(window.title, "Import Browser Data")
|
||||
XCTAssertNotNil(window.contentView)
|
||||
}
|
||||
|
||||
private func makeSourceProfile(displayName: String, path: String, isDefault: Bool) -> InstalledBrowserProfile {
|
||||
InstalledBrowserProfile(
|
||||
displayName: displayName,
|
||||
|
|
@ -291,4 +324,32 @@ final class BrowserImportMappingTests: XCTestCase {
|
|||
isDefault: isDefault
|
||||
)
|
||||
}
|
||||
|
||||
private func makeInstalledBrowserCandidate(
|
||||
descriptorID: String,
|
||||
displayName: String,
|
||||
profiles: [InstalledBrowserProfile]
|
||||
) -> InstalledBrowserCandidate {
|
||||
let descriptor = try! XCTUnwrap(InstalledBrowserDetector.allBrowserDescriptors.first(where: { $0.id == descriptorID }))
|
||||
return InstalledBrowserCandidate(
|
||||
descriptor: BrowserImportBrowserDescriptor(
|
||||
id: descriptor.id,
|
||||
displayName: displayName,
|
||||
family: descriptor.family,
|
||||
tier: descriptor.tier,
|
||||
bundleIdentifiers: descriptor.bundleIdentifiers,
|
||||
appNames: descriptor.appNames,
|
||||
dataRootRelativePaths: descriptor.dataRootRelativePaths,
|
||||
dataArtifactRelativePaths: descriptor.dataArtifactRelativePaths,
|
||||
supportsDataOnlyDetection: descriptor.supportsDataOnlyDetection
|
||||
),
|
||||
resolvedFamily: descriptor.family,
|
||||
homeDirectoryURL: URL(fileURLWithPath: NSHomeDirectory(), isDirectory: true),
|
||||
appURL: nil,
|
||||
dataRootURL: URL(fileURLWithPath: "/tmp/browser-import-\(descriptorID)", isDirectory: true),
|
||||
profiles: profiles,
|
||||
detectionSignals: ["test"],
|
||||
detectionScore: 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1470,6 +1470,56 @@ final class BrowserDevToolsButtonDebugSettingsTests: XCTestCase {
|
|||
)
|
||||
}
|
||||
|
||||
func testBrowserToolbarAccessorySpacingDefaultsToTwoWhenUnset() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.removeObject(forKey: BrowserToolbarAccessorySpacingDebugSettings.key)
|
||||
|
||||
XCTAssertEqual(
|
||||
BrowserToolbarAccessorySpacingDebugSettings.current(defaults: defaults),
|
||||
BrowserToolbarAccessorySpacingDebugSettings.defaultSpacing
|
||||
)
|
||||
}
|
||||
|
||||
func testBrowserToolbarAccessorySpacingFallsBackToDefaultForUnsupportedValue() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.set(99, forKey: BrowserToolbarAccessorySpacingDebugSettings.key)
|
||||
|
||||
XCTAssertEqual(
|
||||
BrowserToolbarAccessorySpacingDebugSettings.current(defaults: defaults),
|
||||
BrowserToolbarAccessorySpacingDebugSettings.defaultSpacing
|
||||
)
|
||||
}
|
||||
|
||||
func testBrowserProfilePopoverPaddingDefaultsWhenUnset() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.removeObject(forKey: BrowserProfilePopoverDebugSettings.horizontalPaddingKey)
|
||||
defaults.removeObject(forKey: BrowserProfilePopoverDebugSettings.verticalPaddingKey)
|
||||
|
||||
XCTAssertEqual(
|
||||
BrowserProfilePopoverDebugSettings.currentHorizontalPadding(defaults: defaults),
|
||||
BrowserProfilePopoverDebugSettings.defaultHorizontalPadding
|
||||
)
|
||||
XCTAssertEqual(
|
||||
BrowserProfilePopoverDebugSettings.currentVerticalPadding(defaults: defaults),
|
||||
BrowserProfilePopoverDebugSettings.defaultVerticalPadding
|
||||
)
|
||||
}
|
||||
|
||||
func testBrowserProfilePopoverPaddingFallsBackForUnsupportedValues() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.set(-3, forKey: BrowserProfilePopoverDebugSettings.horizontalPaddingKey)
|
||||
defaults.set(999, forKey: BrowserProfilePopoverDebugSettings.verticalPaddingKey)
|
||||
|
||||
XCTAssertEqual(
|
||||
BrowserProfilePopoverDebugSettings.currentHorizontalPadding(defaults: defaults),
|
||||
BrowserProfilePopoverDebugSettings.defaultHorizontalPadding
|
||||
)
|
||||
XCTAssertEqual(
|
||||
BrowserProfilePopoverDebugSettings.currentVerticalPadding(defaults: defaults),
|
||||
BrowserProfilePopoverDebugSettings.defaultVerticalPadding
|
||||
)
|
||||
}
|
||||
|
||||
func testCopyPayloadUsesPersistedValues() {
|
||||
let defaults = makeIsolatedDefaults()
|
||||
defaults.set(BrowserDevToolsIconOption.scope.rawValue, forKey: BrowserDevToolsButtonDebugSettings.iconNameKey)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue