Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -3047,7 +3047,21 @@ class BrowserViewController: UIViewController,
if data.isTranslated, let langCode = data.translatedToLanguage {
configureShowOriginalHeader(for: alert, languageCode: langCode)
} else {
alert.title = .Translations.LanguagePicker.Title
let title: String = .Translations.LanguagePicker.Title
let attributedTitleKey = "attributedTitle"
alert.title = title
alert.setValue(
NSAttributedString(
string: title,
attributes: [
.font: DefaultDynamicFontHelper.preferredBoldFont(
withTextStyle: .headline,
size: UIFont.labelFontSize
)
]
),
forKey: attributedTitleKey
)
}

data.languages.forEach { code in
Expand Down Expand Up @@ -3084,7 +3098,8 @@ class BrowserViewController: UIViewController,
if let sourceButton {
popover.sourceView = sourceButton
popover.sourceRect = sourceButton.bounds
} else {
popover.permittedArrowDirections = [.up, .down]
} else if #unavailable(iOS 26) {
popover.sourceView = view
popover.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
popover.permittedArrowDirections = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,17 @@ class MainMenuCoordinator: BaseCoordinator, FeatureFlaggable {
let manager = PreferredTranslationLanguagesManager(prefs: prefs)
let supported = await ASTranslationModelsFetcher.shared.fetchSupportedTargetLanguages()
let languages = manager.preferredLanguages(supportedTargetLanguages: supported)
if isSingleLanguageFlow, let language = languages.first, !isTranslated {
let pageLanguage = try? await TranslationsService().detectPageLanguage(for: windowUUID)
let filteredLanguages = languages.filter { $0 != pageLanguage }
if isSingleLanguageFlow, let language = filteredLanguages.first, !isTranslated {
store.dispatch(TranslationLanguageSelectedAction(
windowUUID: windowUUID,
targetLanguage: language,
actionType: TranslationsActionType.didSelectTargetLanguage
))
} else {
store.dispatch(GeneralBrowserAction(
translationLanguages: languages,
translationLanguages: filteredLanguages,
isPageTranslated: isTranslated,
translatedToLanguage: translatedLanguage,
windowUUID: windowUUID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ final class TranslationsService: TranslationsServiceProtocol {
/// Attempts to detect the language of the currently displayed page.
/// Returns a BCP-47 language tag (e.g. "en", "fr") on success.
/// Otherwise throws a typed `TranslationsServiceError`.
private func detectPageLanguage(for windowUUID: WindowUUID) async throws -> String {
func detectPageLanguage(for windowUUID: WindowUUID) async throws -> String {
let webView = try currentWebView(for: windowUUID)
let source = WebViewLanguageSampleSource(webView: webView)
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ protocol TranslationsServiceProtocol {
func discardTranslations(for windowUUID: WindowUUID) async throws
/// Returns the unique set of languages that can be used as translation targets.
func fetchSupportedTargetLanguages() async -> [String]
/// Returns the BCP-47 language code of the currently displayed page (e.g. "ja", "en").
func detectPageLanguage(for windowUUID: WindowUUID) async throws -> String
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,22 @@ final class TranslationsMiddleware: FeatureFlaggable {
let manager = PreferredTranslationLanguagesManager(prefs: profile.prefs)
let supported = await translationsService.fetchSupportedTargetLanguages()
let languages = manager.preferredLanguages(supportedTargetLanguages: supported)
store.dispatch(GeneralBrowserAction(
buttonTapped: capturedButton,
translationLanguages: languages,
windowUUID: action.windowUUID,
actionType: GeneralBrowserActionType.showTranslationLanguagePicker
))
let pageLanguage = try? await translationsService.detectPageLanguage(for: action.windowUUID)
let filteredLanguages = languages.filter { $0 != pageLanguage }
if !translationConfiguration.isMultiLanguageFlow, let singleLanguage = filteredLanguages.first {
store.dispatch(TranslationLanguageSelectedAction(
windowUUID: action.windowUUID,
targetLanguage: singleLanguage,
actionType: TranslationsActionType.didSelectTargetLanguage
))
} else {
store.dispatch(GeneralBrowserAction(
buttonTapped: capturedButton,
translationLanguages: filteredLanguages,
windowUUID: action.windowUUID,
actionType: GeneralBrowserActionType.showTranslationLanguagePicker
))
}
}
} else if translationConfiguration.state == .inactive {
guard let deviceLanguage = Locale.current.languageCode else { return }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ final class MockTranslationsService: TranslationsServiceProtocol {
private let translateResult: Result<Void, Error>
private let firstResponseReceivedResult: Result<Void, Error>
private let discardResult: Result<Void, Error>
private let detectPageLanguageResult: Result<String, Error>

// MARK: - Init
init(
shouldOfferTranslationResult: Result<Bool, Error> = .success(false),
translateResult: Result<Void, Error> = .success(()),
firstResponseReceivedResult: Result<Void, Error> = .success(()),
discardResult: Result<Void, Error> = .success(())
discardResult: Result<Void, Error> = .success(()),
detectPageLanguageResult: Result<String, Error> = .success("en")
) {
self.shouldOfferTranslationResult = shouldOfferTranslationResult
self.translateResult = translateResult
self.firstResponseReceivedResult = firstResponseReceivedResult
self.discardResult = discardResult
self.detectPageLanguageResult = detectPageLanguageResult
}

// MARK: - TranslationsServiceProtocol
Expand Down Expand Up @@ -52,4 +55,8 @@ final class MockTranslationsService: TranslationsServiceProtocol {
func fetchSupportedTargetLanguages() async -> [String] {
return []
}

func detectPageLanguage(for windowUUID: WindowUUID) async throws -> String {
return try detectPageLanguageResult.get()
}
}
Loading