Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct TerminalPickerMenuContent {
}
))
}
} else {
} else if value.showsBrowserStreamUpdateHint {
sections.append(UIMenu(
title: L10n.string("mobile.browserStream.menuTitle", defaultValue: "Mac Browsers"),
options: .displayInline,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ struct TerminalPickerMenuValue: Equatable {
let hasActiveBrowser: Bool
let browserStreamRows: [BrowserStreamPickerRow]
let supportsBrowserStream: Bool
/// Whether the current connection has published an authoritative browser
/// capability snapshot. A missing capability while reconnecting is unknown,
/// not evidence that the Mac needs an update.
let browserStreamSupportKnown: Bool
let activeBrowserStreamPanelID: String?
/// The streamed tab the phone-local browser shows "On iPhone", if any.
let onDeviceBrowserStreamPanelID: String?
Expand All @@ -38,6 +42,7 @@ struct TerminalPickerMenuValue: Equatable {
hasActiveBrowser: Bool,
browserStreamRows: [BrowserStreamPickerRow] = [],
supportsBrowserStream: Bool = false,
browserStreamSupportKnown: Bool = false,
activeBrowserStreamPanelID: String? = nil,
onDeviceBrowserStreamPanelID: String? = nil,
simulatorStreamRows: [SimulatorStreamPickerRow] = [],
Expand All @@ -60,6 +65,7 @@ struct TerminalPickerMenuValue: Equatable {
self.hasActiveBrowser = hasActiveBrowser
self.browserStreamRows = browserStreamRows
self.supportsBrowserStream = supportsBrowserStream
self.browserStreamSupportKnown = browserStreamSupportKnown
self.activeBrowserStreamPanelID = activeBrowserStreamPanelID
self.onDeviceBrowserStreamPanelID = onDeviceBrowserStreamPanelID
self.simulatorStreamRows = simulatorStreamRows
Expand Down Expand Up @@ -108,6 +114,12 @@ struct TerminalPickerMenuValue: Equatable {
hasActiveBrowser && checkedBrowserStreamPanelID == nil
}

/// The update hint is valid only after a connected Mac has reported its
/// capabilities. Reconnect teardown clears those capabilities temporarily.
var showsBrowserStreamUpdateHint: Bool {
browserStreamSupportKnown && !supportsBrowserStream
}

var terminalRows: [TerminalPickerMenuRow] {
rows.filter { if case .terminal = $0.id { true } else { false } }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ struct WorkspaceDetailView: View {
hasActiveBrowser: activeBrowser != nil,
browserStreamRows: browserStreamStore.panels(in: workspace.rpcWorkspaceID.rawValue).map(BrowserStreamPickerRow.init),
supportsBrowserStream: store.supportsBrowserStream(inWorkspace: workspace.id),
browserStreamSupportKnown: effectiveConnectionStatus == .connected,
activeBrowserStreamPanelID: activeBrowserStream?.id,
onDeviceBrowserStreamPanelID: activeBrowser?.linkedStreamPanelID,
simulatorStreamRows: simulatorStreamStore.panels(in: workspace.rpcWorkspaceID.rawValue).map(SimulatorStreamPickerRow.init),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,37 @@ import UIKit
#expect(selected == ["first:terminal-1", "second:terminal-1"])
}

@Test func reconnectingMacDoesNotShowUnsupportedBrowserHint() {
let reconnecting = TerminalPickerMenuValue(
liveTerminals: [],
selectedID: nil,
canCreateWorkspace: true,
hasActiveBrowser: false,
supportsBrowserStream: false,
browserStreamSupportKnown: false
)
let unsupported = TerminalPickerMenuValue(
liveTerminals: [],
selectedID: nil,
canCreateWorkspace: true,
hasActiveBrowser: false,
supportsBrowserStream: false,
browserStreamSupportKnown: true
)

let reconnectingActions = menuActions(in: TerminalPickerMenuContent(
value: reconnecting,
actions: actions()
).makeElements())
let unsupportedActions = menuActions(in: TerminalPickerMenuContent(
value: unsupported,
actions: actions()
).makeElements())

#expect(!reconnectingActions.contains { $0.identifier.rawValue == "BrowserStreamMacUpdateHint" })
#expect(unsupportedActions.contains { $0.identifier.rawValue == "BrowserStreamMacUpdateHint" })
}

private func menuValue(generation: Int, grouped: Bool = false) -> TerminalPickerMenuValue {
var terminals = [MobileTerminalPreview(id: "terminal-1", name: "Terminal \(generation)")]
if generation > 0 { terminals.append(MobileTerminalPreview(id: "terminal-2", name: "Added terminal")) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@ import Testing
#expect(legacyMac.macSurfaceRows.map(\.id) == [.macSurface(browser.id), .macSurface(markdown.id)])
}

@Test func browserUpdateHintRequiresAConnectedCapabilitySnapshot() {
func value(
supportsBrowserStream: Bool,
browserStreamSupportKnown: Bool
) -> TerminalPickerMenuValue {
TerminalPickerMenuValue(
liveTerminals: [],
selectedID: nil,
canCreateWorkspace: true,
hasActiveBrowser: false,
supportsBrowserStream: supportsBrowserStream,
browserStreamSupportKnown: browserStreamSupportKnown
)
}

// An empty capability set while disconnected/reconnecting is unknown,
// so it must not claim that the Mac needs an update.
#expect(value(supportsBrowserStream: false, browserStreamSupportKnown: false).showsBrowserStreamUpdateHint == false)
// Once connected, the same missing capability is an authoritative
// unsupported-host result and the hint is appropriate.
#expect(value(supportsBrowserStream: false, browserStreamSupportKnown: true).showsBrowserStreamUpdateHint)
#expect(value(supportsBrowserStream: true, browserStreamSupportKnown: true).showsBrowserStreamUpdateHint == false)
}

/// SSH computers' browser tabs are not on a Mac, so the switcher's
/// browser section is named by the computer's kind.
@Test func browserSectionIsNamedByComputerKind() {
Expand Down
Loading