From 681a0b87e72f99908f8b083d961733ce57fb6acd Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Sat, 12 Oct 2024 14:50:25 -0400 Subject: [PATCH 01/76] Update SettingsViewController.swift Updated the settings page to now behave more like IOS settings app where we have header buttons and drop down menus --- .../Settings/SettingsViewController.swift | 95 ++++++++++++------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index ffd310357..64b8e3c9f 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -7,11 +7,10 @@ // import UIKit - import AppCenterAnalytics class SettingsViewController: BaseTableViewController { - + private enum Section: Int, CaseIterable { case general = 0 case audio = 1 @@ -37,7 +36,7 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: 3, section: Section.general.rawValue): "volumeSettings", IndexPath(row: 4, section: Section.general.rawValue): "manageDevices", IndexPath(row: 5, section: Section.general.rawValue): "siriShortcuts", - + IndexPath(row: 0, section: Section.audio.rawValue): "mixAudio", IndexPath(row: CalloutsRow.all.rawValue, section: Section.callouts.rawValue): "allCallouts", @@ -45,7 +44,7 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: CalloutsRow.mobility.rawValue, section: Section.callouts.rawValue): "mobilityCallouts", IndexPath(row: CalloutsRow.beacon.rawValue, section: Section.callouts.rawValue): "beaconCallouts", IndexPath(row: CalloutsRow.shake.rawValue, section: Section.callouts.rawValue): "shakeCallouts", - + IndexPath(row: 0, section: Section.streetPreview.rawValue): "streetPreview", IndexPath(row: 0, section: Section.troubleshooting.rawValue): "troubleshooting", IndexPath(row: 0, section: Section.about.rawValue): "about", @@ -62,6 +61,19 @@ class SettingsViewController: BaseTableViewController { // MARK: Properties @IBOutlet weak var largeBannerContainerView: UIView! + + private var expandedSections: Set = [] + + // Section Descriptions + private static let sectionDescriptions: [Section: String] = [ + .general: "General settings for the app.", + .audio: "Control how audio interacts with other media.", + .callouts: "Manage the callouts that help navigate.", + .streetPreview: "Settings for including unnamed roads.", + .troubleshooting: "Options for troubleshooting the app.", + .about: "Information about the app.", + .telemetry: "Manage data collection and privacy." + ] // MARK: View Life Cycle @@ -73,6 +85,7 @@ class SettingsViewController: BaseTableViewController { GDATelemetry.trackScreenView("settings") self.title = GDLocalizedString("settings.screen_title") + expandedSections = [] // Initialize or reset expanded sections } override func numberOfSections(in tableView: UITableView) -> Int { @@ -83,28 +96,37 @@ class SettingsViewController: BaseTableViewController { guard let sectionType = Section(rawValue: section) else { return 0 } switch sectionType { - case .general: return 6 - case .audio: return 1 - case .callouts: return SettingsContext.shared.automaticCalloutsEnabled ? 5 : 1 - case .streetPreview: return 1 - case .troubleshooting: return 1 - case .about: return 1 - case .telemetry: return 1 + case .general: return expandedSections.contains(section) ? 6 : 0 + case .audio: return expandedSections.contains(section) ? 1 : 0 + case .callouts: + return SettingsContext.shared.automaticCalloutsEnabled && expandedSections.contains(section) ? 5 : 0 + case .streetPreview, .troubleshooting, .about, .telemetry: + return expandedSections.contains(section) ? 1 : 0 } } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + // Return a default height for cells + return expandedSections.contains(indexPath.section) ? UITableView.automaticDimension : 0 + } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard expandedSections.contains(indexPath.section) else { + return UITableViewCell() // Return an empty cell if the section is not expanded + } + let identifier = SettingsViewController.cellIdentifiers[indexPath] guard let sectionType = Section(rawValue: indexPath.section) else { return tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) } + // Configure the cell based on the section type switch sectionType { case .callouts: let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! CalloutSettingsCellView cell.delegate = self - + if let rowType = CalloutsRow(rawValue: indexPath.row) { switch rowType { case .all: cell.type = .all @@ -114,13 +136,11 @@ class SettingsViewController: BaseTableViewController { case .shake: cell.type = .shake } } - return cell case .telemetry: let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! TelemetrySettingsTableViewCell cell.parent = self - return cell case .audio: @@ -131,11 +151,8 @@ class SettingsViewController: BaseTableViewController { default: return tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) } - } - // MARK: UITableViewDataSource - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } @@ -153,6 +170,11 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } + // Return description for expanded sections + if expandedSections.contains(section) { + return SettingsViewController.sectionDescriptions[sectionType] + } + switch sectionType { case .audio: return GDLocalizedString("settings.audio.mix_with_others.description") case .streetPreview: return GDLocalizedString("preview.include_unnamed_roads.subtitle") @@ -160,30 +182,42 @@ class SettingsViewController: BaseTableViewController { default: return nil } } + + override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { + guard let header = view as? UITableViewHeaderFooterView else { return } + header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleHeaderTap(_:)))) + header.tag = section // Set the tag to identify the section + + header.textLabel?.textColor = .systemBlue // Change text color + header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Change font size + } + @objc private func handleHeaderTap(_ gesture: UITapGestureRecognizer) { + guard let header = gesture.view as? UITableViewHeaderFooterView else { return } + let section = header.tag + + // Toggle the section's expanded state + if expandedSections.contains(section) { + expandedSections.remove(section) + tableView.reloadSections(IndexSet(integer: section), with: .automatic) + } else { + expandedSections.insert(section) + tableView.reloadSections(IndexSet(integer: section), with: .automatic) + } + } } extension SettingsViewController: MixAudioSettingCellDelegate { func onSettingValueChanged(_ cell: MixAudioSettingCell, settingSwitch: UISwitch) { - // Note: The UI for this setting is "Enable Media Controls" but the setting is stored as - // "Mixes with Others" (the inverse of "Enable Media Controls") - guard settingSwitch.isOn else { - // If the setting switch is now off, the user disabled media controls. This doesn't - // require a warning alert, so just set mixesWithOthers to true and return. updateSetting(true) return } - - // Otherwise, the user is turning on media controls, so we need to show a warning to make sure - // they understand what this change means in terms of how other audio apps will stop Soundscape - // from playing. This warning was added based on bug bash feedback on 12/3/20. - // Show an alert indicating that the user can download an enhanced version of the voice in Settings + let alert = UIAlertController(title: GDLocalizedString("general.alert.confirmation_title"), message: GDLocalizedString("setting.audio.mix_with_others.confirmation"), preferredStyle: .alert) let mixAction = UIAlertAction(title: GDLocalizedString("settings.audio.mix_with_others.title"), style: .default) { [weak self] (_) in - // Make the setting switch - turn off mixesWithOthers self?.updateSetting(false) self?.focusOnCell(cell) } @@ -191,12 +225,8 @@ extension SettingsViewController: MixAudioSettingCellDelegate { alert.preferredAction = mixAction alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.cancel"), style: .cancel, handler: { [weak self] (_) in - // Toggle the setting back off settingSwitch.isOn = false - - // Track that the user decided not to enable media controls GDATelemetry.track("settings.mix_audio.cancel", with: ["context": "app_settings"]) - self?.focusOnCell(cell) })) @@ -241,5 +271,4 @@ extension SettingsViewController: LargeBannerContainerView { largeBannerContainerView.setHeight(height) tableView.reloadData() } - } From 0cc26228ad5731b89babf51037198cd16c7e878d Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Sat, 12 Oct 2024 19:02:29 -0400 Subject: [PATCH 02/76] Updated the Settings page to contain cleaner UI --- .../Settings/SettingsViewController.swift | 67 ++++++++++++++----- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index 64b8e3c9f..060af061f 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -106,7 +106,6 @@ class SettingsViewController: BaseTableViewController { } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - // Return a default height for cells return expandedSections.contains(indexPath.section) ? UITableView.automaticDimension : 0 } @@ -122,34 +121,37 @@ class SettingsViewController: BaseTableViewController { } // Configure the cell based on the section type + let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) + cell.backgroundColor = UIColor(named: "CellBackgroundColor") // Set a custom dark background color + switch sectionType { case .callouts: - let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! CalloutSettingsCellView - cell.delegate = self + let calloutCell = cell as! CalloutSettingsCellView + calloutCell.delegate = self if let rowType = CalloutsRow(rawValue: indexPath.row) { switch rowType { - case .all: cell.type = .all - case .poi: cell.type = .poi - case .mobility: cell.type = .mobility - case .beacon: cell.type = .beacon - case .shake: cell.type = .shake + case .all: calloutCell.type = .all + case .poi: calloutCell.type = .poi + case .mobility: calloutCell.type = .mobility + case .beacon: calloutCell.type = .beacon + case .shake: calloutCell.type = .shake } } - return cell + return calloutCell case .telemetry: - let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! TelemetrySettingsTableViewCell - cell.parent = self - return cell + let telemetryCell = cell as! TelemetrySettingsTableViewCell + telemetryCell.parent = self + return telemetryCell case .audio: - let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! MixAudioSettingCell - cell.delegate = self - return cell + let audioCell = cell as! MixAudioSettingCell + audioCell.delegate = self + return audioCell default: - return tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) + return cell } } @@ -188,9 +190,37 @@ class SettingsViewController: BaseTableViewController { header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleHeaderTap(_:)))) header.tag = section // Set the tag to identify the section - header.textLabel?.textColor = .systemBlue // Change text color - header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Change font size + // Customize header title + header.textLabel?.textColor = .white // Change header text color to white for contrast + header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Make the text bold + + // Customize header appearance + header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") // Set a custom darker color + header.layer.borderColor = UIColor.clear.cgColor // Optional: set border color + header.layer.borderWidth = 0.0 // Optional: border width + header.layer.cornerRadius = 8.0 // Set rounded corners + header.layer.masksToBounds = true // Clip content to rounded corners + + // Optional: Add some padding + header.contentView.layoutMargins = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15) + + // Add chevron icon + let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) // Use system image + chevronImageView.tintColor = .white // Set the color for the arrow + chevronImageView.translatesAutoresizingMaskIntoConstraints = false + + // Add chevron to header + header.contentView.addSubview(chevronImageView) + + // Set up constraints for chevron + NSLayoutConstraint.activate([ + chevronImageView.trailingAnchor.constraint(equalTo: header.contentView.trailingAnchor, constant: -15), + chevronImageView.centerYAnchor.constraint(equalTo: header.contentView.centerYAnchor), + chevronImageView.widthAnchor.constraint(equalToConstant: 20), + chevronImageView.heightAnchor.constraint(equalToConstant: 20) + ]) } + @objc private func handleHeaderTap(_ gesture: UITapGestureRecognizer) { guard let header = gesture.view as? UITableViewHeaderFooterView else { return } let section = header.tag @@ -272,3 +302,4 @@ extension SettingsViewController: LargeBannerContainerView { tableView.reloadData() } } + From aa4165debe8134f747cb9bef5c14216389be71ae Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Mon, 28 Oct 2024 19:01:26 -0400 Subject: [PATCH 03/76] finalized a new settings page with dropdown bars like IOS --- .../Settings/SettingsViewController.swift | 101 +++++++++--------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index 060af061f..789e2251d 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -1,4 +1,4 @@ -// + // SettingsViewController.swift // Soundscape // @@ -85,7 +85,7 @@ class SettingsViewController: BaseTableViewController { GDATelemetry.trackScreenView("settings") self.title = GDLocalizedString("settings.screen_title") - expandedSections = [] // Initialize or reset expanded sections + expandedSections = [] } override func numberOfSections(in tableView: UITableView) -> Int { @@ -111,50 +111,45 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard expandedSections.contains(indexPath.section) else { - return UITableViewCell() // Return an empty cell if the section is not expanded + return UITableViewCell() } let identifier = SettingsViewController.cellIdentifiers[indexPath] - - guard let sectionType = Section(rawValue: indexPath.section) else { - return tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) - } - - // Configure the cell based on the section type let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) - cell.backgroundColor = UIColor(named: "CellBackgroundColor") // Set a custom dark background color - - switch sectionType { + + switch Section(rawValue: indexPath.section) { case .callouts: - let calloutCell = cell as! CalloutSettingsCellView - calloutCell.delegate = self - - if let rowType = CalloutsRow(rawValue: indexPath.row) { - switch rowType { - case .all: calloutCell.type = .all - case .poi: calloutCell.type = .poi - case .mobility: calloutCell.type = .mobility - case .beacon: calloutCell.type = .beacon - case .shake: calloutCell.type = .shake - } - } - return calloutCell - + configureCalloutCell(cell as! CalloutSettingsCellView, at: indexPath) case .telemetry: - let telemetryCell = cell as! TelemetrySettingsTableViewCell - telemetryCell.parent = self - return telemetryCell - + (cell as! TelemetrySettingsTableViewCell).parent = self case .audio: - let audioCell = cell as! MixAudioSettingCell - audioCell.delegate = self - return audioCell - + (cell as! MixAudioSettingCell).delegate = self default: - return cell + break } + + return cell } + private func configureCalloutCell(_ cell: CalloutSettingsCellView, at indexPath: IndexPath) { + cell.delegate = self + if let rowType = CalloutsRow(rawValue: indexPath.row) { + switch rowType { + case .all: + cell.type = .all + case .poi: + cell.type = .poi + case .mobility: + cell.type = .mobility + case .beacon: + cell.type = .beacon + case .shake: + cell.type = .shake + } + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } @@ -172,7 +167,7 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } - // Return description for expanded sections + if expandedSections.contains(section) { return SettingsViewController.sectionDescriptions[sectionType] } @@ -188,37 +183,38 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { guard let header = view as? UITableViewHeaderFooterView else { return } header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleHeaderTap(_:)))) - header.tag = section // Set the tag to identify the section + header.tag = section - // Customize header title - header.textLabel?.textColor = .white // Change header text color to white for contrast - header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Make the text bold + + header.textLabel?.textColor = .white + header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) - // Customize header appearance - header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") // Set a custom darker color - header.layer.borderColor = UIColor.clear.cgColor // Optional: set border color - header.layer.borderWidth = 0.0 // Optional: border width - header.layer.cornerRadius = 8.0 // Set rounded corners - header.layer.masksToBounds = true // Clip content to rounded corners + + header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") + header.layer.borderColor = UIColor.clear.cgColor + header.layer.borderWidth = 0.0 + header.layer.cornerRadius = 8.0 + header.layer.masksToBounds = true - // Optional: Add some padding + header.contentView.layoutMargins = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15) - // Add chevron icon - let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) // Use system image - chevronImageView.tintColor = .white // Set the color for the arrow + /* + let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) + chevronImageView.tintColor = .white chevronImageView.translatesAutoresizingMaskIntoConstraints = false - // Add chevron to header + header.contentView.addSubview(chevronImageView) - // Set up constraints for chevron + NSLayoutConstraint.activate([ chevronImageView.trailingAnchor.constraint(equalTo: header.contentView.trailingAnchor, constant: -15), chevronImageView.centerYAnchor.constraint(equalTo: header.contentView.centerYAnchor), chevronImageView.widthAnchor.constraint(equalToConstant: 20), chevronImageView.heightAnchor.constraint(equalToConstant: 20) ]) + */ } @objc private func handleHeaderTap(_ gesture: UITapGestureRecognizer) { @@ -302,4 +298,3 @@ extension SettingsViewController: LargeBannerContainerView { tableView.reloadData() } } - From 2cee25e296f098919944d0394e5e22c36a90eb73 Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Fri, 28 Mar 2025 23:46:37 -0400 Subject: [PATCH 04/76] Updated main.swft to check for missing translations --- apps/ios/Scripts/LocalizationLinter/main.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/ios/Scripts/LocalizationLinter/main.swift b/apps/ios/Scripts/LocalizationLinter/main.swift index dfd3ccf94..5c2bd48a1 100755 --- a/apps/ios/Scripts/LocalizationLinter/main.swift +++ b/apps/ios/Scripts/LocalizationLinter/main.swift @@ -724,9 +724,12 @@ printLog("Analyzing \(codeFiles.count) code files…") var allUsedKeys: Set = [] +var hasMissingKeys = false + codeFiles.forEach { (codeFile) in codeFile.missingKeys(from: baseLanguageFile).forEach({ (key) in - printWarning("Missing translation: '\(codeFile.filename)' uses a localization key which is not found in the base language file (or the key format is invalid): \"\(key)\"") + printError("Missing translation: '\(codeFile.filename)' uses a localization key which is not found in the base language file (or the key format is invalid): \"\(key)\"") + hasMissingKeys = true }) codeFile.checkDynamicKeys(from: baseLanguageFile).forEach { issue in @@ -749,6 +752,11 @@ codeFiles.forEach { (codeFile) in allUsedKeys = allUsedKeys.union(codeFile.dynamicKeys) } +if hasMissingKeys { + exit(1) +} + + if CommandLine.arguments.contains("unused") { // openscape has several keys that are constructed and will therefore be detected as unused // translations by the code above. We filter out the prefixes for these strings in order to From a151875dd398b30f59035f88ba4cbb6ef64d0c59 Mon Sep 17 00:00:00 2001 From: MBtheOtaku <45703141+MBtheOtaku@users.noreply.github.com> Date: Thu, 3 Apr 2025 17:10:26 -0400 Subject: [PATCH 05/76] Added a basic script --- script.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 script.py diff --git a/script.py b/script.py new file mode 100644 index 000000000..b88201835 --- /dev/null +++ b/script.py @@ -0,0 +1,50 @@ +import pandas as pd +import json +import numpy as np +from scipy.spatial import cKDTree +from geopy.distance import geodesic + +# Load the files (Update paths as needed) +csv_file_path = "C:/Users/Matthew Bui/Dropbox/Soundscape/via_sanantonio_NaviLens_Enabled_Bus_Stops.csv" +geojson_file_path = "C:/Users/Matthew Bui/Dropbox/Soundscape/export.geojson" + +# Load NaviLens-enabled bus stops CSV +navilens_df = pd.read_csv(csv_file_path) + +# Ensure correct latitude and longitude column names +navilens_df = navilens_df.rename(columns={"stop_lat": "lat", "stop_lon": "lon"}) + +# Load OSM bus stops from GeoJSON +with open(geojson_file_path, "r") as f: + geojson_data = json.load(f) + +# Extract OSM bus stop coordinates +osm_stops = [] +for feature in geojson_data["features"]: + if "geometry" in feature and "coordinates" in feature["geometry"]: + lon, lat = feature["geometry"]["coordinates"] # GeoJSON stores as [lon, lat] + osm_stops.append((lat, lon)) # Convert to (lat, lon) format + +# Convert OSM stops to a KDTree for fast lookup +osm_tree = cKDTree(np.array(osm_stops)) + +# Convert NaviLens stops to an array +navilens_coords = np.array(navilens_df[['lat', 'lon']]) + +# Define distance threshold in degrees (~1 degree = 111.32 km) +distance_threshold_deg = 5 / 111320 # Convert 5 meters to degrees + +# Find the closest OSM stop for each NaviLens stop +distances, indices = osm_tree.query(navilens_coords, distance_upper_bound=distance_threshold_deg) + +# Mark NaviLens stops that have a close OSM stop +navilens_df["in_osm"] = distances < distance_threshold_deg + +# Print Summary to Console +total_stops = len(navilens_df) +stops_in_osm = navilens_df["in_osm"].sum() +stops_not_in_osm = total_stops - stops_in_osm + +print(f"Total NaviLens Stops: {total_stops}") +print(f"Stops Found in OSM: {stops_in_osm}") +print(f"Stops Not in OSM: {stops_not_in_osm}") From 20a98e33b53b0107e7a6c708fef8059abe4d6a91 Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Thu, 3 Apr 2025 18:56:23 -0400 Subject: [PATCH 06/76] Updated for Auto Unmute --- .../Code/App/Settings/SettingsContext.swift | 38 ++++++++----------- .../Settings/SettingsViewController.swift | 23 ++++++++++- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/ios/GuideDogs/Code/App/Settings/SettingsContext.swift b/apps/ios/GuideDogs/Code/App/Settings/SettingsContext.swift index bca0eddd0..9e62b9eaf 100644 --- a/apps/ios/GuideDogs/Code/App/Settings/SettingsContext.swift +++ b/apps/ios/GuideDogs/Code/App/Settings/SettingsContext.swift @@ -31,7 +31,6 @@ class SettingsContext { fileprivate static let appUseCount = "GDAAppUseCount" fileprivate static let newFeaturesLastDisplayedVersion = "GDANewFeaturesLastDisplayedVersion" fileprivate static let clientIdentifier = "GDAUserDefaultClientIdentifier" - fileprivate static let servicesHostName = "GDAServicesHostName" fileprivate static let metricUnits = "GDASettingsMetric" fileprivate static let locale = "GDASettingsLocaleIdentifier" fileprivate static let voiceID = "GDAAppleSynthVoice" @@ -63,6 +62,8 @@ class SettingsContext { fileprivate static let ttsGain = "GDATTSAudioGain" fileprivate static let beaconGain = "GDABeaconAudioGain" fileprivate static let afxGain = "GDAAFXAudioGain" + fileprivate static let autoUnmuteEnabled = "GDAAutoUnmuteEnabled" + // MARK: Notification Keys @@ -111,7 +112,9 @@ class SettingsContext { Keys.audioSessionMixesWithOthers: true, Keys.markerSortStyle: SortStyle.distance.rawValue, Keys.leaveImmediateVicinityDistance: 30.0, - Keys.enterImmediateVicinityDistance: 15.0 + Keys.enterImmediateVicinityDistance: 15.0, + Keys.autoUnmuteEnabled: false + ]) resetLocaleIfNeeded() @@ -164,22 +167,6 @@ class SettingsContext { } } - var servicesHostName: String { - get { - // Allow URL to be reset to default when it is cleared - if let servicesHostName = userDefaults.string(forKey: Keys.servicesHostName), !servicesHostName.isEmpty { - return servicesHostName - } else { - let servicesHostName = "https://tiles.soundscape.services" - userDefaults.set(servicesHostName, forKey: Keys.servicesHostName) - return servicesHostName - } - } - set(newValue) { - userDefaults.set(newValue, forKey: Keys.servicesHostName) - } - } - var metricUnits: Bool { get { return userDefaults.bool(forKey: Keys.metricUnits) @@ -339,6 +326,16 @@ class SettingsContext { } } + var autoUnmuteEnabled: Bool { + get { + return userDefaults.bool(forKey: Keys.autoUnmuteEnabled) + } + set { + userDefaults.set(newValue, forKey: Keys.autoUnmuteEnabled) + } + } + + // MARK: Push Notifications var apnsDeviceToken: Data? { @@ -397,8 +394,6 @@ class SettingsContext { } set { userDefaults.set(newValue, forKey: Keys.leaveImmediateVicinityDistance) - // Ensure leave is always 15m greater than enter - userDefaults.set(max(newValue - 15.0, 0.0), forKey: Keys.enterImmediateVicinityDistance) } } @@ -408,8 +403,6 @@ class SettingsContext { } set { userDefaults.set(newValue, forKey: Keys.enterImmediateVicinityDistance) - // Ensure leave is always 15m greater than enter - userDefaults.set(newValue + 15.0, forKey: Keys.leaveImmediateVicinityDistance) } } } @@ -504,3 +497,4 @@ extension SettingsContext: AutoCalloutSettingsProvider { } } } + diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index 789e2251d..8418ed2a6 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -48,7 +48,9 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: 0, section: Section.streetPreview.rawValue): "streetPreview", IndexPath(row: 0, section: Section.troubleshooting.rawValue): "troubleshooting", IndexPath(row: 0, section: Section.about.rawValue): "about", - IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry" + IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry", + IndexPath(row: 6, section: Section.general.rawValue): "autoUnmute" + ] private static let collapsibleCalloutIndexPaths: [IndexPath] = [ @@ -96,7 +98,7 @@ class SettingsViewController: BaseTableViewController { guard let sectionType = Section(rawValue: section) else { return 0 } switch sectionType { - case .general: return expandedSections.contains(section) ? 6 : 0 + case .general: return expandedSections.contains(section) ? 7 : 0 case .audio: return expandedSections.contains(section) ? 1 : 0 case .callouts: return SettingsContext.shared.automaticCalloutsEnabled && expandedSections.contains(section) ? 5 : 0 @@ -127,10 +129,27 @@ class SettingsViewController: BaseTableViewController { default: break } + if identifier == "autoUnmute" { + let cell = tableView.dequeueReusableCell(withIdentifier: "autoUnmute", for: indexPath) + cell.textLabel?.text = GDLocalizedString("settings.beacon.auto_unmute") + + let toggle = UISwitch() + toggle.isOn = SettingsContext.shared.autoUnmuteEnabled + toggle.addTarget(self, action: #selector(autoUnmuteToggled(_:)), for: .valueChanged) + cell.accessoryView = toggle + cell.selectionStyle = .none + return cell + } return cell } + @objc private func autoUnmuteToggled(_ sender: UISwitch) { + SettingsContext.shared.autoUnmuteEnabled = sender.isOn + GDATelemetry.track("settings.auto_unmute_changed", with: ["enabled": "\(sender.isOn)"]) + } + + private func configureCalloutCell(_ cell: CalloutSettingsCellView, at indexPath: IndexPath) { cell.delegate = self if let rowType = CalloutsRow(rawValue: indexPath.row) { From b39fb89f123bbfebe8446b4a46aba9f16ae6043b Mon Sep 17 00:00:00 2001 From: KerryKoi <91487021+KerryKoi@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:09:11 -0400 Subject: [PATCH 07/76] Create visualize_tiles_map.py --- svcs/data/utilities/visualize_tiles_map.py | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 svcs/data/utilities/visualize_tiles_map.py diff --git a/svcs/data/utilities/visualize_tiles_map.py b/svcs/data/utilities/visualize_tiles_map.py new file mode 100644 index 000000000..378b096a2 --- /dev/null +++ b/svcs/data/utilities/visualize_tiles_map.py @@ -0,0 +1,69 @@ +import json +import math +import pandas as pd +import folium + +# Tile coordinate conversion +def num2deg(xtile, ytile, zoom): + n = 2.0 ** zoom + lon_deg = xtile / n * 360.0 - 180.0 + lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n))) + lat_deg = math.degrees(lat_rad) + return lat_deg, lon_deg + +# Read JSON file +json_file = "tiles.log.json" +rows = [] + +with open(json_file, "r") as f: + buffer = "" + for line in f: + line = line.strip() + if not line: + continue + buffer += line + if line.endswith("}"): + try: + log = json.loads(buffer) + uri = log["uri"] + ts = log["ts"] + parts = uri.strip("/").split("/") + if len(parts) >= 4 and parts[0] == "tiles": + z = int(parts[1]) + x = int(parts[2]) + y = int(parts[3].replace(".json", "")) + lat, lon = num2deg(x, y, z) + rows.append({"ts": ts, "lat": lat, "lon": lon}) + except Exception: + pass + buffer = "" + + +df = pd.DataFrame(rows) + +center_lat = df["lat"].mean() +center_lon = df["lon"].mean() + +# Count frequency of each tile +df["coord_key"] = df["lat"].round(6).astype(str) + "," + df["lon"].round(6).astype(str) +df["count"] = df["coord_key"].map(df["coord_key"].value_counts()) + +# Build folium map +m = folium.Map(location=[40.7128, -74.0060], zoom_start=4) + +for _, row in df.iterrows(): + count = row["count"] + radius = 3 + count + color = "red" if count > 3 else "blue" + + folium.CircleMarker( + location=[row["lat"], row["lon"]], + radius=radius, + color=color, + fill=True, + fill_opacity=0.6, + popup=f"ts: {row['ts']}
count: {count}" + ).add_to(m) + +m.save("tiles_map.html") +print("✅ Map saved as tiles_map.html") From 64c86920932c8a8e69ea84aa21dc132daadbeaf0 Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Fri, 11 Apr 2025 17:05:05 -0400 Subject: [PATCH 08/76] Updated Settings View for Dropdowns --- .../Settings/SettingsViewController.swift | 74 +++++++------------ 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index 8418ed2a6..c7f880254 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -1,4 +1,4 @@ - +// // SettingsViewController.swift // Soundscape // @@ -48,9 +48,7 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: 0, section: Section.streetPreview.rawValue): "streetPreview", IndexPath(row: 0, section: Section.troubleshooting.rawValue): "troubleshooting", IndexPath(row: 0, section: Section.about.rawValue): "about", - IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry", - IndexPath(row: 6, section: Section.general.rawValue): "autoUnmute" - + IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry" ] private static let collapsibleCalloutIndexPaths: [IndexPath] = [ @@ -87,7 +85,7 @@ class SettingsViewController: BaseTableViewController { GDATelemetry.trackScreenView("settings") self.title = GDLocalizedString("settings.screen_title") - expandedSections = [] + expandedSections = [] // Initialize or reset expanded sections } override func numberOfSections(in tableView: UITableView) -> Int { @@ -98,7 +96,7 @@ class SettingsViewController: BaseTableViewController { guard let sectionType = Section(rawValue: section) else { return 0 } switch sectionType { - case .general: return expandedSections.contains(section) ? 7 : 0 + case .general: return expandedSections.contains(section) ? 6 : 0 case .audio: return expandedSections.contains(section) ? 1 : 0 case .callouts: return SettingsContext.shared.automaticCalloutsEnabled && expandedSections.contains(section) ? 5 : 0 @@ -113,7 +111,7 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard expandedSections.contains(indexPath.section) else { - return UITableViewCell() + return UITableViewCell() // Return an empty cell if the section is not expanded } let identifier = SettingsViewController.cellIdentifiers[indexPath] @@ -129,41 +127,24 @@ class SettingsViewController: BaseTableViewController { default: break } - if identifier == "autoUnmute" { - let cell = tableView.dequeueReusableCell(withIdentifier: "autoUnmute", for: indexPath) - cell.textLabel?.text = GDLocalizedString("settings.beacon.auto_unmute") - - let toggle = UISwitch() - toggle.isOn = SettingsContext.shared.autoUnmuteEnabled - toggle.addTarget(self, action: #selector(autoUnmuteToggled(_:)), for: .valueChanged) - cell.accessoryView = toggle - cell.selectionStyle = .none - return cell - } return cell } - @objc private func autoUnmuteToggled(_ sender: UISwitch) { - SettingsContext.shared.autoUnmuteEnabled = sender.isOn - GDATelemetry.track("settings.auto_unmute_changed", with: ["enabled": "\(sender.isOn)"]) - } - - private func configureCalloutCell(_ cell: CalloutSettingsCellView, at indexPath: IndexPath) { cell.delegate = self if let rowType = CalloutsRow(rawValue: indexPath.row) { switch rowType { case .all: - cell.type = .all + cell.type = .all // Ensure this matches with your CalloutSettingCellType case .poi: - cell.type = .poi + cell.type = .poi // Ensure this matches with your CalloutSettingCellType case .mobility: - cell.type = .mobility + cell.type = .mobility // Ensure this matches with your CalloutSettingCellType case .beacon: - cell.type = .beacon + cell.type = .beacon // Ensure this matches with your CalloutSettingCellType case .shake: - cell.type = .shake + cell.type = .shake // Ensure this matches with your CalloutSettingCellType } } } @@ -186,7 +167,7 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } - + // Return description for expanded sections if expandedSections.contains(section) { return SettingsViewController.sectionDescriptions[sectionType] } @@ -202,38 +183,37 @@ class SettingsViewController: BaseTableViewController { override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { guard let header = view as? UITableViewHeaderFooterView else { return } header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleHeaderTap(_:)))) - header.tag = section + header.tag = section // Set the tag to identify the section - - header.textLabel?.textColor = .white - header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) + // Customize header title + header.textLabel?.textColor = .white // Change header text color to white for contrast + header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Make the text bold - - header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") - header.layer.borderColor = UIColor.clear.cgColor - header.layer.borderWidth = 0.0 - header.layer.cornerRadius = 8.0 - header.layer.masksToBounds = true + // Customize header appearance + header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") // Set a custom darker color + header.layer.borderColor = UIColor.clear.cgColor // Optional: set border color + header.layer.borderWidth = 0.0 // Optional: border width + header.layer.cornerRadius = 8.0 // Set rounded corners + header.layer.masksToBounds = true // Clip content to rounded corners - + // Optional: Add some padding header.contentView.layoutMargins = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15) - /* - let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) - chevronImageView.tintColor = .white + // Add chevron icon + let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) // Use system image + chevronImageView.tintColor = .white // Set the color for the arrow chevronImageView.translatesAutoresizingMaskIntoConstraints = false - + // Add chevron to header header.contentView.addSubview(chevronImageView) - + // Set up constraints for chevron NSLayoutConstraint.activate([ chevronImageView.trailingAnchor.constraint(equalTo: header.contentView.trailingAnchor, constant: -15), chevronImageView.centerYAnchor.constraint(equalTo: header.contentView.centerYAnchor), chevronImageView.widthAnchor.constraint(equalToConstant: 20), chevronImageView.heightAnchor.constraint(equalToConstant: 20) ]) - */ } @objc private func handleHeaderTap(_ gesture: UITapGestureRecognizer) { From 307ab9fc41501843ecca80393f15dd99076e3c8b Mon Sep 17 00:00:00 2001 From: MBtheOtaku <45703141+MBtheOtaku@users.noreply.github.com> Date: Sat, 12 Apr 2025 01:28:49 -0400 Subject: [PATCH 09/76] Update script.py --- script.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/script.py b/script.py index b88201835..fe4f0ed1f 100644 --- a/script.py +++ b/script.py @@ -1,12 +1,20 @@ +import argparse import pandas as pd import json import numpy as np from scipy.spatial import cKDTree from geopy.distance import geodesic -# Load the files (Update paths as needed) -csv_file_path = "C:/Users/Matthew Bui/Dropbox/Soundscape/via_sanantonio_NaviLens_Enabled_Bus_Stops.csv" -geojson_file_path = "C:/Users/Matthew Bui/Dropbox/Soundscape/export.geojson" +# Argument parser for CLI inputs +parser = argparse.ArgumentParser(description="Check NaviLens stops against OSM GeoJSON data.") +parser.add_argument("--csv", required=True, help="Path to NaviLens-enabled bus stops CSV file") +parser.add_argument("--geojson", required=True, help="Path to OSM bus stops GeoJSON file") +parser.add_argument("--output", help="Optional path to save result CSV file") +args = parser.parse_args() + +# Load the files +csv_file_path = args.csv +geojson_file_path = args.geojson # Load NaviLens-enabled bus stops CSV navilens_df = pd.read_csv(csv_file_path) @@ -22,8 +30,8 @@ osm_stops = [] for feature in geojson_data["features"]: if "geometry" in feature and "coordinates" in feature["geometry"]: - lon, lat = feature["geometry"]["coordinates"] # GeoJSON stores as [lon, lat] - osm_stops.append((lat, lon)) # Convert to (lat, lon) format + lon, lat = feature["geometry"]["coordinates"] # GeoJSON uses [lon, lat] + osm_stops.append((lat, lon)) # Convert to (lat, lon) # Convert OSM stops to a KDTree for fast lookup osm_tree = cKDTree(np.array(osm_stops)) @@ -31,7 +39,7 @@ # Convert NaviLens stops to an array navilens_coords = np.array(navilens_df[['lat', 'lon']]) -# Define distance threshold in degrees (~1 degree = 111.32 km) +# Define distance threshold in degrees (~1 degree ≈ 111.32 km) distance_threshold_deg = 5 / 111320 # Convert 5 meters to degrees # Find the closest OSM stop for each NaviLens stop @@ -40,7 +48,7 @@ # Mark NaviLens stops that have a close OSM stop navilens_df["in_osm"] = distances < distance_threshold_deg -# Print Summary to Console +# Print Summary total_stops = len(navilens_df) stops_in_osm = navilens_df["in_osm"].sum() stops_not_in_osm = total_stops - stops_in_osm @@ -48,3 +56,12 @@ print(f"Total NaviLens Stops: {total_stops}") print(f"Stops Found in OSM: {stops_in_osm}") print(f"Stops Not in OSM: {stops_not_in_osm}") + +# Show sample of matched stops for manual spot-check +print("\nSample matched NaviLens stops (lat, lon):") +print(navilens_df[navilens_df["in_osm"]][["lat", "lon"]].head()) + +# Optional: save to output CSV if requested +if args.output: + navilens_df.to_csv(args.output, index=False) + print(f"\nFull results saved to: {args.output}") From 301c5123030d39501ebb0a7e335326ced1722bd4 Mon Sep 17 00:00:00 2001 From: MBtheOtaku <45703141+MBtheOtaku@users.noreply.github.com> Date: Sat, 12 Apr 2025 01:31:58 -0400 Subject: [PATCH 10/76] Added script for deduplication --- svcs/data/non_osm_scripts/script.py | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 svcs/data/non_osm_scripts/script.py diff --git a/svcs/data/non_osm_scripts/script.py b/svcs/data/non_osm_scripts/script.py new file mode 100644 index 000000000..fe4f0ed1f --- /dev/null +++ b/svcs/data/non_osm_scripts/script.py @@ -0,0 +1,67 @@ +import argparse +import pandas as pd +import json +import numpy as np +from scipy.spatial import cKDTree +from geopy.distance import geodesic + +# Argument parser for CLI inputs +parser = argparse.ArgumentParser(description="Check NaviLens stops against OSM GeoJSON data.") +parser.add_argument("--csv", required=True, help="Path to NaviLens-enabled bus stops CSV file") +parser.add_argument("--geojson", required=True, help="Path to OSM bus stops GeoJSON file") +parser.add_argument("--output", help="Optional path to save result CSV file") +args = parser.parse_args() + +# Load the files +csv_file_path = args.csv +geojson_file_path = args.geojson + +# Load NaviLens-enabled bus stops CSV +navilens_df = pd.read_csv(csv_file_path) + +# Ensure correct latitude and longitude column names +navilens_df = navilens_df.rename(columns={"stop_lat": "lat", "stop_lon": "lon"}) + +# Load OSM bus stops from GeoJSON +with open(geojson_file_path, "r") as f: + geojson_data = json.load(f) + +# Extract OSM bus stop coordinates +osm_stops = [] +for feature in geojson_data["features"]: + if "geometry" in feature and "coordinates" in feature["geometry"]: + lon, lat = feature["geometry"]["coordinates"] # GeoJSON uses [lon, lat] + osm_stops.append((lat, lon)) # Convert to (lat, lon) + +# Convert OSM stops to a KDTree for fast lookup +osm_tree = cKDTree(np.array(osm_stops)) + +# Convert NaviLens stops to an array +navilens_coords = np.array(navilens_df[['lat', 'lon']]) + +# Define distance threshold in degrees (~1 degree ≈ 111.32 km) +distance_threshold_deg = 5 / 111320 # Convert 5 meters to degrees + +# Find the closest OSM stop for each NaviLens stop +distances, indices = osm_tree.query(navilens_coords, distance_upper_bound=distance_threshold_deg) + +# Mark NaviLens stops that have a close OSM stop +navilens_df["in_osm"] = distances < distance_threshold_deg + +# Print Summary +total_stops = len(navilens_df) +stops_in_osm = navilens_df["in_osm"].sum() +stops_not_in_osm = total_stops - stops_in_osm + +print(f"Total NaviLens Stops: {total_stops}") +print(f"Stops Found in OSM: {stops_in_osm}") +print(f"Stops Not in OSM: {stops_not_in_osm}") + +# Show sample of matched stops for manual spot-check +print("\nSample matched NaviLens stops (lat, lon):") +print(navilens_df[navilens_df["in_osm"]][["lat", "lon"]].head()) + +# Optional: save to output CSV if requested +if args.output: + navilens_df.to_csv(args.output, index=False) + print(f"\nFull results saved to: {args.output}") From 5e11cd99b1d13f31f18ac42d6d38da3177e42bbf Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Wed, 16 Apr 2025 21:13:09 -0400 Subject: [PATCH 11/76] Adjust NaviLens recommender color --- .../Views/Recommender/Containers/RecommenderContainerView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Containers/RecommenderContainerView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Containers/RecommenderContainerView.swift index 24f637b5f..8d27a5bc4 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Containers/RecommenderContainerView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Containers/RecommenderContainerView.swift @@ -39,7 +39,7 @@ struct RecommenderContainerView: View { .padding(.horizontal, 18.0) .padding(.vertical, 12.0) .frame(maxWidth: .infinity, alignment: .leading) - .linearGradientBackground(.purple) + .linearGradientBackground(.blue) .accessibilityElement(children: .combine) } From f1b60f437d6a6d72e8511cf8c1aebf1ad1786eeb Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Wed, 16 Apr 2025 21:22:43 -0400 Subject: [PATCH 12/76] Skip appending NaviLens to callouts if already in POI name --- .../Code/Behaviors/Default/Callouts/POICallout.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift index 32345c262..4596b9032 100644 --- a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift +++ b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift @@ -171,8 +171,9 @@ struct POICallout: POICalloutProtocol { sounds.append(TTSSound(formattedName, at: soundLocation)) } - // Announce "NaviLens available" for NaviLens-enabled locations - if poi.superCategory == "navilens" { + // Announce "NaviLens available" for NaviLens-enabled locations, + // unless NaviLens is already in the name + if poi.superCategory == "navilens" && !name.lowercased().contains("navilens") { sounds.append(TTSSound(GDLocalizedString("directions.navilens_available"), at: soundLocation)) } From fc582446721855f63c2183783b192a4754eb91fe Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Fri, 18 Apr 2025 16:33:43 -0400 Subject: [PATCH 13/76] Automatically choose audio beacon or NaviLens action based on distance --- .../en-GB.lproj/Localizable.strings | 4 ++- .../en-US.lproj/Localizable.strings | 9 ++++--- .../es-ES.lproj/Localizable.strings | 1 - .../pt-BR.lproj/Localizable.strings | 4 --- .../pt-PT.lproj/Localizable.strings | 3 --- .../Code/Visual UI/Helpers/Integrations.swift | 27 ++++++++++++++++++- .../Location Action/LocationAction.swift | 17 ++++++------ .../Home/HomeViewController.swift | 5 +++- .../LocationDetailViewController.swift | 14 +++++++++- .../POI Table/NearbyTableViewController.swift | 5 +++- .../POI Table/SearchTableViewController.swift | 5 +++- .../Views/Beacon/BeaconToolbarView.swift | 6 +++-- ...MarkersAndRoutesListNavigationHelper.swift | 5 +++- .../NaviLens/NavilensRecommenderView.swift | 4 +-- 14 files changed, 79 insertions(+), 30 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 0351dd45c..fce161736 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -1023,6 +1023,8 @@ /* */ "location_detail.action.beacon" = "Start Audio Beacon"; +/* */ +"location_detail.action.beacon_or_navilens" = "Start NaviLens or Audio Beacon"; /* */ "location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location."; @@ -4477,6 +4479,6 @@ "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; "location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; -"navilens.title" = "Launch NaviLens"; +"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 2048080e0..41383a875 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -885,9 +885,15 @@ /* Title for the action to set a beacon */ "location_detail.action.beacon" = "Start Audio Beacon"; +/* Text label for the action to start audio beacon at a NaviLens-enabled location */ +"location_detail.action.beacon_or_navilens" = "Start NaviLens or Audio Beacon"; + /* Voiceover hint for the action to set a beacon */ "location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location."; +/* Voiceover hint for the action to set a beacon or launch NaviLens */ +"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; + /* Text displayed when audio beacon action is disabled */ "location_detail.action.beacon.hint.disabled" = "Setting a new audio beacon is disabled while route guidance is active."; @@ -906,9 +912,6 @@ /* Text displayed when street preview is disabled */ "location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; -/* Text label for the action to launch NaviLens */ -"navilens.title" = "Launch NaviLens"; - /* Voiceover hint for the action to launch NaviLens */ "location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index a9d50cb9f..3cef5efce 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -4444,7 +4444,6 @@ "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens."; -"navilens.title" = "Iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso."; diff --git a/apps/ios/GuideDogs/Assets/Localization/pt-BR.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/pt-BR.lproj/Localizable.strings index 5d8eee218..98584c385 100644 --- a/apps/ios/GuideDogs/Assets/Localization/pt-BR.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/pt-BR.lproj/Localizable.strings @@ -1050,10 +1050,6 @@ "location_detail.action.preview.hint.disabled" = "O Street Preview será desativado enquanto a orientação pela rota estiver ativa"; -/* */ -"navilens.title" = "Iniciar NaviLens"; - - /* */ "location_detail.action.directions.hint" = "Dê um toque duplo para abrir esta localização em um aplicativo de mapas externo"; diff --git a/apps/ios/GuideDogs/Assets/Localization/pt-PT.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/pt-PT.lproj/Localizable.strings index ac267efcd..e7ea84618 100644 --- a/apps/ios/GuideDogs/Assets/Localization/pt-PT.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/pt-PT.lproj/Localizable.strings @@ -1049,9 +1049,6 @@ /* */ "location_detail.action.preview.hint.disabled" = "O Street Preview está desativado enquanto a orientação de rotas está ativa"; -/* */ -"navilens.title" = "Iniciar NaviLens"; - /* */ "location_detail.action.directions.hint" = "Faça duplo toque para abrir esta localização numa aplicação de mapas externa"; diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift index d09e048c0..edf56edb2 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift @@ -6,7 +6,7 @@ // Copyright © 2025 Soundscape community. All rights reserved. // -func launchNaviLens() { +func launchNaviLens(detail: LocationDetail) { // Launch NaviLens app, or open App Store listing if not installed let navilensUrl = URL(string: "navilens://")! let appStoreUrl = URL(string: "https://apps.apple.com/us/app/navilens/id1273704914")! @@ -16,3 +16,28 @@ func launchNaviLens() { UIApplication.shared.open(appStoreUrl) } } + +func guideToNaviLens(detail: LocationDetail) throws { + // Launch NaviLens if close enough, otherwise start beacon + guard let location = AppContext.shared.geolocationManager.location else { + // Location is unknown + return launchNaviLens(detail: detail) + } + + // If our GPS is more precise than we are close, use a beacon + if location.distance(from: detail.location) > location.horizontalAccuracy { + try LocationActionHandler.beacon(locationDetail: detail) + } else { + launchNaviLens(detail: detail) + } +} + +func safeGuideToNaviLens(poi: POI) { + // Launch NaviLens if starting a beacon throws an error + let detail = LocationDetail(entity: poi) + do { + try guideToNaviLens(detail: detail) + } catch { + launchNaviLens(detail: detail) + } +} diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Action/LocationAction.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Action/LocationAction.swift index e27e9d3dd..6667cded9 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Action/LocationAction.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Action/LocationAction.swift @@ -31,18 +31,19 @@ enum LocationAction { } static func actions(for detail: LocationDetail) -> [LocationAction] { - var result: [LocationAction] + var result: [LocationAction] = [.beacon] + if detail.source.hasNaviLens { + // NaviLens action replaces beacon action + result = [.navilens] + } if detail.isMarker { - result = [.beacon, .edit, .preview, .share(isEnabled: true)] + result += [.edit, .preview, .share(isEnabled: true)] } else { // If the location does not have a backup coordinate // disable the save and share actions let isEnabled = detail.source.isCachingEnabled - result = [.beacon, .save(isEnabled: isEnabled), .preview, .share(isEnabled: isEnabled)] - } - if detail.source.hasNaviLens { - result += [.navilens] + result += [.save(isEnabled: isEnabled), .preview, .share(isEnabled: isEnabled)] } return result } @@ -75,7 +76,7 @@ enum LocationAction { case .beacon: return GDLocalizedString("location_detail.action.beacon") case .preview: return GDLocalizedString("preview.title") case .share: return GDLocalizedString("share.title") - case .navilens: return GDLocalizedString("navilens.title") + case .navilens: return GDLocalizedString("location_detail.action.beacon_or_navilens") } } @@ -86,7 +87,7 @@ enum LocationAction { case .beacon: return isEnabled ? GDLocalizedString("location_detail.action.beacon.hint") : GDLocalizedString("location_detail.action.beacon.hint.disabled") case .preview: return isEnabled ? GDLocalizedString("location_detail.action.preview.hint") : GDLocalizedString("location_detail.action.preview.hint.disabled") case .share(let isEnabled): return isEnabled ? GDLocalizedString("location_detail.action.share.hint") : GDLocalizedString("location_detail.disabled.share") - case .navilens: return GDLocalizedString("location_detail.action.navilens.hint") + case .navilens: return GDLocalizedString("location_detail.action.beacon_or_navilens.hint") } } diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift index c769a217a..e4fb6dd19 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift @@ -688,7 +688,10 @@ extension HomeViewController: LocationActionDelegate { self.present(firstUseAlert, animated: true, completion: nil) } case .navilens: - launchNaviLens() + // Set a beacon on the given location + // and segue to the home view + try guideToNaviLens(detail: detail) + self.navigationController?.popToRootViewController(animated: true) } } catch let error as LocationActionError { let alert = LocationActionAlert.alert(for: error) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/LocationDetailViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/LocationDetailViewController.swift index ba36783c3..a58e712f3 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/LocationDetailViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/LocationDetailViewController.swift @@ -345,7 +345,19 @@ extension LocationDetailViewController: LocationActionDelegate { self.present(firstUseAlert, animated: true, completion: nil) } case .navilens: - launchNaviLens() + // Set a beacon on the given location + // and segue to the home view + try guideToNaviLens(detail: detail) + + if let home = self.navigationController?.viewControllers.first as? HomeViewController { + home.shouldFocusOnBeacon = true + } + + if self.isPresentedModally && !self.isInPreviewController { + self.dismiss(animated: true) + } else { + self.navigationController?.popToRootViewController(animated: true) + } } } catch let error as LocationActionError { let alert = LocationActionAlert.alert(for: error) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/NearbyTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/NearbyTableViewController.swift index 37e4565ed..c56cf1a81 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/NearbyTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/NearbyTableViewController.swift @@ -376,7 +376,10 @@ extension NearbyTableViewController: LocationAccessibilityActionDelegate { self.present(firstUseAlert, animated: true, completion: nil) } case .navilens: - launchNaviLens() + // Set a beacon on the given location + // and segue to the home view + try guideToNaviLens(detail: detail) + self.navigationController?.popToRootViewController(animated: true) } } catch let error as LocationActionError { diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift index 796915542..cf4f8ecd1 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift @@ -348,7 +348,10 @@ extension SearchTableViewController: LocationActionDelegate { self.present(firstUseAlert, animated: true, completion: nil) } case .navilens: - launchNaviLens() + // Set a beacon on the given location + // and segue to the home view + try guideToNaviLens(detail: detail) + self.navigationController?.popToRootViewController(animated: true) } } catch let error as LocationActionError { let alert = LocationActionAlert.alert(for: error) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift index ca7e8558d..763518aaa 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift @@ -135,7 +135,9 @@ struct BeaconToolbarView: View { // Launch NaviLens (applies to both beacon and route waypoint) if beacon.locationDetail.source.hasNaviLens { - Button(action: launchNaviLens, label: { + Button(action: { + launchNaviLens(detail: beacon.locationDetail) + }, label: { Image("navilens") .renderingMode(.template) .resizable() @@ -145,7 +147,7 @@ struct BeaconToolbarView: View { }) .foregroundColor(.white) - .accessibilityLabel(GDLocalizedTextView("navilens.title")) + .accessibilityLabel(GDLocalizedTextView("location_detail.action.navilens.hint")) } Spacer() diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesListNavigationHelper.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesListNavigationHelper.swift index 412179186..668e7bb88 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesListNavigationHelper.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesListNavigationHelper.swift @@ -88,7 +88,10 @@ class MarkersAndRoutesListNavigationHelper: ViewNavigationHelper, LocationAccess } case .navilens: - launchNaviLens() + // Set a beacon on the given location + // and segue to the home view + try guideToNaviLens(detail: detail) + self.popToRootViewController(animated: true) } } catch let error as LocationActionError { let alert = LocationActionAlert.alert(for: error) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Publishers/NaviLens/NavilensRecommenderView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Publishers/NaviLens/NavilensRecommenderView.swift index f92aa2595..5ecfc65cf 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Publishers/NaviLens/NavilensRecommenderView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Recommender/Publishers/NaviLens/NavilensRecommenderView.swift @@ -19,10 +19,10 @@ struct NavilensRecommenderView: View { // MARK: Body var body: some View { - Button(action: launchNaviLens, label: { + Button(action: { safeGuideToNaviLens(poi: poi) }, label: { RecommenderContainerView { VStack(alignment: .leading, spacing: 4.0) { - GDLocalizedTextView("navilens.title") + GDLocalizedTextView("location_detail.action.beacon_or_navilens") .font(.body) Text(poi.localizedName) From e5780c23f5ac421cbd38f1f425c06090405223ed Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Fri, 18 Apr 2025 17:14:24 -0400 Subject: [PATCH 14/76] Suggest NaviLens when in audio beacon vicinity --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 4 ++++ .../Assets/Localization/en-US.lproj/Localizable.strings | 3 +++ .../Behaviors/Default/Callouts/DestinationCallout.swift | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index fce161736..6c5e43925 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -816,6 +816,10 @@ "beacon.beacon_location_within_audio_beacon_muted" = "Beacon within %@. Audio beacon has been muted."; +/* */ +"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; + + /* */ "preview.title" = "Soundscape Street Preview"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 41383a875..38a404f3f 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -721,6 +721,9 @@ /* Notification, Beacon location nearby. Audio beacon has been muted. */ "beacon.beacon_location_within_audio_beacon_muted" = "Beacon within %@. Audio beacon has been muted."; +/* Suggest the user launch NaviLens for the remaining distance. Appended to beacon.beacon_location_within_audio_beacon_muted. */ +"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; + //------------------------------------------------------------------------------ // MARK: - Preview //------------------------------------------------------------------------------ diff --git a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/DestinationCallout.swift b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/DestinationCallout.swift index 00180996c..aaf398f2b 100644 --- a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/DestinationCallout.swift +++ b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/DestinationCallout.swift @@ -91,7 +91,12 @@ struct DestinationCallout: POICalloutProtocol { // Inform the user why the audio beacon has stopped if causedAudioDisabled { let earcon = GlyphSound(.beaconFound) - let tts = TTSSound(GDLocalizedString("beacon.beacon_location_within_audio_beacon_muted", formattedDistance), at: markerLocation) + var text = GDLocalizedString("beacon.beacon_location_within_audio_beacon_muted", formattedDistance) + // Append suggestion to launch NaviLens if available at location + if (poi != nil) && LocationDetail(entity: poi!).source.hasNaviLens { + text += " " + GDLocalizedString("beacon.suggest_navilens") + } + let tts = TTSSound(text, at: markerLocation) guard let layered = LayeredSound(earcon, tts) else { return Sounds([earcon, tts]) From 6ae6d57d0a16b9dc786e1880ecdf4103f12903a7 Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Sun, 20 Apr 2025 13:57:11 -0400 Subject: [PATCH 15/76] Move/rename script from #177 --- script.py => svcs/data/non_osm_scripts/find_duplicate_points.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename script.py => svcs/data/non_osm_scripts/find_duplicate_points.py (100%) diff --git a/script.py b/svcs/data/non_osm_scripts/find_duplicate_points.py similarity index 100% rename from script.py rename to svcs/data/non_osm_scripts/find_duplicate_points.py From 2402e3af6a2a98f8502a8e7f07a7550f46c859d0 Mon Sep 17 00:00:00 2001 From: KerryKoi <91487021+KerryKoi@users.noreply.github.com> Date: Tue, 22 Apr 2025 18:09:39 -0400 Subject: [PATCH 16/76] Update visualize_tiles_map.py --- svcs/data/utilities/visualize_tiles_map.py | 48 +++++++++++++++------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/svcs/data/utilities/visualize_tiles_map.py b/svcs/data/utilities/visualize_tiles_map.py index 378b096a2..f24050fb9 100644 --- a/svcs/data/utilities/visualize_tiles_map.py +++ b/svcs/data/utilities/visualize_tiles_map.py @@ -2,6 +2,7 @@ import math import pandas as pd import folium +import argparse # Tile coordinate conversion def num2deg(xtile, ytile, zoom): @@ -11,11 +12,17 @@ def num2deg(xtile, ytile, zoom): lat_deg = math.degrees(lat_rad) return lat_deg, lon_deg -# Read JSON file -json_file = "tiles.log.json" -rows = [] +# Parse command-line arguments +parser = argparse.ArgumentParser(description="Visualize tile request log as interactive map.") +parser.add_argument("json_file", help="Path to tile log JSON file") +parser.add_argument("--output", default="tiles_map_v2.html", help="Output HTML map file name") +parser.add_argument("--min_radius", type=int, default=3, help="Minimum marker radius") +parser.add_argument("--max_radius", type=int, default=15, help="Maximum marker radius") +args = parser.parse_args() -with open(json_file, "r") as f: +# Read and parse JSON file +rows = [] +with open(args.json_file, "r") as f: buffer = "" for line in f: line = line.strip() @@ -38,32 +45,45 @@ def num2deg(xtile, ytile, zoom): pass buffer = "" - +# Create DataFrame and preprocess df = pd.DataFrame(rows) +df["coord_key"] = df["lat"].round(6).astype(str) + "," + df["lon"].round(6).astype(str) +df["count"] = df["coord_key"].map(df["coord_key"].value_counts()) center_lat = df["lat"].mean() center_lon = df["lon"].mean() -# Count frequency of each tile -df["coord_key"] = df["lat"].round(6).astype(str) + "," + df["lon"].round(6).astype(str) -df["count"] = df["coord_key"].map(df["coord_key"].value_counts()) +min_count = df["count"].min() +max_count = df["count"].max() + +def scale_radius(count): + if max_count == min_count: + return args.min_radius + return args.min_radius + (count - min_count) / (max_count - min_count) * (args.max_radius - args.min_radius) + +def heatmap_color(count): + if max_count == min_count: + hue = 240 + else: + hue = 240 - int((count - min_count) / (max_count - min_count) * 240) + return f"hsl({hue}, 100%, 50%)" -# Build folium map +# Create map m = folium.Map(location=[40.7128, -74.0060], zoom_start=4) for _, row in df.iterrows(): count = row["count"] - radius = 3 + count - color = "red" if count > 3 else "blue" + radius = scale_radius(count) + color = heatmap_color(count) folium.CircleMarker( location=[row["lat"], row["lon"]], radius=radius, color=color, fill=True, - fill_opacity=0.6, + fill_opacity=0.7, popup=f"ts: {row['ts']}
count: {count}" ).add_to(m) -m.save("tiles_map.html") -print("✅ Map saved as tiles_map.html") +m.save(args.output) +print(f"✅ Optimized map saved as {args.output}") From e0b9ea9f34785678934d0f51df7a7875239db4d8 Mon Sep 17 00:00:00 2001 From: KerryKoi <91487021+KerryKoi@users.noreply.github.com> Date: Tue, 22 Apr 2025 18:18:55 -0400 Subject: [PATCH 17/76] Update visualize_tiles_map.py --- svcs/data/utilities/visualize_tiles_map.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/svcs/data/utilities/visualize_tiles_map.py b/svcs/data/utilities/visualize_tiles_map.py index f24050fb9..f19ea57b0 100644 --- a/svcs/data/utilities/visualize_tiles_map.py +++ b/svcs/data/utilities/visualize_tiles_map.py @@ -1,3 +1,15 @@ +# Usage: +# python visualize_tiles_map_v2.py tiles.log.json +# +# Options: +# output (optional) Output HTML filename, default: tiles_map_v2.html +# min_radius (optional) Minimum circle radius, default: 3 +# max_radius (optional) Maximum circle radius, default: 15 +# +# Example: +# python visualize_tiles_map_v2.py tiles.log.json output mymap.html min_radius 4 max_radius 10 + + import json import math import pandas as pd @@ -15,9 +27,9 @@ def num2deg(xtile, ytile, zoom): # Parse command-line arguments parser = argparse.ArgumentParser(description="Visualize tile request log as interactive map.") parser.add_argument("json_file", help="Path to tile log JSON file") -parser.add_argument("--output", default="tiles_map_v2.html", help="Output HTML map file name") -parser.add_argument("--min_radius", type=int, default=3, help="Minimum marker radius") -parser.add_argument("--max_radius", type=int, default=15, help="Maximum marker radius") +parser.add_argument("output", default="tiles_map_v2.html", help="Output HTML map file name") +parser.add_argument("min_radius", type=int, default=3, help="Minimum marker radius") +parser.add_argument("max_radius", type=int, default=15, help="Maximum marker radius") args = parser.parse_args() # Read and parse JSON file From dd7782e178e2967b8e9b715bb7bd97d32a61be8b Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Wed, 23 Apr 2025 00:37:08 -0400 Subject: [PATCH 18/76] Add script to check ingest of non-OSM data CSV --- .../non_osm_scripts/check_non_osm_ingested.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 svcs/data/non_osm_scripts/check_non_osm_ingested.py diff --git a/svcs/data/non_osm_scripts/check_non_osm_ingested.py b/svcs/data/non_osm_scripts/check_non_osm_ingested.py new file mode 100644 index 000000000..c90e4128c --- /dev/null +++ b/svcs/data/non_osm_scripts/check_non_osm_ingested.py @@ -0,0 +1,71 @@ +# Copyright (c) Soundscape Community. +# Licensed under the MIT License. +""" +Checks that a non-OSM data CSV was properly loaded by choosing a random row +and confirming that the row is served as a feature in the expected tile. +""" +import argparse +import csv +import math +from pathlib import Path +import random +import sys + +import requests + + +# standard tile to coordinates and reverse versions from +# https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames +def osm_deg2num(lat_deg, lon_deg, zoom): + lat_rad = math.radians(lat_deg) + n = 2.0 ** zoom + xtile = int((lon_deg + 180.0) / 360.0 * n) + ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n) + return (xtile, ytile) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("non_osm_csv", type=Path) + parser.add_argument( + "--tile-server", type=str, default="https://tiles.soundscape.services/") + parser.add_argument("--zoom", type=int, default=16) + args = parser.parse_args() + + with open(args.non_osm_csv) as f: + # Choose a random row from the CSV + data = csv.DictReader(f) + some_row = random.choice([row for row in data]) + print(f"Chose feature: {some_row['name']}") + + # Determine tile that would contain feature + x, y = osm_deg2num( + float(some_row['latitude']), float(some_row["longitude"]), args.zoom) + url = f"{args.tile_server}/{args.zoom}/{x}/{y}.json" + print(f"Fetching {url}...") + response = requests.get(url) + features = response.json()["features"] + print(f"Tile contains {len(features)} features.") + + # Check that some feature in the tile matches our row + from pprint import pprint + for feature in features: + #pprint(feature) + if ( + feature["feature_type"] == some_row["feature_type"] + and feature["feature_value"] == some_row["feature_value"] + and feature["geometry"]["type"] == "Point" + #and feature["geometry"]["coordinates"] == [ + # str(some_row["latitude"]), str(some_row["longitude"])] + # All feature properties should have come from CSV fields + and all( + some_row[key] == val + for (key, val) in feature["properties"].items() + ) + ): + print("PASS") + break + else: + # No feature in tile matched our row + print("FAIL") + sys.exit(-1) \ No newline at end of file From 2c8c148662c832922282fbe664b1eda3549903e6 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Wed, 30 Apr 2025 00:05:48 +0200 Subject: [PATCH 19/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 62 ++--- .../en-US.lproj/Localizable.strings | 94 +++---- .../es-ES.lproj/Localizable.strings | 255 +++++++++--------- 3 files changed, 207 insertions(+), 204 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 6c5e43925..845a887b3 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -359,7 +359,7 @@ /* */ -"settings.clear_cache.alert_message" = "Soundscape stores map data to reduce data and battery consumption. Deleting stored data will require Soundscape to reload the data."; +"settings.clear_cache.alert_message" = "Soundscape stores map data to reduce mobile data and battery consumption. Deleting stored data will require Soundscape to reload the data."; /* */ @@ -375,7 +375,7 @@ /* */ -"settings.clear_cache.no_service.message" = "Soundscape is currently unable to connect to the internet. An internet connection is required when clearing the stored map data so that the map data can be refreshed."; +"settings.clear_cache.no_service.message" = "Soundscape is currently unable to connect to the internet. An internet connection is required when clearing the stored map data so that the data can be refreshed."; /* */ @@ -633,7 +633,7 @@ /* */ -"troubleshooting.check_audio.hint" = "Double tap to check the status of the headphones you are using with Soundscape."; +"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones."; /* */ @@ -1630,7 +1630,7 @@ /* */ -"routes.tutorial.details" = "You will now return to the Soundscape home page and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; +"routes.tutorial.details" = "You will now return to the Soundscape home screen and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; /* */ @@ -2749,8 +2749,8 @@ /* */ -"devices.explain_ar.connected.airpods" = "Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you do not need to hold the phone in your hand."; -"devices.explain_ar.connected.boseframes" = "Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you do not need to hold the phone in your hand."; +"devices.explain_ar.connected.airpods" = "Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you don't need to hold the phone in your hand."; +"devices.explain_ar.connected.boseframes" = "Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you don't need to hold the phone in your hand."; /* */ "devices.explain_ar.paired" = "Soundscape is not currently connected to your %@. Please ensure your headphones are turned on and near your phone."; @@ -2789,7 +2789,7 @@ /* */ -"devices.connect_headset.explanation" = "Select the type of your headphones from the list of supported headphones below."; +"devices.connect_headset.explanation" = "Select the type of headphones from the list of supported headphones below."; /* */ @@ -2805,8 +2805,8 @@ /* */ -"devices.connect_headset.completed.airpods" = "Congratulations! Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. A single click on the headphones button will mute or unmute the beacon, double click will call out your location, and a triple click will repeat the last callout."; -"devices.connect_headset.completed.boseframes" = "Congratulations! Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you do not need to hold the phone in your hand."; +"devices.connect_headset.completed.airpods" = "Congratulations! Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you don't need to hold the phone in your hand. A single click on the headphones button will mute or unmute the beacon, a double click will call out your location, and a triple click will repeat the last callout."; +"devices.connect_headset.completed.boseframes" = "Congratulations! Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you don't need to hold the phone in your hand."; /* */ "devices.connect_headset.completed.test" = "Check Your Headphones"; @@ -2828,7 +2828,7 @@ /* */ -"devices.test_headset.callout" = "We've placed an audio beacon to your right. Listen where it is, and turn your head towards it… Notice how you can do this even when your phone is in your pocket."; +"devices.test_headset.callout" = "We've placed an audio beacon to your right. Listen where it is, and turn your head towards it. Notice how you can do this even when your phone is in your pocket."; /* */ @@ -2932,7 +2932,7 @@ /* */ -"behavior.experiences.reset.prompt" = "Resetting this activity will remove your current progress and allow you to start this activity over again. In addition to resetting this activity, you may also choose to check for updates. This will download updated information for this activity if any updates are available."; +"behavior.experiences.reset.prompt" = "Resetting this activity will remove your current progress and allow you to start this activity over again. You may also check for updates. This will download updated information for this activity if any updates are available."; /* */ @@ -3680,7 +3680,7 @@ /* */ -"help.text.destination_beacons.how.1" = "To set a beacon:
First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. From the location details screen you can select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; +"help.text.destination_beacons.how.1" = "To set a beacon:
First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. Then from the location details screen, select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; /* */ @@ -3708,7 +3708,7 @@ /* */ -"help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off in the \"Manage Callouts\" section of the \"Settings\" screen where you can tap the \"Allow Callouts\" toggle to turn them on or off. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; +"help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off by going to the \"Manage Callouts\" section of the \"Settings\" screen and then toggling the \"Allow Callouts\" button. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; /* */ @@ -3752,7 +3752,7 @@ /* */ -"help.text.ahead_of_me.what" = "The \"Ahead of Me\" button tells you about four things ahead of you. \"Ahead of Me\" is intended to help you explore the way ahead of yourself when you are learning about a new area."; +"help.text.ahead_of_me.what" = "The \"Ahead of Me\" button tells you about up to five things ahead of you. \"Ahead of Me\" is intended to help you explore the way ahead of yourself when you are learning about a new area."; /* */ @@ -3764,7 +3764,7 @@ /* */ -"help.text.remote_control.what" = "You can access certain features in Soundscape with the help of the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Also note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; +"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; /* */ @@ -3780,7 +3780,7 @@ /* */ -"help.text.markers.content.2" = "You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. You can mark any place or address, but you can also mark things that might traditionally not be available in maps, for example, entrances to buildings or parks, push-to-walk buttons, pedestrian crossings or bridges, bus stops or even your dog’s favourite tree and use these as references along your walk."; +"help.text.markers.content.2" = "You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. You can mark any place or address, but you can also mark things that aren't usually on maps, for example, entrances to buildings or parks, push-to-walk buttons, pedestrian crossings or bridges, bus stops or even your dog’s favourite tree and use these as references along your walk."; /* */ @@ -3792,11 +3792,11 @@ /* */ -"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. This step is optional. If you want to, you can change the name of the marker and also add an annotation that will be called out along with the marker to provide some extra information. Once you are done, select the \"Done\" button to save your Marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your Marker."; /* */ -"help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, then you can do so by selecting the marker from the \"Markers\" tab of the \"Markers & Routes\" page, then selecting the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; +"help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, select the marker from the \"Markers\" tab of the \"Markers & Routes\" page, and then select the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; /* */ @@ -4196,7 +4196,7 @@ /* */ -"faq.what_can_I_set.answer" = "You can set an audio beacon on any business, place, point of interest, address, or intersection. There are a few ways to set a location as a beacon. First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. From the location details screen you can select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; +"faq.what_can_I_set.answer" = "You can set an audio beacon on any business, place, point of interest, address, or intersection. There are a few ways to set a location as a beacon. First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. Then from the location details screen, select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; /* */ @@ -4204,7 +4204,7 @@ /* */ -"faq.how_to_use_beacon.answer" = "You can think of the audible beacon as a \"lighthouse for the ears\", notifying you of where your destination is relative to your location, as the crow flies. Like a lighthouse, it does not tell you how to get there – you may need to make many navigation choices along the way, just as a sailboat will have to make many strategic \"tacks\" to get closer to the lighthouse. The continuous rhythmic sound of the beacon is spatialised from the direction of the destination, and helps you stay aware of its location relative to you as you walk. When you are walking directly toward the destination, or you point the phone in that direction, a higher pitched \"ring\" sound will be heard. This feature allows you to pinpoint the direction of the destination since the direction of the rhythmic sound can sometimes be difficult to perceive in loud environments. When searching for the higher pitched \"ring\", hold the phone flat and sweep the phone slowly; turning your head to point in the same direction as the phone will ensure that you have the best spatial audio experience.\n\nThe lighthouse metaphor for the beacon’s design has several natural implications:\n\n1. There is no \"correct\" direction to travel when using the beacon, instead, with Soundscape you choose how to get there;\n2. The higher pitched \"ring\" helps you pinpoint the direction of the destination only – it is not an indication of how you should get there;\n3. If you generally know how to get to your destination, you may wish to mute the beacon for the majority of your trip and turn it on only as you get closer."; +"faq.how_to_use_beacon.answer" = "You can think of the audible beacon as a \"lighthouse for the ears\", notifying you of where your destination is relative to your location, as the crow flies. Like a lighthouse, it does not tell you how to get there – you may need to make many navigation choices along the way, just as a sailboat will have to make many strategic \"tacks\" to get closer to the lighthouse. The continuous rhythmic sound of the beacon is spatialised from the direction of the destination, and helps you stay aware of its location relative to you as you walk. When you are walking directly towards the destination, or you point the phone in that direction, a higher pitched \"ring\" sound will be heard. This feature allows you to pinpoint the direction of the destination since the direction of the rhythmic sound can sometimes be difficult to perceive in loud environments. When searching for the higher pitched \"ring\", hold the phone flat and sweep the phone slowly; turning your head to point in the same direction as the phone will ensure that you have the best spatial audio experience.\n\nThe lighthouse metaphor for the beacon’s design has several natural implications:\n\n1. There is no \"correct\" direction to travel when using the beacon, instead, with Soundscape you choose how to get there;\n2. The higher pitched \"ring\" helps you pinpoint the direction of the destination only – it is not an indication of how you should get there;\n3. If you generally know how to get to your destination, you may wish to mute the beacon for the majority of your trip and turn it on only as you get closer."; /* */ @@ -4212,7 +4212,7 @@ /* */ -"faq.why_does_beacon_disappear.answer" = "Soundscape’s audible beacon is fundamentally a directional cue, telling you where your destination is relative to the direction you are facing. When Soundscape is uncertain about what direction you are facing, it lowers the volume of the beacon. Most often this occurs if you have been walking with the phone stored in a pocket or bag, and you stop moving, such as to cross a street. The beacon will get louder once you start moving again, or if you hold the phone flat and point it in the direction you are facing."; +"faq.why_does_beacon_disappear.answer" = "Soundscape’s audible beacon is fundamentally a directional cue, telling you where your destination is relative to the direction you are facing. When Soundscape is uncertain about which way you are facing, it lowers the volume of the beacon. Most often this occurs if you have been walking with the phone stored in a pocket or bag, and you stop moving, such as to cross a street. The beacon will get louder once you start moving again, or if you hold the phone flat and point it away from you."; /* */ @@ -4260,7 +4260,7 @@ /* */ -"faq.why_not_every_business.answer" = "Soundscape is designed not to be too chatty. In addition, it uses Open Street Map as its back-end data source. Open Street Map (OSM, https://www.openstreetmap.org/) is a community-developed and edited map of the world, relying on individuals, to enter and curate the data. If a business or point of interest is not announced by Soundscape, the most probable reason is that the business has not been added, or in some cases updated, by a member of the OSM community yet."; +"faq.why_not_every_business.answer" = "Soundscape is designed not to be too chatty. In addition, it uses Open Street Map as its back-end data source. Open Street Map (OSM, https://www.openstreetmap.org/) is a community-developed and edited map of the world, relying on individuals, to enter and curate the data. If Soundscape doesn't announce a business or point of interest, the most probable reason is that the business has not been added, or in some cases updated, by an OSM community member yet."; /* */ @@ -4296,7 +4296,7 @@ /* */ -"faq.supported_headsets.answer" = "Which headphones you use with Soundscape is a matter of personal preference, and each option comes with benefits and trade-offs. The only specific requirement is to use a pair of stereo headphones so that you can take advantage of Soundscape’s 3D spatial audio callouts."; +"faq.supported_headsets.answer" = "Which headphones you use with Soundscape is a matter of personal preference, and each option comes with benefits and trade-offs. The only requirement is to use a pair of stereo headphones so that you can take advantage of Soundscape’s 3D spatial audio callouts."; /* */ @@ -4304,7 +4304,7 @@ /* */ -"faq.battery_impact.answer" = "Battery life varies significantly depending on which iPhone you own and how old it is. The biggest drain on your battery is having the screen on, so to maximise your phone's battery life you should keep the screen locked whenever possible. To help minimise the impact on your iPhone battery Soundscape now has a Sleep Mode and a Snooze Mode. To further reduce the amount of battery you use, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; +"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximise your phone's battery life you should keep the screen locked whenever possible. To help minimise the impact on your iPhone battery, Soundscape has a Sleep Mode and a Snooze Mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; /* */ @@ -4320,7 +4320,7 @@ /* */ -"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go in to a low power state until you leave your current location."; +"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go into a low power state until you leave your current location."; /* */ @@ -4336,7 +4336,7 @@ /* */ -"faq.background_battery_impact.answer" = "Soundscape uses Location Services to determine your location. In our tests, Soundscape does not consume any more battery than the average map application; but if you are concerned about your phone's battery consumption, the following are a few tips which will help lower usage:\n\n1. Turn the screen display off as much as possible when you are not interacting with the app.\n2. When not using the app, close it down. Soundscape uses location services continually when it is running so that it always knows your location, even when you are not moving. Don’t forget to restart the app when you resume your journey.\n3. In cold weather, keep your phone warm as batteries perform more poorly in colder temperatures."; +"faq.background_battery_impact.answer" = "Soundscape uses Location Services to determine where you are. In our tests, Soundscape does not consume any more battery than the average map application; but if you are concerned about your phone's battery consumption, the following are a few tips which will help lower usage:\n\n1. Turn the screen display off as much as possible when you are not interacting with the app.\n2. When not using the app, close it down. Soundscape uses location services continually when it is running so that it always knows your location, even when you are not moving. Don’t forget to restart the app when you resume your journey.\n3. In cold weather, keep your phone warm as batteries perform more poorly in colder temperatures."; /* */ @@ -4368,7 +4368,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not traveling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up again when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and choose to turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; +"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not travelling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; /* */ @@ -4376,7 +4376,7 @@ /* */ -"faq.holding_phone_flat.answer" = "No! While walking you can put the phone away in a bag or pocket or wherever is convenient. Soundscape will use the direction you are walking to figure out which callouts to announce to your left and to your right. When you stop moving, Soundscape does not know which direction you are facing. If the audible beacon is on, you will notice it get quiet until you start moving again. You can pull the phone out to tap the \"Hear My Surroundings\" buttons at the bottom of the home screen at any time, but make sure to hold the phone with the top of the phone pointing in the direction you are facing and with the screen to the sky. In this \"flat\" position, Soundscape will use the phone’s compass to determine which way you are facing and provide accurate spatial callouts. If the beacon is on, you will also notice that it returns to full volume."; +"faq.holding_phone_flat.answer" = "No! While walking you can put the phone away in a bag or pocket or wherever is convenient. Soundscape will use the direction you are walking to figure out which callouts to announce to your left and to your right. When you stop moving, Soundscape does not know which way you are facing. If the audible beacon is on, you will notice it get quiet until you start moving again. You can pull the phone out to tap the \"Hear My Surroundings\" buttons at the bottom of the home screen at any time, but make sure to hold the phone with the top of the phone pointing in the direction you are facing and with the screen to the sky. In this \"flat\" position, Soundscape will use the phone’s compass to determine which way you are facing and provide accurate spatial callouts. If the beacon is on, you will also notice that it returns to full volume."; /* */ @@ -4384,7 +4384,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape allows you to customise three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Distance Metric: Soundscape allows you to hear all distances in either feet or metres. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (metres).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the Nearby Markers button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following VoiceOver settings can influence how Soundscape behaves:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the primary Soundscape screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts that occur as you are interacting with the phone. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the My Location, Around Me, and Ahead of Me buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; +"faq.personalize_experience.answer" = "Soundscape allows you to customise three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or metres. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (metres).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the Nearby Markers button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behaviour:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the My Location, Around Me, and Ahead of Me buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; /* */ @@ -4400,7 +4400,7 @@ /* */ -"faq.tip.setting_beacon_on_address" = "You can set a beacon on any address. From the home screen, tap on the search bar and then type the address. After selecting the address in the search results, a \"Location Details\" screen will be shown and it has an option to \"Start Audio Beacon\" on the address. In this way, you can set a beacon on businesses, places, points of interest, and residences that are not in Open Street Map."; +"faq.tip.setting_beacon_on_address" = "You can set a beacon on any address. From the home screen, tap on the search bar and then type the address. After selecting the address in the search results, a \"Location Details\" screen will be shown containing the option to \"Start Audio Beacon\" on the address. In this way, you can set a beacon on businesses, places, points of interest, and residences that are not in Open Street Map."; /* */ @@ -4474,7 +4474,7 @@ "help.using_headsets.bose_frames.how.1" = "Connecting a Device:
Go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "help.using_headsets.bose_frames.when" = "You can use Bose Frames with Soundscape anytime you would normally use Soundscape. Using Bose Frames provides you with high quality audio that does not occlude environmental audio and allows you to have a more hands-free experience."; "help.using_headsets.bose_frames.title" = "Using Bose Frames"; -"help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can also repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; +"help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; "help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
Support for the Bose Frames is new and we would love to hear your feedback. You can contact us by choosing the \"Send Feedback\" Option in the menu."; "help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly."; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 38a404f3f..a33a463fa 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -327,7 +327,7 @@ "settings.clear_cache.alert_title" = "Delete Stored Data?"; /* Message, Soundscape stores map data to reduce device data and battery consumption {NumberedPlaceholder="Soundscape"} */ -"settings.clear_cache.alert_message" = "Soundscape stores map data to reduce data and battery consumption. Deleting stored data will require Soundscape to reload the data."; +"settings.clear_cache.alert_message" = "Soundscape stores map data to reduce cellular data and battery consumption. Deleting stored data will require Soundscape to reload the data."; /* Alert, would you like to keep saved markers */ "settings.clear_cache.markers.alert_title" = "Keep Markers and Routes?"; @@ -339,7 +339,7 @@ "settings.clear_cache.no_service.title" = "Unable to Clear Stored Map Data"; /* Message, the cached data cannot be deleted when there is no internet connection */ -"settings.clear_cache.no_service.message" = "Soundscape is currently unable to connect to the internet. An internet connection is required when clearing the stored map data so that the map data can be refreshed."; +"settings.clear_cache.no_service.message" = "Soundscape is currently unable to connect to the internet. An internet connection is required when clearing the stored map data so that the data can be refreshed."; /* Alert, opt-out of app telemetry */ "settings.telemetry.optout.alert_title" = "Telemetry Opt-Out"; @@ -569,7 +569,7 @@ "troubleshooting.check_audio" = "Check Audio"; /* Voiceover hint that explains the action of the "Check Audio" button. */ -"troubleshooting.check_audio.hint" = "Double tap to check the status of the headphones you are using with Soundscape."; +"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones."; /* Explanation of what the "Check Audio" button does, displayed below the button */ "troubleshooting.check_audio.explanation" = "Tap this button to hear about the status of the headphones you are using with Soundscape."; @@ -1383,7 +1383,7 @@ "routes.tutorial.title" = "Hear Your Waypoints on Your Journey"; /* Explanation of the route guidance feature that is presented to the user the first time that they try to start route guidance {NumberedPlaceholder="Soundscape"} */ -"routes.tutorial.details" = "You will now return to the Soundscape home page and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; +"routes.tutorial.details" = "You will now return to the Soundscape home screen and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; /* Callout indicating a the user has arrived at the final waypoint in their route and the route experience is now complete. */ "routes.callout.complete" = "Route complete!"; @@ -2290,10 +2290,10 @@ "devices.explain_ar.disconnected" = "Head tracking headphones are Bluetooth headphones with sensors that tell Soundscape where you are facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world.\n\nTap the button below to connect a device."; /* Message indicating that the app has successfully been connected to a head tracking headset, {NumberedPlaceholder="AirPods","Soundscape"} */ -"devices.explain_ar.connected.airpods" = "Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you do not need to hold the phone in your hand."; +"devices.explain_ar.connected.airpods" = "Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you don't need to hold the phone in your hand."; /* Message indicating that the app has successfully been connected to Bose Frames */ -"devices.explain_ar.connected.boseframes" = "Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you do not need to hold the phone in your hand."; +"devices.explain_ar.connected.boseframes" = "Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape is tracking the direction of your head so you don't need to hold the phone in your hand."; /* Message indicating that the app has successfully been paired to head tracking headphones but is not connected, %@ headset name, "Soundscape is not currently connected to your AirPods Pro. Please ensure your headset is turned on and near your phone." {NumberedPlaceholder="%@"} */ "devices.explain_ar.paired" = "Soundscape is not currently connected to your %@. Please ensure your headphones are turned on and near your phone."; @@ -2323,7 +2323,7 @@ "devices.connect_headset.unavailable" = "The device you've selected is currently unavailable for connection. Please try again later."; /* Prompt presented to the user when they try to connect to an head tracking headset */ -"devices.connect_headset.explanation" = "Select the type of your headphones from the list of supported headphones below."; +"devices.connect_headset.explanation" = "Select the type of headphones from the list of supported headphones below."; /* Prompt presented to the user before they connect to their headset which indicates that they need to pair to the device through iOS Settings > Bluetooth */ "devices.connect_headset.audio" = "Before connecting your headphones to Soundscape, be sure it is paired to your phone. If it is not yet paired, go to the Bluetooth section in the iOS Settings app to pair your device and then return to Soundscape."; @@ -2335,10 +2335,10 @@ "devices.connect_headset.calibrate.in_ear" = "Your headphones need to be calibrated. Gently shake your head in all directions for about 10 seconds. This must be repeated if the calibration chime continues to play."; /* Message displayed to the user after they successfully connect Soundscape to their AR headset. {NumberedPlaceholder="AirPods", "Soundscape"} */ -"devices.connect_headset.completed.airpods" = "Congratulations! Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. A single click on the headphones button will mute or unmute the beacon, double click will call out your location, and a triple click will repeat the last callout."; +"devices.connect_headset.completed.airpods" = "Congratulations! Your AirPods are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you don't need to hold the phone in your hand. A single click on the headphones button will mute or unmute the beacon, a double click will call out your location, and a triple click will repeat the last callout."; /* D.o for Bose Frame (Rondo) */ -"devices.connect_headset.completed.boseframes" = "Congratulations! Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you do not need to hold the phone in your hand."; +"devices.connect_headset.completed.boseframes" = "Congratulations! Your Bose Frames are ready for use, so you can put your phone in your pocket and go! Soundscape will now track the direction of your head so you don't need to hold the phone in your hand."; /* Button label for a button that allows users to test their newly connected headset */ "devices.connect_headset.completed.test" = "Check Your Headphones"; @@ -2350,13 +2350,13 @@ "devices.test_headset.title" = "Headphones Check"; /* Label explaining to the user that how the headset test works and what they should do */ -"devices.test_headset.explanation" = "We've placed an audio beacon to your right. Listen where it is, and turn your head towards it. Notice how you can do this even when your phone is in your pocket. When you are done, Tap the button below to return to Soundscape, and enjoy your next walk with your new head tracking headphones."; +"devices.test_headset.explanation" = "We've placed an audio beacon to your right. Listen where it is, and turn your head toward it. Notice how you can do this even when your phone is in your pocket. When you are done, Tap the button below to return to Soundscape, and enjoy your next walk with your new head tracking headphones."; /* Button title for a button that ends the headset testing process and returns the user to Soundscape */ "devices.test_headset.continue" = "Return to Soundscape"; /* Announcement that occurs when the user presses the "Check Your Headphones" button */ -"devices.test_headset.callout" = "We've placed an audio beacon to your right. Listen where it is, and turn your head towards it… Notice how you can do this even when your phone is in your pocket."; +"devices.test_headset.callout" = "We've placed an audio beacon to your right. Listen where it is, and turn your head toward it. Notice how you can do this even when your phone is in your pocket."; /* Title of a prompt that is presented to users when they tap the "Forget This Device" button to disconnect and forget a head tracking headset */ "devices.forget_headset.prompt.forget" = "Are you sure you wish to forget these headphones?"; @@ -2440,7 +2440,7 @@ "behavior.experiences.reset_and_update_action" = "Check for Updates"; /* Prompt presented to users when they tap the "Reset" action for an activity. This prompt informs the user what happens when they reset an activity and confirms whether or not they want to proceed. */ -"behavior.experiences.reset.prompt" = "Resetting this activity will remove your current progress and allow you to start this activity over again. In addition to resetting this activity, you may also choose to check for updates. This will download updated information for this activity if any updates are available."; +"behavior.experiences.reset.prompt" = "Resetting this activity will remove your current progress and allow you to start this activity over again. You may also check for updates. This will download updated information for this activity if any updates are available."; /* Explanation prompt that tells the users that if they choose to check for updates to the event, the event will be reset and any available updates will be downloaded. */ "behavior.experiences.updates.prompt" = "If any updates are available, this will reset this activity and download the updates."; @@ -2645,7 +2645,7 @@ "tutorial.markers.text.NearbyMarkers" = "Excellent! You have a new marker named @!marker_name!!.\nNow, to hear where your marker is, press the Nearby Markers button. This button can be found at the bottom of the main screen.\nTry it out now."; /* Tutorial, set Audio Beacon from Marker. {NumberedPlaceholder="@!marker_name!!", "\n"} */ -"tutorial.markers.text.AudioBeacon" = "You can also set an audio beacon on your marker.\nLet's try it out. Here is the beacon on @!marker_name!!.\nListen carefully where it is, and holding your phone flat, turn towards it."; +"tutorial.markers.text.AudioBeacon" = "You can also set an audio beacon on your marker.\nLet's try it out. Here is the beacon on @!marker_name!!.\nListen carefully where it is, and holding your phone flat, turn toward it."; /* Tutorial, Marker Wrap Up. {NumberedPlaceholder="@!marker_name!!", "\n"} */ "tutorial.markers.text.WrapUp" = "Perfect, you are now facing your marker, @!marker_name!!.\nIt looks like you've got it!\nYou can manage your list of markers by selecting Markers & Routes from the home screen.\nAnd you can always visit the Help & Tutorials pages to go through this tutorial again or to read a comprehensive guide on everything you can do with markers. The beacon you've set for this tutorial will now be cleared and you will be returned to the previous screen."; @@ -2695,16 +2695,16 @@ "tutorial.beacons.text.IntroPart2" = "Press the \"Start Audio Beacon\" button below to open a list of nearby places. Choose a location from the list and the tutorial will begin."; /* Tutorial, Beacon phone orientation is flat */ -"tutorial.beacons.text.OrientationIsFlat" = "You are currently holding your phone flat with the screen facing up towards the sky. Make sure the top of the phone is pointing straight ahead of you."; +"tutorial.beacons.text.OrientationIsFlat" = "You are currently holding your phone flat with the screen facing up toward the sky. Make sure the top of the phone is pointing straight ahead of you."; /* Tutorial, Beacon phone orientation is not flat */ -"tutorial.beacons.text.OrientationIsNotFlat" = "To get started, hold your phone flat in your hand with the screen facing up towards the sky and with the top of the phone pointing straight ahead of you."; +"tutorial.beacons.text.OrientationIsNotFlat" = "To get started, hold your phone flat in your hand with the screen facing up toward the sky and with the top of the phone pointing straight ahead of you."; /* Tutorial, Phone orientation doesn't matter because the user is wearing AirPods Pro {NumberedPlaceholder="Soundscape","AirPods"} */ "tutorial.beacons.text.OrientationAirPods" = "Your AirPods are connected to Soundscape. Once they're connected, it doesn't matter how you hold your phone. It can even go in your pocket or bag."; /* Tutorial, Beacon phone orientation repeat */ -"tutorial.beacons.text.OrientationRepeat" = "To continue, hold your phone flat in your hand so that the screen is facing up towards the sky"; +"tutorial.beacons.text.OrientationRepeat" = "To continue, hold your phone flat in your hand so that the screen is facing up toward the sky"; /* Tutorial, phone must be held flat when you are standing still */ "tutorial.beacons.text.HoldingPhone" = "Holding your phone flat in this way is only required when you are standing still. When walking feel free to place the phone in an easily accessible pocket or bag."; @@ -2719,10 +2719,10 @@ "tutorial.beacons.text.BeaconOutOfBounds" = "If you listen carefully you will hear that it is playing from a certain direction around you."; /* Tutorial, Beacon out of Bounds sound change when phone is rotated */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Now, still holding your phone flat, slowly turn towards the direction of the beacon. You will hear a bell sound when you are facing directly towards it."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Now, still holding your phone flat, slowly turn toward the direction of the beacon. You will hear a bell sound when you are facing directly toward it."; /* Tutorial, Beacon out of bounds sound change when head tracking headphones is rotated */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Now, slowly turn towards the direction of the beacon. You will hear a bell sound when you are facing directly towards it."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Now, slowly turn toward the direction of the beacon. You will hear a bell sound when you are facing directly toward it."; /* Tutorial, Beacon out of Bounds repeat */ "tutorial.beacons.text.BeaconOutOfBoundsRepeat" = "Slowly turn until you hear the bell indicating you are facing in the direction of the beacon."; @@ -2731,7 +2731,7 @@ "tutorial.beacons.text.BeaconOutOfBoundsConfirmation" = "Perfect, you are now facing in the direction of @!destination!!."; /* Tutorial, Beacon in bounds sound. {NumberedPlaceholder="@!destination!!"} */ -"tutorial.beacons.text.BeaconInBounds" = "If you listen carefully you will hear that it is playing from right in front of you and that there is a bell sound in addition to the normal beacon sound. That is because you are facing directly towards @!destination!!."; +"tutorial.beacons.text.BeaconInBounds" = "If you listen carefully you will hear that it is playing from right in front of you and that there is a bell sound in addition to the normal beacon sound. That is because you are facing directly toward @!destination!!."; /* Tutorial, Beacon in of Bounds sound change when phone is rotated. {NumberedPlaceholder="@!destination!!"} */ "tutorial.beacons.text.BeaconInBoundsRotate" = "Now try to slowly turn away from the direction of the beacon, while still holding your phone flat. The bell sound will stop and the beacon continues to show you where @!destination!! is. Give it a try now."; @@ -2743,7 +2743,7 @@ "tutorial.beacons.text.BeaconInBoundsRepeat" = "Slowly turn away from the direction of the beacon."; /* Tutorial, Beacon explanation */ -"tutorial.beacons.text.MobilitySkills" = "The beacon always points directly towards the location you've selected. It does not tell you the paths to follow or give you directions to get to that location. Use this beacon as a tool to decide how you want to get there."; +"tutorial.beacons.text.MobilitySkills" = "The beacon always points directly toward the location you've selected. It does not tell you the paths to follow or give you directions to get to that location. Use this beacon as a tool to decide how you want to get there."; /* Tutorial, Automatic Callouts {NumberedPlaceholder="Soundscape"} */ "tutorial.beacons.text.AutomaticCallout" = "As you progress on your journey, Soundscape will occasionally update you about the distance to the location marked by the beacon with a callout like this."; @@ -3059,7 +3059,7 @@ "help.text.destination_beacons.when" = "Setting a beacon is useful when you want to keep track of a familiar landmark as you explore a new area or when you are going somewhere and want to be informed about your surroundings along the way. The beacon feature does not give you turn-by-turn directions, but it does give you a continuous audible sound that tells you the direction to the beacon, relative to where you are currently located. Using the audio beacon, your existing wayfinding skills, and even your favorite navigation app, you can choose how you want to get to nearby locations yourself."; /* Notification, Information how to set a beacon. Ensure that "Set a Beacon" is translated the same as `universal_links.alert.action.beacon`. Quotes written as \" {NumberedPlaceholder="","","
"} */ -"help.text.destination_beacons.how.1" = "To set a beacon:
First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. From the location details screen you can select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; +"help.text.destination_beacons.how.1" = "To set a beacon:
First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. Then from the \"Location Details\" screen, select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; /* Notification, Information how to set a beacon continued. Ensure that "Remove Beacon" is translated the same as `beacon.action.remove_beacon`. Quotes written as \" {NumberedPlaceholder="","","
"} */ "help.text.destination_beacons.how.2" = "To remove the current beacon:
Simply press the \"Remove Beacon\" button on the home screen."; @@ -3080,7 +3080,7 @@ "help.text.automatic_callouts.when.3" = "When you need silence:
When you are about to cross a road or just need the app to be quiet, you can turn callouts off. When callouts are off, the app will only tell you information if you manually tap one of the \"My Location\", \"Nearby Markers\", \"Around Me\", or \"Ahead of Me\" buttons."; /* Notification, Information how to turn on callouts. Ensure that "Manage Callouts" is translated the same as `menu.manage_callouts` and "Callouts Off" is translated the same as `callouts.callouts_off` and "Allow callouts" is translated the same as `callouts.allow_callouts`. Quotes written as \" {NumberedPlaceholder="","","
"} */ -"help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off in the \"Manage Callouts\" section of the \"Settings\" screen where you can tap the \"Allow Callouts\" toggle to turn them on or off. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; +"help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off by going to the \"Manage Callouts\" section of the \"Settings\" screen and then toggling the \"Allow Callouts\" button. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; /* Notification, Information how to turn on callouts continued. Ensure that "Manage Callouts" is translated the same as `menu.manage_callouts` and "Allow callouts" is translated the same as `callouts.allow_callouts`. Quotes written as \" {NumberedPlaceholder="","","
"} */ "help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings Screen\" contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; @@ -3092,7 +3092,7 @@ "help.text.my_location.when" = "\"My Location\" is useful when you need to figure out where you are or what cardinal direction you are facing."; /* Notification, Information how to use My Location. Ensure that "My Location" is translated the same as `directions.my_location`. Quotes written as \" {NumberedPlaceholder="",""} */ -"help.text.my_location.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing towards the sky) and the top of the phone pointing in the direction you are facing before you press the \"My Location\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"My Location\" button and listen."; +"help.text.my_location.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing toward the sky) and the top of the phone pointing in the direction you are facing before you press the \"My Location\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"My Location\" button and listen."; /* Notification, Information about what Nearby Markers does. Ensure that "Nearby Markers" is translated the same as `callouts.nearby_markers`. Quotes written as \" {NumberedPlaceholder="",""} */ "help.text.nearby_markers.what" = "The \"Nearby Markers\" button tells you about up to four markers that are closest to you. \"Nearby Markers\" is intended to help you orient yourself using places you already know about."; @@ -3101,7 +3101,7 @@ "help.text.nearby_markers.when" = "When you are trying to get your bearings and orient yourself to your surroundings, use \"Nearby Markers\" to hear about the locations of places you know of."; /* Notification, Information about how to use Nearby Markers. Ensure that "Nearby Markers" is translated the same as `callouts.nearby_markers`. Quotes written as \" {NumberedPlaceholder="",""} */ -"help.text.nearby_markers.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing towards the sky) and the top of the phone pointing in the direction you are facing before you press the \"Nearby Markers\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Nearby Markers\" button and you will hear up to four markers near you."; +"help.text.nearby_markers.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing toward the sky) and the top of the phone pointing in the direction you are facing before you press the \"Nearby Markers\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Nearby Markers\" button and you will hear up to four markers near you."; /* Notification, Information about what Around Me does. Ensure that "Around Me" is translated the same as `help.orient.page_title`. Quotes written as \" {NumberedPlaceholder="",""} */ "help.text.around_me.what" = "The \"Around Me\" button tells you about one thing in each of the four quadrants around you (ahead, to the right, behind, and to the left). \"Around Me\" is intended to help you orient yourself to your surroundings."; @@ -3110,19 +3110,19 @@ "help.text.around_me.when" = "When you are trying to get your bearings and orient yourself to your surroundings, use \"Around Me\" to hear about the things around you."; /* Notification, Information about how to use Around Me. Ensure that "Around Me" is translated the same as `help.orient.page_title`. Quotes written as \" {NumberedPlaceholder="",""} */ -"help.text.around_me.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing towards the sky) and the top of the phone pointing in the direction you are facing before you press the \"Around Me\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Around Me\" button and you will hear four points of interest arranged around you."; +"help.text.around_me.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing toward the sky) and the top of the phone pointing in the direction you are facing before you press the \"Around Me\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Around Me\" button and you will hear four points of interest arranged around you."; /* Notification, Information about what Ahead of Me does. Ensure that "Ahead of Me" is translated the same as `help.explore.page_title`. Quotes written as \" {NumberedPlaceholder="",""} */ -"help.text.ahead_of_me.what" = "The \"Ahead of Me\" button tells you about four things ahead of you. \"Ahead of Me\" is intended to help you explore the way ahead of yourself when you are learning about a new area."; +"help.text.ahead_of_me.what" = "The \"Ahead of Me\" button tells you about up to five things ahead of you. \"Ahead of Me\" is intended to help you explore the way ahead of yourself when you are learning about a new area."; /* Notification, Information about when to use Ahead of Me. Ensure that "Ahead of Me" is translated the same as `help.explore.page_title`. Quotes written as \" {NumberedPlaceholder="",""} */ "help.text.ahead_of_me.when" = "When you are walking down the street, try using \"Ahead of Me\" to discover the places and things coming up on either side of the street ahead."; /* Notification, Information about how to use Ahead of Me. Ensure that "Ahead of Me" is translated the same as `help.explore.page_title`. Quotes written as \" {NumberedPlaceholder="",""} */ -"help.text.ahead_of_me.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing towards the sky) and the top of the phone pointing in the direction you are facing before you press the \"Ahead of Me\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Ahead of Me\" button and you will hear several points of interest all roughly ahead of you."; +"help.text.ahead_of_me.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing toward the sky) and the top of the phone pointing in the direction you are facing before you press the \"Ahead of Me\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Ahead of Me\" button and you will hear several points of interest all roughly ahead of you."; /* Notification, Information about what headphone media controls do in Soundscape. Keep HTML tags. {NumberedPlaceholder="Soundscape", "
"} */ -"help.text.remote_control.what" = "You can access certain features in Soundscape with the help of the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Also note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; +"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; /* Notification, Information about when to use media controls on headphones. {NumberedPlaceholder="Soundscape"} */ "help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while Soundscape is in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; @@ -3134,7 +3134,7 @@ "help.text.markers.content.1" = "With Soundscape, you can mark your world and anything you care about."; /* Notification, Markers content continued */ -"help.text.markers.content.2" = "You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. You can mark any place or address, but you can also mark things that might traditionally not be available in maps, for example, entrances to buildings or parks, push-to-walk buttons, pedestrian crossings or bridges, bus stops or even your dog’s favorite tree and use these as references along your walk."; +"help.text.markers.content.2" = "You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. You can mark any place or address, but you can also mark things that aren't usually on maps, for example, entrances to buildings or parks, push-to-walk buttons, pedestrian crossings or bridges, bus stops or even your dog’s favorite tree and use these as references along your walk."; /* Notification, Markers content continued {NumberedPlaceholder="Soundscape"} */ "help.text.markers.content.3" = "To experience marked places, Soundscape will automatically call out marked places as you walk by or approach them, or you can use the Nearby markers button at the bottom of the home screen to hear a spatial callout of marked places around you. You can even set an audio beacon on any marked place. When you do this, the Soundscape audio beacon you are familiar with, will be heard and you can operate it as usual."; @@ -3143,10 +3143,10 @@ "help.text.creating_markers.content.1" = "You can create markers in three ways: searching for the place you would like to save using the search bar, finding somewhere using the \"Places Nearby\" button, or using the \"Current Location\" button, all of which can be found on the Soundscape home screen. Once you have found the place you would like, selecting it will take you to the \"Location Details\" page. On this page, select the button called \"Save as Marker\"."; /* Notification, Creating Markers help content continued, Quotation marks are written as \" */ -"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. This step is optional. If you want to, you can change the name of the marker and also add an annotation that will be called out along with the marker to provide some extra information. Once you are done, select the \"Done\" button to save your Marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your Marker."; /* Notification, Customizing Markers help content. "Markers & Routes" should be translated the same as the string with key 'search.view_markers'. Quotes written as \" */ -"help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, then you can do so by selecting the marker from the \"Markers\" tab of the \"Markers & Routes\" page, then selecting the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; +"help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, select the marker from the \"Markers\" tab of the \"Markers & Routes\" page, and then select the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; /* Notification, Customizing Markers help content continued */ "help.text.customizing_markers.content.2" = "From this Edit screen, you can also delete a marker if you no longer need it."; @@ -3155,7 +3155,7 @@ "help.text.routes.content.what" = "Routes are a series of waypoints. You will be informed on arrival to each waypoint, and the Audio Beacon will automatically advance to the next waypoint."; /* Help content explaining when a user might choose to use the routes feature */ -"help.text.routes.content.when" = "You may want to create and use a route somewhere you know to make sure you keep on track, or you may want to use it as a tool to help familiarise yourself along a new journey."; +"help.text.routes.content.when" = "You may want to create and use a route somewhere you know to make sure you keep on track, or you may want to use it as a tool to help familiarize yourself along a new journey."; /* Help content explaining how a user can create a route. Quotes written as \" */ "help.text.routes.content.how.1" = "Creating a route:
First, go to \"Markers & Routes\", select the \"Routes\" tab, and then select the \"New Route\" button. Give the route a name and an optional description, then add waypoints as you go or pick them from your list of Markers. You can rearrange the order of the waypoints along a route at any time by editing the route."; @@ -3191,7 +3191,7 @@ "help.using_headsets.bose_frames.how.1" = "Connecting a Device:
Go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; /* information on how to calibrate Bose Frames with Soundscape, Quotes written as \", {NumberedPlaceholder="Soundscape","Bose Frames"} */ -"help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can also repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; +"help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; /* Information on how to use the media buttons on Bose Frames */ "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; @@ -3551,7 +3551,7 @@ "faq.what_can_I_set.question" = "What can I set as a beacon?"; /* An 'audio beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Intersection - A junction where two or more roads meet or cross., Marker - A location that has been marked as important by the user or application. This can be an address, a business or a custom place such as an entrance, a bus stop or a bench. Point of interest - A specific location that someone may find useful or interesting. Quotation marks are written as \" */ -"faq.what_can_I_set.answer" = "You can set an audio beacon on any business, place, point of interest, address, or intersection. There are a few ways to set a location as a beacon. First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. From the location details screen you can select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; +"faq.what_can_I_set.answer" = "You can set an audio beacon on any business, place, point of interest, address, or intersection. There are a few ways to set a location as a beacon. First, view the details for a location by either using the search bar to search for a place, or tapping one of the \"Places Nearby\", \"Markers & Routes\", or \"Current Location\" buttons and selecting a location. Then from the \"Location Details\" screen, select the \"Start Audio Beacon\" button. Tapping this will return you to the home screen and turn on an audible beacon coming from the direction of the place you've selected. The name of the place along with its distance and physical address, if available, will now be displayed on the main screen."; /* A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. */ "faq.how_to_use_beacon.question" = "How do I use a beacon like a pro?"; @@ -3563,7 +3563,7 @@ "faq.why_does_beacon_disappear.question" = "Why does the audible beacon disappear sometimes?"; /* A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.why_does_beacon_disappear.answer" = "Soundscape’s audible beacon is fundamentally a directional cue, telling you where your destination is relative to the direction you are facing. When Soundscape is uncertain about what direction you are facing, it lowers the volume of the beacon. Most often this occurs if you have been walking with the phone stored in a pocket or bag, and you stop moving, such as to cross a street. The beacon will get louder once you start moving again, or if you hold the phone flat and point it in the direction you are facing."; +"faq.why_does_beacon_disappear.answer" = "Soundscape’s audible beacon is fundamentally a directional cue, telling you where your destination is relative to the direction you are facing. When Soundscape is uncertain about which way you are facing, it lowers the volume of the beacon. Most often this occurs if you have been walking with the phone stored in a pocket or bag, and you stop moving, such as to cross a street. The beacon will get louder once you start moving again, or if you hold the phone flat and point it away from you."; /* A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. */ "faq.beacon_on_address.question" = "Can I set a beacon on an address?"; @@ -3599,7 +3599,7 @@ "faq.why_not_every_business.question" = "Why doesn’t Soundscape announce every business that I pass?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape","Open Street Map","OSM"} */ -"faq.why_not_every_business.answer" = "Soundscape is designed not to be too chatty. In addition, it uses Open Street Map as its back-end data source. Open Street Map (OSM, https://www.openstreetmap.org/) is a community-developed and edited map of the world, relying on individuals, to enter and curate the data. If a business or point of interest is not announced by Soundscape, the most probable reason is that the business has not been added, or in some cases updated, by a member of the OSM community yet."; +"faq.why_not_every_business.answer" = "Soundscape is designed not to be too chatty. In addition, it uses Open Street Map as its back-end data source. Open Street Map (OSM, https://www.openstreetmap.org/) is a community-developed and edited map of the world, relying on individuals, to enter and curate the data. If Soundscape doesn't announce a business or point of interest, the most probable reason is that the business has not been added, or in some cases updated, by an OSM community member yet."; /* Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. */ "faq.callouts_stopping_in_vehicle.question" = "Why do some callouts stop when I'm in a vehicle?"; @@ -3628,25 +3628,25 @@ "faq.supported_headsets.question" = "What headphones should I use with Soundscape?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. 3D spatial audio is where the audio through your headphones sounds as though it is coming from a given direction, as if it was actually coming from a speaker. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. {NumberedPlaceholder="Soundscape"} */ -"faq.supported_headsets.answer" = "Which headphones you use with Soundscape is a matter of personal preference, and each option comes with benefits and trade-offs. The only specific requirement is to use a pair of stereo headphones so that you can take advantage of Soundscape’s 3D spatial audio callouts."; +"faq.supported_headsets.answer" = "Which headphones you use with Soundscape is a matter of personal preference, and each option comes with benefits and trade-offs. The only requirement is to use a pair of stereo headphones so that you can take advantage of Soundscape’s 3D spatial audio callouts."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.battery_impact.question" = "How does Soundscape impact my iPhone’s battery?"; /* Sleep - To put the app in an idle state for a period of time. Snooze - To put the app in an idle state that is interrupted by user movement. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape","iPhone"} */ -"faq.battery_impact.answer" = "Battery life varies significantly depending on which iPhone you own and how old it is. The biggest drain on your battery is having the screen on, so to maximize your phone's battery life you should keep the screen locked whenever possible. To help minimize the impact on your iPhone battery Soundscape now has a Sleep Mode and a Snooze Mode. To further reduce the amount of battery you use, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; +"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximize your phone's battery life you should keep the screen locked whenever possible. To help minimize the impact on your iPhone battery, Soundscape has a Sleep Mode and a Snooze Mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; /* Sleep - To put the app in an idle state for a period of time. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.sleep_mode_battery.question" = "How do I use Sleep Mode to minimize Soundscape’s impact on my phone battery?"; /* Sleep - To put the app in an idle state for a period of time. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. "Location Services" refers to the feature of the same name in iOS. It should be translated in the same manner that it is in the Settings app under Settings > Privacy > Location Services. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and mobile data until you wake it up."; +"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and cellular data until you wake it up."; /* Snooze - To put the app in an idle state that is interrupted by user movement. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.snooze_mode_battery.question" = "How do I use Snooze mode to minimize Soundscape’s impact on my phone battery?"; /* Snooze - To put the app in an idle state that is interrupted by user movement. Sleep - To put the app in an idle state for a period of time. Wake Up - To restore the app from a sleep (idle) state. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go in to a low power state until you leave your current location."; +"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go into a low power state until you leave your current location."; /* A question about how different headsets affect the phone's battery consumption */ "faq.headset_battery_impact.question" = "How does my choice of headphones affect my phone's battery life?"; @@ -3658,13 +3658,13 @@ "faq.background_battery_impact.question" = "How does running Soundscape in the background impact my phone's battery life?"; /* 'Location Services' in the name of the iPhone feature that gives an app the iPhones location. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.background_battery_impact.answer" = "Soundscape uses Location Services to determine your location. In our tests, Soundscape does not consume any more battery than the average map application; but if you are concerned about your phone's battery consumption, the following are a few tips which will help lower usage:\n\n1. Turn the screen display off as much as possible when you are not interacting with the app.\n2. When not using the app, close it down. Soundscape uses location services continually when it is running so that it always knows your location, even when you are not moving. Don’t forget to restart the app when you resume your journey.\n3. In cold weather, keep your phone warm as batteries perform more poorly in colder temperatures."; +"faq.background_battery_impact.answer" = "Soundscape uses Location Services to determine where you are. In our tests, Soundscape does not consume any more battery than the average map application; but if you are concerned about your phone's battery consumption, the following are a few tips which will help lower usage:\n\n1. Turn the screen display off as much as possible when you are not interacting with the app.\n2. When not using the app, close it down. Soundscape uses location services continually when it is running so that it always knows your location, even when you are not moving. Don’t forget to restart the app when you resume your journey.\n3. In cold weather, keep your phone warm as batteries perform more poorly in colder temperatures."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.mobile_data_use.question" = "How much mobile data does Soundscape use?"; +"faq.mobile_data_use.question" = "How much cellular data does Soundscape use?"; /* Wi-Fi - The set of standards for delivering digital information over high-frequency, wireless local area networks, defined by IEEE 802.11. 'Force close' is referring to the way to completely close an iPhone app rather than just putting it in to the background. "Sleep" should be translated the in the same way as the string for key "sleep.sleep". Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.mobile_data_use.answer" = "The amount of mobile data used depends on how you use Soundscape. We have designed Soundscape to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to download them again every time you go back to somewhere you’ve already been. To reduce the amount of mobile data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; +"faq.mobile_data_use.answer" = "The amount of cellular data used depends on how you use Soundscape. We have designed Soundscape to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to download them again every time you go back to somewhere you’ve already been. To reduce the amount of cellular data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.difference_from_map_apps.question" = "How is Soundscape different from other map apps?"; @@ -3682,19 +3682,19 @@ "faq.controlling_what_you_hear.question" = "How do I control what I hear and when I hear it in Soundscape?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. A 'beacon' or 'audio beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Intersection - A junction where two or more roads meet or cross. Point of interest - A specific location that someone may find useful or interesting. Snooze - To put the app in an idle state that is interrupted by user movement. Sleep - To put the app in an idle state for a period of time. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not traveling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up again when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and choose to turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; +"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not traveling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; /* A frequently asked question about how the user should hold their phone */ "faq.holding_phone_flat.question" = "Do I need to hold the phone in my hand all the time?"; /* Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.holding_phone_flat.answer" = "No! While walking you can put the phone away in a bag or pocket or wherever is convenient. Soundscape will use the direction you are walking to figure out which callouts to announce to your left and to your right. When you stop moving, Soundscape does not know which direction you are facing. If the audible beacon is on, you will notice it get quiet until you start moving again. You can pull the phone out to tap the \"Hear My Surroundings\" buttons at the bottom of the home screen at any time, but make sure to hold the phone with the top of the phone pointing in the direction you are facing and with the screen to the sky. In this \"flat\" position, Soundscape will use the phone’s compass to determine which way you are facing and provide accurate spatial callouts. If the beacon is on, you will also notice that it returns to full volume."; +"faq.holding_phone_flat.answer" = "No! While walking you can put the phone away in a bag or pocket or wherever is convenient. Soundscape will use the direction you are walking to figure out which callouts to announce to your left and to your right. When you stop moving, Soundscape does not know which way you are facing. If the audible beacon is on, you will notice it get quiet until you start moving again. You can pull the phone out to tap the \"Hear My Surroundings\" buttons at the bottom of the home screen at any time, but make sure to hold the phone with the top of the phone pointing in the direction you are facing and with the screen to the sky. In this \"flat\" position, Soundscape will use the phone’s compass to determine which way you are facing and provide accurate spatial callouts. If the beacon is on, you will also notice that it returns to full volume."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.personalize_experience.question" = "In what ways can I personalize my Soundscape experience?"; /* All of the terms in the string "Settings > Accessibility > Spoken Content > Voices" should be translated such that they are consistant with those in the iOS Settings app. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. 'Nearby Markers' is the name of one of the buttons in the app. 'Voiceover' is an iPhone feature to help people who are visually impaired use the iPhone. 'Audio Ducking' is the name of an accessibility feature on the iPhone which reduces the volume of an app while 'Voiceover' is speaking. 'Touch ID' is the name of the iPhone feature for unlocking your phone using your finger print. 'Face ID' is the name of the iPhone feature for unlocking your phone using your face. 'Passcode' and 'iPhone Unlock' are all names of sections in the iPhone 'Settings' app. 'My Location', 'Around Me' and 'Ahead of Me' are buttons in the Soundscape app. {NumberedPlaceholder="Soundscape", "VoiceOver","Touch ID", "Face ID","iOS"} */ -"faq.personalize_experience.answer" = "Soundscape allows you to customize three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Distance Metric: Soundscape allows you to hear all distances in either feet or meters. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (meters).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the Nearby Markers button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following VoiceOver settings can influence how Soundscape behaves:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the primary Soundscape screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts that occur as you are interacting with the phone. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the My Location, Around Me, and Ahead of Me buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; +"faq.personalize_experience.answer" = "Soundscape allows you to customize three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or meters. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (meters).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the Nearby Markers button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behavior:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the My Location, Around Me, and Ahead of Me buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape","Open Street Map"} */ "faq.what_is_osm.question" = "What is Open Street Map and why do we use it for Soundscape?"; @@ -3708,7 +3708,7 @@ "faq.tip.beacon_quiet" = "If you put your phone in your pocket and stop moving, the beacon sound will get quieter because Soundscape can’t tell which way you are facing. Solve this by starting to walk again, or pulling your phone out and holding it flat."; /* The 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. "Start Audio Beacon" should be translated the same as "location_detail.action.beacon" Quotes written as \" */ -"faq.tip.setting_beacon_on_address" = "You can set a beacon on any address. From the home screen, tap on the search bar and then type the address. After selecting the address in the search results, a \"Location Details\" screen will be shown and it has an option to \"Start Audio Beacon\" on the address. In this way, you can set a beacon on businesses, places, points of interest, and residences that are not in Open Street Map."; +"faq.tip.setting_beacon_on_address" = "You can set a beacon on any address. From the home screen, tap on the search bar and then type the address. After selecting the address in the search results, a \"Location Details\" screen will be shown containing the option to \"Start Audio Beacon\" on the address. In this way, you can set a beacon on businesses, places, points of interest, and residences that are not in Open Street Map."; /* 'Nearby Places' is a screen in the app that shows a list of places that are close to the user. Quotes written as \" */ "faq.tip.finding_bus_stops" = "You can find nearby bus stops by selecting the \"Public Transit\" filter in the Nearby Places list."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 3cef5efce..969b84244 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -163,7 +163,7 @@ /* */ -"general.alert.offline_search.message" = "Cuando Soundscape funciona sin conexión, la búsqueda está desactivada. Descartar para volver a la pantalla anterior"; +"general.alert.offline_search.message" = "Cuando Soundscape funciona sin conexión, la búsqueda está deshabilitada. Descartar para volver a la pantalla anterior"; /* */ @@ -179,7 +179,7 @@ /* */ -"general.loading.end" = "Limpiando…"; +"general.loading.end" = "Poniendo todo en orden…"; /* */ @@ -231,19 +231,19 @@ /* */ -"general.error.location_services" = "Activar los servicios de localización para utilizar Soundscape"; +"general.error.location_services" = "Activar Localización para usar Soundscape"; /* */ -"general.error.precise_location" = "Activar la ubicación precisa para utilizar Soundscape"; +"general.error.precise_location" = "Activar Ubicación exacta para usar Soundscape"; /* */ -"general.error.location_services.authorize.title" = "Permitir servicios de localización"; +"general.error.location_services.authorize.title" = "Autorizar Localización"; /* */ -"general.error.location_services.authorize.description" = "Soundscape usa tu ubicación para encontrar e informarte sobre los lugares y cosas que te rodean. La aplicación debe tener tu permiso para utilizar los servicios de localización."; +"general.error.location_services.authorize.description" = "Soundscape usa tu ubicación para encontrar e informarte sobre los lugares y cosas de tu entorno. La aplicación necesita tu permiso para usar la localización."; /* */ @@ -255,23 +255,23 @@ /* */ -"general.error.location_services_resume" = "Abre Soundscape para reanudar servicios de localización"; +"general.error.location_services_resume" = "Abre Soundscape para reanudar la localización"; /* */ -"general.error.location_services_enable" = "Activar servicios de localización"; +"general.error.location_services_enable" = "Habilitar Localización"; /* */ -"general.error.location_services_enable_description" = "Los servicios de localización están desactivados actualmente. Soundscape no puede funcionar cuando Localización está desactivada."; +"general.error.location_services_enable_description" = "La localización está deshabilitada actualmente. Soundscape no puede funcionar cuando la localización está desactivada."; /* */ -"general.error.location_services_enable_instructions.2" = "Activa los servicios de localización en la aplicación Ajustes para continuar.\n\n1. Presiona el botón Atrás (en Ajustes)\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización \n4. Activa Localización"; +"general.error.location_services_enable_instructions.2" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona el botón Atrás (en Ajustes)\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización \n4. Activa Localización"; /* */ -"general.error.location_services_enable_instructions.3" = "Activa los servicios de localización en la aplicación Ajustes para continuar.\n\n1. Presiona Abrir Ajustes\n2. Presiona el botón atrás (con el título Ajustes)\n3. Selecciona Privacidad y seguridad\n4. Selecciona Localización\n5. Activa Localización"; +"general.error.location_services_enable_instructions.3" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona Abrir Ajustes\n2. Presiona el botón atrás (con el título Ajustes)\n3. Selecciona Privacidad y seguridad\n4. Selecciona Localización\n5. Activa Localización"; /* */ @@ -283,7 +283,7 @@ /* */ -"general.error.location_services_find_location_error.try_again" = "Estamos teniendo problemas para encontrar tu ubicación actual. Vuelve a intentarlo más tarde."; +"general.error.location_services_find_location_error.try_again" = "Tenemos problemas para encontrar tu ubicación actual. Vuelve a intentarlo más tarde."; /* */ @@ -327,11 +327,11 @@ /* */ -"device_motion.enable.title" = "Activar el seguimiento de Actividad física"; +"device_motion.enable.title" = "Habilitar el seguimiento de Actividad física"; /* */ -"device_motion.enable.description" = "El seguimiento de Actividad física está desactivado actualmente. Soundscape no puede funcionar cuando el seguimiento de Actividad física está desactivado."; +"device_motion.enable.description" = "El seguimiento de Actividad física está deshabilitado actualmente. Soundscape no puede funcionar cuando el seguimiento de Actividad física está desactivado."; /* */ @@ -359,7 +359,7 @@ /* */ -"settings.clear_cache.alert_message" = "Soundscape almacena datos de mapas para reducir los datos y el consumo de la batería. La eliminación de los datos almacenados requerirá que Soundscape vuelva a cargar los datos."; +"settings.clear_cache.alert_message" = "Soundscape almacena datos de mapas para reducir el uso de datos móviles y el consumo de la batería. La eliminación de los datos almacenados requerirá que Soundscape vuelva a cargar los datos."; /* */ @@ -367,7 +367,7 @@ /* */ -"settings.clear_cache.markers.alert_message" = "Selecciona \"Eliminar\" para eliminar los marcadores, señales y rutas, o \"Mantener\" para eliminar únicamente los datos del mapa.¡ \"Eliminar\" restablecerá la aplicación a su estado original y no se puede deshacer!"; +"settings.clear_cache.markers.alert_message" = "Selecciona \"Eliminar\" para eliminar los marcadores, señales y rutas, o \"Mantener\" para eliminar únicamente los datos del mapa. ¡\"Eliminar\" restablecerá la aplicación a su estado original y no se puede deshacer!"; /* */ @@ -375,11 +375,11 @@ /* */ -"settings.clear_cache.no_service.message" = "Soundscape no puede conectarse a internet. Se requiere una conexión a Internet para borrar los datos del mapa almacenados, para que los datos del mapa puedan actualizarse."; +"settings.clear_cache.no_service.message" = "Soundscape actualmente no puede conectarse a internet. Se requiere una conexión a Internet para borrar los datos del mapa almacenados, para que los datos puedan actualizarse."; /* */ -"settings.telemetry.optout.alert_title" = "Desactivar telemetría"; +"settings.telemetry.optout.alert_title" = "Rechazo de telemetría"; /* */ @@ -483,11 +483,11 @@ /* */ -"settings.audio.mix_with_others.title" = "Activar controles multimedia"; +"settings.audio.mix_with_others.title" = "Habilitar controles multimedia"; /* */ -"settings.audio.mix_with_others.description" = "Usa esta opción para activar el control de Soundscape con los botones de los auriculares y los botones de reproducción multimedia de la pantalla de bloqueo. Ten en cuenta que cuando está activada, no se puede usar Soundscape mientras se reproducen otros medios como podcasts o música."; +"settings.audio.mix_with_others.description" = "Usa esta opción para habilitar el control de Soundscape con los botones de los auriculares y los botones de reproducción multimedia de la pantalla de bloqueo. Ten en cuenta que cuando está activada, no se puede usar Soundscape mientras se reproducen otros medios como podcasts o música."; /* */ @@ -595,11 +595,11 @@ /* */ -"beacon.settings.melodies" = "Activar indicaciones de salida y llegada"; +"beacon.settings.melodies" = "Habilitar indicaciones de salida y llegada"; /* */ -"beacon.settings.explanation" = "Selecciona un estilo de señal que resulte cómodo en los oídos y que se escuche fácilmente al aire libre y en entornos ruidosos. Asegúrate de que puedes determinar con facilidad tu dirección a través de tu dispositivo de escucha preferido (auriculares o altavoz del teléfono)."; +"beacon.settings.explanation" = "Selecciona un estilo de señal que sea cómodo de escuchar y que se oiga fácilmente al aire libre y en entornos ruidosos. Asegúrate de que puedes determinar con facilidad su dirección a través de tu dispositivo de escucha preferido (auriculares o altavoz del teléfono)."; /* */ @@ -611,11 +611,11 @@ /* */ -"troubleshooting.gps_status.explanation.meters" = "Este valor es una estimación de la precisión con la que Soundscape sabe dónde te encuentras. Menos de ±10 metros es una buena distancia. Menos de ±20 metros es una distancia satisfactoria. Todas las distancias que sean superiores serán insuficientes. Los datos de ubicación tienen la máxima precisión cuando el usuario se encuentra en el exterior y no debajo de estructuras."; +"troubleshooting.gps_status.explanation.meters" = "Este valor es una estimación de la precisión con la que Soundscape sabe dónde te encuentras. Menos de ±10 metros es una buena distancia. Menos de ±20 metros es una distancia aceptable. Más de ±20 metros necesita ser recalculado. Los datos de ubicación son más precisos cuando estás afuera y no debajo de ninguna estructura."; /* */ -"troubleshooting.gps_status.explanation.feet" = "Este valor es una estimación de la precisión con la que Soundscape sabe dónde te encuentras. Menos de ±30 pies es una buena distancia. Menos de ±60 pies es una distancia satisfactoria. Todas las distancias que sean superiores serán insuficientes. Los datos de ubicación tienen la máxima precisión cuando el usuario se encuentra en el exterior y no debajo de estructuras."; +"troubleshooting.gps_status.explanation.feet" = "Este valor es una estimación de la precisión con la que Soundscape sabe dónde te encuentras. Menos de ±30 pies es una buena distancia. Menos de ±60 pies es una distancia aceptable. Más de ±60 pies necesita ser recalculado. Los datos de ubicación son más precisos cuando estás afuera y no debajo de ninguna estructura."; /* */ @@ -631,7 +631,7 @@ /* */ -"troubleshooting.check_audio.hint" = "Pulsa dos veces para comprobar el estado de los auriculares que usas con Soundscape."; +"troubleshooting.check_audio.hint" = "Pulsa dos veces para comprobar el estado de los auriculares."; /* */ @@ -647,7 +647,7 @@ /* */ -"troubleshooting.cache.explanation" = "Soundscape descarga datos de mapas conforme camina para poder indicarte los elementos y lugares que tienes a tu alrededor. Si tienes problemas con Soundscape o consume demasiada memoria, puedes borrar los datos de mapas almacenados y Soundscape solo volverá a descargar los datos de mapas que se encuentran cerca de tu ubicación actual."; +"troubleshooting.cache.explanation" = "Soundscape descarga datos de mapas conforme caminas para poder indicarte los elementos y lugares a tu alrededor. Si tienes problemas con Soundscape o consume demasiada memoria, puedes borrar los datos de mapas almacenados y Soundscape solo volverá a descargar los datos de mapas que se encuentran cerca de tu ubicación actual."; /* */ @@ -1027,7 +1027,7 @@ /* */ -"location_detail.action.beacon.hint.disabled" = "El ajuste de una nueva señal de audio está desactivado mientras la guía de ruta está activa."; +"location_detail.action.beacon.hint.disabled" = "Establecer una nueva señal de audio está deshabilitado mientras la guía de ruta está activa."; /* */ @@ -1067,11 +1067,11 @@ /* */ -"location_detail.disabled.save" = "La operación de guardar un marcador en esta ubicación no está actualmente disponible"; +"location_detail.disabled.save" = "Guardar un marcador en esta ubicación no está actualmente disponible"; /* */ -"location_detail.disabled.share" = "La operación de compartir esta ubicación no está actualmente disponible"; +"location_detail.disabled.share" = "Compartir esta ubicación no está actualmente disponible"; /* */ @@ -1255,11 +1255,11 @@ /* */ -"route.end.completed" = "Ruta completada.・%@"; +"route.end.completed" = "¡Ruta completada!・%@"; /* */ -"route.end.completed.accessibility" = "Ruta completada. %@"; +"route.end.completed.accessibility" = "¡Ruta completada! %@"; /* */ @@ -1367,7 +1367,7 @@ /* */ -"route.update.fail.title" = "Error al actualizar"; +"route.update.fail.title" = "Falla de actualizar"; /* */ @@ -1499,7 +1499,7 @@ /* */ -"universal_links.marker.share.message" = "He compartido un marcador de Soundscape contigo. \"%@\""; +"universal_links.marker.share.message" = "¡He compartido un marcador de Soundscape contigo! \"%@\""; /* */ @@ -1543,7 +1543,7 @@ /* */ -"url_resource.alert.route.share.message" = "He compartido una ruta de Soundscape contigo. \"%@\""; +"url_resource.alert.route.share.message" = "¡He compartido una ruta de Soundscape contigo! \"%@\""; /* */ @@ -1607,7 +1607,7 @@ /* */ -"routes.tutorial.details" = "Ahora volverás a la página de inicio de Soundscape y se colocará una señal de audio en tu primer punto de ruta. Cuando llegues al primer punto de ruta, la señal avanzará al siguiente punto de ruta."; +"routes.tutorial.details" = "Ahora volverás a la pantalla de inicio de Soundscape y se colocará una señal de audio en tu primer punto de ruta. Cuando llegues al primer punto de ruta, la señal avanzará al siguiente punto de ruta."; /* */ @@ -1815,7 +1815,7 @@ /* */ -"search.button.current_location.accessibility_hint" = "Pulsa dos veces para previsualizar, marcar o compartir tu ubicación actual con un amigo."; +"search.button.current_location.accessibility_hint" = "Pulsa dos veces para obtener una vista previa, marcar o compartir tu ubicación actual con un amigo."; /* */ @@ -1867,7 +1867,7 @@ /* */ -"filter.not_available" = "Algunos filtros de categoría no están disponibles. Todavía puedes buscar lugares cercanos seleccionando \"%@\"."; +"filter.not_available" = "Algunos filtros de categoría no están disponibles. Todavía puedes examinar lugares cercanos seleccionando \"%@\"."; /* */ @@ -1979,11 +1979,11 @@ /* */ -"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Usa Servicios de localización, pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa en el botón siguiente para reactivar ahora."; +"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Esto usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa en el botón siguiente para reactivar ahora."; /* */ -"sleep.sleeping.message" = "Soundscape se encuentra actualmente en el modo de suspensión. Evita que Soundscape use Servicios de localización o descargue datos y ahorra energía de la batería cuando no se usa Soundscape. Pulsa en el botón siguiente para reactivar Soundscape."; +"sleep.sleeping.message" = "Soundscape se encuentra actualmente en modo de suspensión. Esto evita que Soundscape use Localización o descargue datos. Esto ahorra batería cuando no se usa Soundscape. Pulsa en el botón siguiente para reactivar Soundscape."; /* */ @@ -2083,7 +2083,7 @@ /* */ -"directions.nearest_road_name_is_distance" = "La carretera más cercana, %1$@, está a %2$@ de distancia"; +"directions.nearest_road_name_is_distance" = "Carretera más cercana, %1$@, está a %2$@ de distancia"; /* */ @@ -2570,7 +2570,7 @@ /* */ -"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares de los cuatro cuadrantes que te rodean."; +"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares en los cuatro cuadrantes que te rodean."; /* */ @@ -2578,7 +2578,7 @@ /* */ -"ui.action_button.ahead_of_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares delante de ti."; +"ui.action_button.ahead_of_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares que se encuentran delante."; /* */ @@ -2650,7 +2650,7 @@ /* */ -"poi_screen.loading_title.finding_error" = "Tenemos problemas para encontrar los lugares cercanos. Vuelve a intentarlo más tarde."; +"poi_screen.loading_title.finding_error" = "¡Ay! Tenemos problemas para encontrar los lugares cercanos. Vuelve a intentarlo más tarde."; /* */ @@ -2710,7 +2710,7 @@ /* */ -"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape el lugar frente al cual te encuentras. Esto ayuda a Soundscape a mejorar tu experiencia de audio, lo que hace que tu desplazamiento por el mundo sea más natural.\n\nPulsa en el botón siguiente para conectar un dispositivo."; +"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo.\n\nPulsa en el botón siguiente para conectar un dispositivo."; /* */ @@ -2762,15 +2762,15 @@ /* */ -"devices.connect_headset.calibrate" = "Los auriculares deben estar calibrados. Quítate los de la cabeza, agítalos suavemente en todas direcciones durante unos 10 segundos y colócalos de nuevo sobre tu cabeza. Se debe repetir si el timbre de calibración sigue sonando."; +"devices.connect_headset.calibrate" = "Los auriculares tienen que calibrarse. Quítate los de la cabeza, agítalos suavemente en todas direcciones durante unos 10 segundos y colócalos de nuevo sobre tu cabeza. Se debe repetir si el timbre de calibración sigue sonando."; /* */ -"devices.connect_headset.calibrate.in_ear" = "Los auriculares deben estar calibrados. Agita suavemente la cabeza en todas las direcciones durante unos 10 segundos. Se debe repetir si el timbre de calibración sigue sonando."; +"devices.connect_headset.calibrate.in_ear" = "Los auriculares tienen que calibrarse. Agita suavemente la cabeza en todas las direcciones durante unos 10 segundos. Se debe repetir si el timbre de calibración sigue sonando."; /* */ -"devices.connect_headset.completed.airpods" = "¡Enhorabuena! Tus AirPods están listos para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano. Un solo clic en el botón de los auriculares silenciará o desactivará la señal, un doble clic indicará tu ubicación y un triple clic repetirá la última indicación."; +"devices.connect_headset.completed.airpods" = "¡Enhorabuena! Tus AirPods están listos para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano. Un solo clic en el botón de los auriculares silenciará o desactivará la señal, un doble clic avisará de tu ubicación y un triple clic repetirá el último aviso."; /* */ @@ -2794,7 +2794,7 @@ /* */ -"devices.test_headset.callout" = "Hemos colocado una señal de audio a tu derecha. Escucha dónde se encuentra y gira la cabeza hacia ella… Observa cómo puedes hacer esto incluso con el teléfono en el bolsillo."; +"devices.test_headset.callout" = "Hemos colocado una señal de audio a tu derecha. Escucha dónde se encuentra y gira la cabeza hacia ella. Observa cómo puedes hacer esto incluso con el teléfono en el bolsillo."; /* */ @@ -2850,7 +2850,7 @@ /* */ -"devices.reachability.alert.description" = "Tu %@ puede indicarte a Soundscape frente a qué dirección te encuentras actualmente, y esto ayudará a Soundscape a mejorar tu experiencia de audio. Puedes habilitar el seguimiento de cabezas en los ajustes de Auriculares con seguimiento de cabeza."; +"devices.reachability.alert.description" = "Tu %@ puede indicarle a Soundscape en qué dirección estás mirando, y esto ayudará a Soundscape a mejorar tu experiencia de audio. Puedes activar el seguimiento de cabezas en los ajustes de Auriculares con seguimiento de cabeza."; /* */ @@ -2890,7 +2890,7 @@ /* */ -"behavior.experiences.reset.prompt" = "Al restablecer esta actividad se eliminará tu progreso actual y te permitirá iniciarla de nuevo. Además de restablecerla, también puedes elegir buscar actualizaciones. De esta manera, se descargará información actualizada para esta actividad si hay actualizaciones disponibles."; +"behavior.experiences.reset.prompt" = "Al restablecer esta actividad se eliminará tu progreso actual y te permitirá iniciarla de nuevo. También puedes buscar actualizaciones. De esta manera, se descargará información actualizada para esta actividad si hay actualizaciones disponibles."; /* */ @@ -3118,11 +3118,11 @@ /* */ -"tutorial.markers.text.EditMarker" = "Excelente. Has seleccionado @!marker_name!! como marcador. Oirás como lo avisa Soundscape cuando pases cerca.\nEn la siguiente pantalla, puedes cambiar su nombre si lo deseas."; +"tutorial.markers.text.EditMarker" = "¡Excelente! Has seleccionado @!marker_name!! como marcador. Oirás como lo avisa Soundscape cuando pases cerca.\nEn la siguiente pantalla, puedes cambiar su nombre si lo deseas."; /* */ -"tutorial.markers.text.NearbyMarkers" = "Excelente. Tienes un nuevo marcador llamado @!marker_name!!.\nAhora, para oír dónde está tu marcador, presiona el botón Marcadores cercanos. Este botón se encuentra en la parte inferior de la pantalla principal.\nPruébalo ahora."; +"tutorial.markers.text.NearbyMarkers" = "¡Excelente! Tienes un nuevo marcador llamado @!marker_name!!.\nAhora, para oír dónde está tu marcador, presiona el botón Marcadores cercanos. Este botón se encuentra en la parte inferior de la pantalla principal.\nPruébalo ahora."; /* */ @@ -3130,7 +3130,7 @@ /* */ -"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás frente a tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará y volverás a la pantalla anterior."; +"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará y volverás a la pantalla anterior."; /* */ @@ -3202,7 +3202,7 @@ /* */ -"tutorial.beacons.text.HoldingPhone.great" = "Mantener el teléfono en posición horizontal de esta manera solo es necesario cuando no te mueves. Mientras camines, puedes colocar el teléfono en un bolso o un bolsillo al que puedas tener fácil acceso."; +"tutorial.beacons.text.HoldingPhone.great" = "¡Excelente! Mantener el teléfono en posición horizontal de esta manera solo es necesario cuando no te mueves. Mientras camines, puedes colocar el teléfono en un bolso o un bolsillo al que puedas tener fácil acceso."; /* */ @@ -3214,23 +3214,23 @@ /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Ahora, manteniendo todavía el teléfono en posición horizontal, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estés orientado directamente hacia ella."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Ahora, manteniendo todavía el teléfono en posición horizontal, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estás mirando directamente en su dirección."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Ahora, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando te encuentres directamente frente a ella."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Ahora, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estás mirando directamente en su dirección."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRepeat" = "Gira lentamente hasta que oigas el timbre que indica que está orientado en la dirección de la señal."; +"tutorial.beacons.text.BeaconOutOfBoundsRepeat" = "Gira lentamente hasta que oigas el timbre que indica que estás mirando en la dirección de la señal."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsConfirmation" = "¡Perfecto, ahora estás orientado en la dirección de @!destination!!."; +"tutorial.beacons.text.BeaconOutOfBoundsConfirmation" = "Perfecto, ahora estás mirando en dirección a @!destination!!."; /* */ -"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido de señal normal. Eso significa que te encuentras orientado directamente hacia @!destination!!."; +"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido normal de la señal. Eso significa que estás mirando directamente hacia @!destination!!."; /* */ @@ -3238,7 +3238,7 @@ /* */ -"tutorial.beacons.text.BeaconInBoundsRotate.ar_headset" = "Ahora intenta alejarte lentamente de la dirección de la señal. El sonido de la campana se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; +"tutorial.beacons.text.BeaconInBoundsRotate.ar_headset" = "Ahora intenta alejarte lentamente de la dirección de la señal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; /* */ @@ -3246,11 +3246,11 @@ /* */ -"tutorial.beacons.text.MobilitySkills" = "La señal siempre señala directamente hacia la ubicación que has seleccionado. No te indica las rutas que debes seguir ni le proporciona indicaciones para llegar a esa ubicación. Usa esta señal como herramienta para decidir cómo deseas llegar allí."; +"tutorial.beacons.text.MobilitySkills" = "La señal siempre apunta directamente hacia la ubicación que has seleccionado. No te indica las rutas que debes seguir ni te proporciona indicaciones para llegar a esa ubicación. Usa esta señal como herramienta para decidir cómo deseas llegar allí."; /* */ -"tutorial.beacons.text.AutomaticCallout" = "A medida que avances en su viaje, Soundscape te informará ocasionalmente de la distancia hasta el lugar marcado por la señal con un aviso como éste."; +"tutorial.beacons.text.AutomaticCallout" = "A medida que avances en tu viaje, Soundscape te informará ocasionalmente de la distancia hasta el lugar marcado por la señal con un aviso como éste."; /* */ @@ -3266,7 +3266,7 @@ /* */ -"tutorial.beacons.text.WrapUp" = "Parece que lo entiendes. Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que ha establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.beacons.text.WrapUp" = "¡Parece que lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que ha establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3342,7 +3342,7 @@ /* */ -"help.tutorial.footer.disabled" = "Los tutoriales están deshabilitados mientras la guía de la ruta esté activa"; +"help.tutorial.footer.disabled" = "Los tutoriales están deshabilitados mientras la guía de la ruta está activa"; /* */ @@ -3434,15 +3434,15 @@ /* */ -"first_launch.soundscape_language.text" = "Selecciona el idioma que deseas usar en Soundscape. Siempre podrás cambiar tu elección en los ajustes de la aplicación."; +"first_launch.soundscape_language.text" = "Selecciona el idioma que deseas usar en Soundscape. Siempre puedes cambiar tu selección en los ajustes de la aplicación."; /* */ -"first_launch.location.text" = "Soundscape es una aplicación basada en la ubicación. Utilizamos tu ubicación para encontrar y avisar de las cosas que te rodean."; +"first_launch.location.text" = "Soundscape es una aplicación basada en la ubicación. Utilizamos tu ubicación para encontrar y avisar de las cosas de tu entorno."; /* */ -"first_launch.location.enable_location" = "Habilitar ubicación"; +"first_launch.location.enable_location" = "Habilitar localización"; /* */ @@ -3450,7 +3450,7 @@ /* */ -"first_launch.device_motion.text" = "Esto le permite a Soundscape mejorar tu experiencia en función de si va a pie, se desplaza en un vehículo o no se mueve."; +"first_launch.device_motion.text" = "Esto permite a Soundscape mejorar tu experiencia en función de si caminas, te desplazas en un vehículo o permaneces quieto."; /* */ @@ -3458,7 +3458,7 @@ /* */ -"first_launch.lighting_way_with_sound.text_alt" = "Soundscape usa sonido 3D para indicarte qué hay a tu alrededor. Por ejemplo, si tu destino está a tu derecha, oirás un sonido procedente de esa dirección, o si hay una cafetería a tu izquierda, oirás un aviso procedente de esa dirección."; +"first_launch.lighting_way_with_sound.text_alt" = "Soundscape usa sonido 3D para informarte de lo que hay a tu alrededor. Por ejemplo, si tu destino está a tu derecha, oirás un sonido procedente de esa dirección, o si hay una cafetería a tu izquierda, oirás un aviso procedente de esa dirección."; /* */ @@ -3466,7 +3466,7 @@ /* */ -"first_launch.heading_somewhere.text" = "Coloca una señal de audio en el destino y Soundscape te mantendrá informado de tu ubicación y tu entorno en el trayecto. Usa Soundscape junto con tus habilidades de orientación e incluso tu aplicación de navegación favorita para encontrar el camino a tu destino."; +"first_launch.heading_somewhere.text" = "Coloca una señal de audio en el destino y Soundscape te mantendrá informado de su ubicación y tu entorno en el trayecto. Usa Soundscape junto con tus habilidades de orientación e incluso tu aplicación de navegación favorita para encontrar el camino a tu destino."; /* */ @@ -3510,7 +3510,7 @@ /* */ -"first_launch.headphones.message.2" = "Si no tienes auriculares o prefieres no usarlos, Soundscape seguirá funcionando con los altavoces del teléfono."; +"first_launch.headphones.message.2" = "Si no tienes auriculares o prefieres no usarlos, no te preocupes. Soundscape seguirá funcionando con los altavoces del teléfono."; /* */ @@ -3518,7 +3518,7 @@ /* */ -"first_launch.callouts.message" = "Soundscape te ayuda a saber dónde te encuentras y hacia dónde vas avisando de carreteras, cruces y puntos de interés a medida que te acerques a ellos."; +"first_launch.callouts.message" = "Soundscape te ayuda a estar informado de dónde te encuentras y hacia dónde vas avisando de carreteras, cruces y puntos de interés a medida que te acerques a ellos."; /* */ @@ -3554,7 +3554,7 @@ /* */ -"first_launch.permissions.location" = "Servicios de localización con Ubicación exacta"; +"first_launch.permissions.location" = "Localización con Ubicación exacta"; /* */ @@ -3634,27 +3634,27 @@ /* */ -"help.text.destination_beacons.what" = "Establecer una señal en una ubicación cercana permite a Soundscape mantenerte informado reproduciendo un sonido procedente de la dirección de esa ubicación. Esta señal se puede silenciar o reactivar en la pantalla principal. Además, Soundscape muestra información sobre la ubicación de la pantalla principal incluyendo la distancia hasta ella y la dirección si se conoce."; +"help.text.destination_beacons.what" = "Establecer una señal en una ubicación cercana permite a Soundscape mantenerte informado reproduciendo un sonido procedente de la dirección de esa ubicación. Esta señal se puede silenciar o reactivar en la pantalla principal. Además, Soundscape muestra información sobre la ubicación en la pantalla principal incluyendo la distancia hasta ella y la dirección si se conoce."; /* */ -"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia familiar cuando exploras una zona nueva o cuando vas a algún lugar y deseas estar informado de tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar en que te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes, e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas a ti."; +"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia conocido mientras exploras una zona nueva o cuando vas a algún lugar y deseas estar informado de tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar donde te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes, e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas."; /* */ -"help.text.destination_beacons.how.1" = "Para establecer una señal:
Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o tocando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. En la pantalla \"Detalles de la Ubicación\" puedes seleccionar el botón \"Iniciar Señal de Audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, ahora se mostrará en la pantalla principal."; +"help.text.destination_beacons.how.1" = "Para establecer una señal:
Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando en uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la Ubicación\", selecciona el botón \"Iniciar Señal de Audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerán ahora en la pantalla principal."; /* */ -"help.text.destination_beacons.how.2" = "Para quitar la señal actual:
solo tienes que presionar el botón \"Quitar señal\" de la pantalla principal."; +"help.text.destination_beacons.how.2" = "Para quitar la señal actual:
solo tienes que presionar el botón \"Quitar señal\" en la pantalla principal."; /* */ -"help.text.destination_beacons.how.3" = "Para silenciar la señal de audio:
pulsa el botón \"Silenciar señal\" que se encuentra debajo del botón \"Quitar señal\" de la pantalla principal."; +"help.text.destination_beacons.how.3" = "Para silenciar la señal de audio:
pulsa el botón \"Silenciar señal\" debajo del botón \"Quitar señal\" en la pantalla principal."; /* */ -"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos que tienes a tu alrededor conforme te acercas ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobuses e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\" y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; +"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos que se encuentran a tu alrededor conforme te acercas a ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobús e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\" y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; /* */ @@ -3670,23 +3670,23 @@ /* */ -"help.text.automatic_callouts.how.1" = "Activar o desactivar los avisos:
Al desactivar los avisos, se silenciará la aplicación. Los avisos se pueden activar o desactivar en la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", donde puedes tocar el botón \"Permitir Avisos\" para activarlos o desactivarlos. También puedes activar o desactivar los avisos mediante el comando \"saltar hacia adelante\" (toca dos veces y mantén presionado) si tus auriculares tienen botones de control de medios. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio para evitar que Soundscape haga avisos hasta que lo reactives."; +"help.text.automatic_callouts.how.1" = "Activación o desactivación de avisos:
Al desactivar los avisos, se silenciará la aplicación. Los avisos se pueden activar o desactivar yendo a la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", y, a continuación, pulsando en el botón \"Permitir Avisos\". También puedes activar o desactivar los avisos con el comando \"saltar adelante\" (pulsa dos veces y mantén pulsado) si tus auriculares tienen botones de control multimedia. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla principal para evitar que Soundscape haga avisos hasta que lo reactives."; /* */ -"help.text.automatic_callouts.how.2" = "Administrar los avisos que oyes:
Para elegir los tipos de cosas que Soundscape llamará automáticamente, ve a la pantalla \"Ajustes\" desde el menú principal. La sección \"Administrar Avisos\" de la pantalla \"Ajustes\" contiene una lista de tipos de cosas que la app puede llamar. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, toca el botón \"Permitir Avisos\" en la parte superior de la lista."; +"help.text.automatic_callouts.how.2" = "Administración de los avisos que oyes:
Para elegir los tipos de elementos de los que Soundscape avisará automáticamente, ve a la pantalla \"Ajustes\" desde el menú principal. La sección \"Administrar Avisos\" de la pantalla \"Ajustes\" contiene una lista de tipos de elementos de los que puede avisar la aplicación. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, pulsa en el botón \"Permitir Avisos\" en la parte superior de la lista."; /* */ -"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección hacia la que estás orientado, dónde se encuentran cruces o carreteras cercanas, y dónde hay puntos de interés cercanos."; +"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección en la que estás mirando, dónde se encuentran cruces o carreteras cercanas, y dónde hay puntos de interés cercanos."; /* */ -"help.text.my_location.when" = "\"Mi ubicación\" es útil cuando necesitas averiguar dónde te encuentras o hacia qué dirección cardinal estás orientado."; +"help.text.my_location.when" = "\"Mi ubicación\" es útil cuando necesitas averiguar dónde te encuentras o hacia qué dirección cardinal estás mirando."; /* */ -"help.text.my_location.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección hacia la que estás orientado antes de presionar el botón \"Mi ubicación\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Mi ubicación\" y escuchar."; +"help.text.my_location.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Mi ubicación\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Mi ubicación\" y escuchar."; /* */ @@ -3698,23 +3698,23 @@ /* */ -"help.text.nearby_markers.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección hacia la que estás orientado antes de presionar el botón \"Marcadores cercanos\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Marcadores cercanos\" y escuchar hasta cuatro marcadores cerca de ti."; +"help.text.nearby_markers.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Marcadores cercanos\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Marcadores cercanos\" y escuchar hasta cuatro marcadores cerca de ti."; /* */ -"help.text.around_me.what" = "El botón \"Alrededor de mí\" te informa sobre una cosa en cada uno de los cuatro cuadrantes que te rodean (adelante, a la derecha, detrás y a la izquierda). \"Alrededor de mí\" tiene la intención de ayudarte a orientarte en tu entorno."; +"help.text.around_me.what" = "El botón \"Alrededor de mí\" te informa sobre una cosa en cada uno de los cuatro cuadrantes que se encuentran a tu alrededor (adelante, a la derecha, detrás y a la izquierda). \"Alrededor de mí\" tiene la intención de ayudarte a orientarte en tu entorno."; /* */ -"help.text.around_me.when" = "Cuando intentes orientarte en tu entorno, usa \"Alrededor de mí\" para escuchar sobre las cosas que te rodean."; +"help.text.around_me.when" = "Cuando intentes orientarte en tu entorno, usa \"Alrededor de mí\" para escuchar sobre las cosas que hay a tu alrededor."; /* */ -"help.text.around_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección hacia la que estás orientado antes de presionar el botón \"Alrededor de mí\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Alrededor de mí\" y oirás los cuatro puntos de interés situados a tu alrededor."; +"help.text.around_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Alrededor de mí\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Alrededor de mí\" y oirás cuatro puntos de interés situados a tu alrededor."; /* */ -"help.text.ahead_of_me.what" = "El botón \"Delante de mí\" te indica qué se encuentra delante de ti. \"Delante de mí\" está pensado para explorar lo que se encuentra delante de ti cuando estás conociendo una zona nueva."; +"help.text.ahead_of_me.what" = "El botón \"Delante de mí\" te informa de hasta cinco elementos que se encuentran delante de ti. \"Delante de mí\" está pensado para explorar el camino por delante de ti cuando estás conociendo una zona nueva."; /* */ @@ -3722,11 +3722,11 @@ /* */ -"help.text.ahead_of_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección hacia la que estás orientado antes de presionar el botón \"Delante de mí\". Esto actúa como brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Delante de mí\" y oirás varios puntos de interés que estén más o menos delante de ti."; +"help.text.ahead_of_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Delante de mí\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Delante de mí\" y oirás varios puntos de interés que estén más o menos delante de ti."; /* */ -"help.text.remote_control.what" = "Puedes obtener acceso a determinadas características de Soundscape con la ayuda de los botones de control multimedia de sus auriculares. Esta funcionalidad funciona con auriculares Bluetooth o por cable que tenga botones de control multimedia, como Reproducir, Pausa, Siguiente, Anterior y otros. Distintos modelos de auriculares con micrófono pueden incluir diferentes botones; consulta la lista de acciones a continuación para determinar cuáles están disponibles para ti.
Ten en cuenta que esta característica solo funciona con auriculares con micrófono que admitan controles multimedia de Apple (como reproducir y pausa)."; +"help.text.remote_control.what" = "Puedes obtener acceso a determinadas características de Soundscape con los botones de control multimedia de tus auriculares. Esta funcionalidad funciona con auriculares Bluetooth o por cable que tengan botones de control multimedia, como Reproducir, Pausa, Siguiente, Anterior y otros. Distintos modelos de auriculares con micrófono pueden incluir diferentes botones; consulta la lista de acciones a continuación para determinar cuáles están disponibles para ti.
Ten en cuenta que esta característica solo funciona con auriculares con micrófono que admitan controles multimedia de Apple (como reproducir y pausa)."; /* */ @@ -3734,7 +3734,7 @@ /* */ -"help.text.remote_control.how" = "

Puedes acceder a las siguientes funciones de Soundscape utilizando los botones de control multimedia de los auriculares:


⏯ Reproducir/Pausar: Silencie los avisos actuales y, si la señal de audio está establecida, active o desactive el audio.

⏭ siguiente: Llame \"Mi ubicación\".

⏮ Anterior: Repita el último aviso.

⏩ Saltar hacia adelante: Activa y desactiva los avisos.

⏪ Saltar hacia atrás: Gritar \"Alrededor de mí\".

"; +"help.text.remote_control.how" = "

Puedes obtener acceso a las siguientes funciones de Soundscape con los botones de control multimedia de los auriculares:


⏯ Reproducir/Pausa: Silenciar los avisos actuales y, si la señal de audio está establecida, activar o desactivar el audio.

⏭ Siguiente: Aviso \"Mi ubicación\".

⏮ Anterior: Repetir el último aviso.

⏩ Saltar adelante: Activar y desactivar los avisos.

⏪ Saltar atrás: Aviso \"Alrededor de mí\".

"; /* */ @@ -3742,7 +3742,7 @@ /* */ -"help.text.markers.content.2" = "Puedes marcar las cosas que son personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Puedes marcar cualquier lugar o dirección, pero también cosas que podrían no estar disponible tradicionalmente en mapas, por ejemplos, entradas a edificios o parques, lugares con pulsador para cruzar la calle, pasos de peatones o puentes, paradas de autobús o incluso el árbol favorito de tu perro y usarlos como referencia durante tu paseo."; +"help.text.markers.content.2" = "Puedes marcar las cosas que son personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Puedes marcar cualquier lugar o dirección, pero también cosas que normalmente no aparecen en los mapas, por ejemplo, entradas a edificios o parques, lugares con pulsador para cruzar la calle, pasos de peatones o puentes, paradas de autobús o incluso el árbol favorito de tu perro y usarlos como referencia durante tu paseo."; /* */ @@ -3750,15 +3750,15 @@ /* */ -"help.text.creating_markers.content.1" = "Puedes crear marcadores de tres formas: buscando el lugar que te gustaría guardar mediante la barra de búsqueda, encontrando algún lugar mediante el botón \"Lugares cercanos\" o utilizando el botón \"Ubicación actual\", todos ellos en la pantalla de inicio de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo accederás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; +"help.text.creating_markers.content.1" = "Puedes crear marcadores de tres formas: buscando el lugar que deseas guardar con la barra de búsqueda, encontrando algún lugar mediante el botón \"Lugares cercanos\" o usando el botón \"Ubicación actual\", todos ellos en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; /* */ -"help.text.creating_markers.content.2" = "Tendrás la opción de personalizar este marcador. Este paso es opcional. Si lo deseas, puedes cambiar el nombre del marcador y también agregar una anotación que se oirá con el marcador para proporcionar información adicional. Una vez que hayas acabado, selecciona el botón \"Listo\" para guardar el marcador."; +"help.text.creating_markers.content.2" = "Tendrás la opción de personalizar este marcador. Puedes cambiar su nombre y también agregar una anotación que se oirá con el marcador para proporcionar información adicional. A continuación, selecciona el botón \"Listo\" para guardar el marcador."; /* */ -"help.text.customizing_markers.content.1" = "Si deseas cambiar el nombre de un marcador que has creado anteriormente, o agregarle una anotación, puedes hacerlo seleccionando el marcador en la pestaña \"Marcadores\" de la página \"Marcadores y rutas\" y, a continuación, \"Editar marcador\" . Puedes usarlo para asignar a los marcadores sobrenombres útiles o descriptivos, así como para proporcionarles una descripción más larga con el campo de anotación."; +"help.text.customizing_markers.content.1" = "Si deseas cambiar el nombre de un marcador que has creado anteriormente, o agregarle una anotación, selecciona el marcador en la pestaña \"Marcadores\" de la página \"Marcadores y rutas\" y, a continuación, \"Editar marcador\" . Puedes usarlo para asignar a los marcadores sobrenombres útiles o descriptivos, así como para proporcionarles una descripción más larga con el campo de anotación."; /* */ @@ -3766,7 +3766,7 @@ /* */ -"help.text.routes.content.what" = "Las rutas son una serie de puntos de ruta. Se te informará a la llegada a cada uno de ellos y la señal de audio avanzará automáticamente hasta el siguiente."; +"help.text.routes.content.what" = "Las rutas son una serie de puntos de referencia. Se te informará a la llegada a cada uno de ellos y la señal de audio avanzará automáticamente hasta el siguiente."; /* */ @@ -3786,7 +3786,7 @@ /* */ -"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza cuando se utilizan AirPods compatibles. Cuando se conecten, los sensores de los AirPods indican a Soundscape la dirección frente a la cual te encuentras. Esto ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que Soundscape funcione bien."; +"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que Soundscape funcione bien."; /* */ @@ -3798,7 +3798,7 @@ /* */ -"help.using_headsets.airpods.how.2" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén activados en la configuración de Soundscape, podrás usarlos en los AirPods para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; +"help.using_headsets.airpods.how.2" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén habilitados en la configuración de Soundscape, podrás usarlos en los AirPods para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; /* */ @@ -4110,7 +4110,7 @@ /* */ -"voice.apple.additional" = "Se pueden descargar voces adicionales, incluidas las de calidad mejorada, en la sección Contenido leído de la configuración de accesibilidad de iOS."; +"voice.apple.additional" = "Se pueden descargar voces adicionales, incluidas las de calidad mejorada, en la sección Contenido leído de los ajustes de accesibilidad de iOS."; /* */ @@ -4142,7 +4142,7 @@ /* */ -"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares descubiertos por la aplicación o lugares totalmente nuevos que hayas añadido tú mismo. Puedes guardar tu ubicación actual como marcador seleccionando el botón \"Ubicación actual\" en la pantalla de inicio y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que te gustaría guardar utilizando la barra de búsqueda, o encontrando algún lugar utilizando el botón \"Lugares cercanos\", ambos en la pantalla de inicio de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo accederás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; +"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares descubiertos por la aplicación o lugares totalmente nuevos que hayas añadido tú mismo. Puedes guardar tu ubicación actual como marcador seleccionando el botón \"Ubicación actual\" en la pantalla principal y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que deseas guardar con la barra de búsqueda, o encontrando algún lugar mediante el botón \"Lugares cercanos\", ambos en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; /* */ @@ -4154,7 +4154,7 @@ /* */ -"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como baliza. Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o tocando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. En la pantalla ddetalles de la ubicación puedes seleccionar el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, ahora se mostrará en la pantalla principal."; +"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como baliza. Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando en uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerá ahora en la pantalla principal."; /* */ @@ -4170,7 +4170,7 @@ /* */ -"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección hacia la que estás orientado. Cuando Soundscape no está seguro de hacia qué dirección estás orientado, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apunta en la dirección hacia la que estás orientado."; +"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección en la que estás mirando. Cuando Soundscape no está seguro de hacia donde estás mirando, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apunta en dirección contraria a ti."; /* */ @@ -4194,7 +4194,7 @@ /* */ -"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, oirás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar cuándo se apaga la señal yendo a \"Señal de audio\" en la pantalla \"Ajustes\" y moviendo el control deslizante \"Distancia de Silenciar el audio\" hacia arriba o hacia abajo."; +"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, oirás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar cuándo se silencia la señal yendo a \"Señal de audio\" en la pantalla \"Ajustes\" y moviendo el control deslizante \"Distancia de Silenciar el audio\" hacia arriba o hacia abajo."; /* */ @@ -4230,11 +4230,11 @@ /* */ -"faq.miss_a_callout.question" = "¿Qué ocurre si no comprendo un aviso o si no lo oigo por el ruido?"; +"faq.miss_a_callout.question" = "¿Qué ocurre si no entiendo un aviso o si no lo oigo por el ruido?"; /* */ -"faq.miss_a_callout.answer" = "Soundscape tiene una lista de tus avisoss recientes para que puedas volver a visitar los avisos que te hayas perdido. Para ello, pulsa en la barra de búsqueda de la pantalla de inicio de Soundscape. En la parte inferior de esta página, hay una sección de \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar el teléfono para repetir el último aviso. En la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", activa la opción \"Repetir Avisos\"."; +"faq.miss_a_callout.answer" = "Soundscape tiene una lista de tus avisoss recientes para que puedas volver a visitar los avisos que te hayas perdido. Para ello, pulsa en la barra de búsqueda de la pantalla principal de Soundscape. En la parte inferior de esta página, hay una sección de \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar el teléfono para repetir el último aviso. En la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", activa la opción \"Repetir Avisos\"."; /* */ @@ -4254,7 +4254,7 @@ /* */ -"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal y cada opción tiene sus ventajas e inconvenientes. El requisito específico es usar auriculares estéreos para beneficiarte de los avisos acústicos espaciales 3D de Soundscape."; +"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal y cada opción tiene sus ventajas y desventajas. El único requisito es usar auriculares estéreos para beneficiarte de los avisos acústicos espaciales 3D de Soundscape."; /* */ @@ -4262,15 +4262,15 @@ /* */ -"faq.battery_impact.answer" = "La duración de la batería varía en gran medida en función del iPhone que tengas y de su antigüedad. El mayor consumo de la batería se produce al tener la pantalla encendida, por lo que para maximizar su duración, debes mantener la pantalla bloqueada siempre que sea posible. Para ayudar a minimizar el impacto en la batería de iPhone, Soundscape ahora tiene un modo de reposo y un modo de aplazamiento. Para reducir aún más el uso de la batería, cuando no uses Soundscape, debes forzar cerrar la aplicación con el Selector de aplicación de iPhone."; +"faq.battery_impact.answer" = "La duración de la batería varía en gran medida en función del modelo y la antigüedad de tu iPhone. El mayor consumo de la batería se produce al tener la pantalla encendida, por lo que para maximizar su duración, debes mantener la pantalla bloqueada siempre que sea posible. Para ayudar a minimizar el impacto en la batería de iPhone, Soundscape tiene un modo de suspensión y un modo de aplazamiento. Para reducir aún más el uso de la batería, cuando no uses Soundscape, debes forzar cerrar la aplicación con el Selector de app de iPhone."; /* */ -"faq.sleep_mode_battery.question" = "¿Cómo uso el modo de reposo para minimizar el impacto de Soundscape en la batería del teléfono?"; +"faq.sleep_mode_battery.question" = "¿Cómo uso el modo de suspensión para minimizar el impacto de Soundscape en la batería del teléfono?"; /* */ -"faq.sleep_mode_battery.answer" = "Para poner Soundscape en el modo de reposo, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando lo selecciones, Soundscape dejará de utilizar los servicios de localización y los datos móviles hasta que lo reactives."; +"faq.sleep_mode_battery.answer" = "Para poner Soundscape en el modo de suspensión, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando lo selecciones, Soundscape dejará de usar la localización y los datos móviles hasta que lo reactives."; /* */ @@ -4278,7 +4278,7 @@ /* */ -"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape esté en el modo de reposo, selecciona el botón \"Reactivar cuando Salga\" y Soundscape pasará a un estado de bajo consumo hasta que te vayas de la ubicación actual."; +"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape esté en el modo de suspensión, selecciona el botón \"Reactivar cuando Salga\" y Soundscape entrará en un estado de bajo consumo hasta que te vayas de la ubicación actual."; /* */ @@ -4294,7 +4294,7 @@ /* */ -"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar tu ubicación. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupas el consumo de la batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa servicios de localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; +"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar dónde te encuentras. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupas el consumo de la batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa la localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; /* */ @@ -4318,7 +4318,7 @@ /* */ -"faq.use_with_wayfinding_apps.answer" = "Soundscape se ha diseñado para ayudar a completar la información de tu entorno que es posible que no conozcas de otra manera. Aunque no se ha diseñado como una aplicación de navegación paso a paso, se puede usar junto con esas aplicaciones para proporcionar información complementaria. Para usar Soundscape con estas aplicaciones, inicia tu aplicación de navegación primero. A continuación, pasa a Soundscape y establece una señal en el mismo destino que la aplicación de navegación. En este punto, ambas aplicaciones se estarán ejecutando y oirás indicaciones de ruta a pie de tu aplicación de navegación, a la vez que recibirás de Soundscape actualizaciones sobre puntos de interés, cruces y la distancia a la que se encuentras de tu destino."; +"faq.use_with_wayfinding_apps.answer" = "Soundscape se ha diseñado para ayudar a completar la información de tu entorno que es posible que no conozcas de otra manera. Aunque no se ha diseñado como una aplicación de navegación paso a paso, se puede usar junto con esas aplicaciones para proporcionar información complementaria. Para usar Soundscape con estas aplicaciones, inicia tu aplicación de navegación primero. A continuación, pasa a Soundscape y establece una señal en el mismo destino que la aplicación de navegación. En este punto, ambas aplicaciones se estarán ejecutando y oirás indicaciones de ruta a pie de tu aplicación de navegación, a la vez que recibirás de Soundscape actualizaciones sobre puntos de interés, cruces y la distancia a la que te encuentras de tu destino."; /* */ @@ -4326,7 +4326,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias formas de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: Toca dos veces la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente cuando te acerques al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla de inicio para reanudar la audición de la señal.\n2. Detener los avisos automáticos: Cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga avisándote de las cosas que te rodean. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará de nuevo cuando salgas, o puedes poner Soundscape en el modo de reposo y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y elegir desactivar todos los avisos en la sección \"Administrar Avisos\".\n3. Detener la señal: Hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras recibir actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla de inicio."; +"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias formas de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: Pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente cuando te acerques al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: Cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar Avisos\".\n3. Detener la señal: Hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras recibir actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; /* */ @@ -4334,7 +4334,7 @@ /* */ -"faq.holding_phone_flat.answer" = "¡No, no! Mientras caminas puedes guardar el teléfono en una bolsa o bolsillo o donde sea conveniente. El paisaje sonoro usará la dirección que estás caminando para averiguar qué avisos anunciar a tu izquierda y a tu derecha. Cuando dejas de moverte, Soundscape no sabe hacia qué dirección te diriges. Si la señal de audio está activada, notarás que se calla hasta que comiences a moverte de nuevo. Puedes sacar el teléfono para tocar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla de inicio en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando hacia la dirección en la que estás mirando y con la pantalla hacia el cielo. En esta posición \"plana\", Soundscape utilizará la brújula del teléfono para determinar hacia qué dirección te estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también te darás cuenta de que vuelve a todo su volumen."; +"faq.holding_phone_flat.answer" = "¡No, no! Mientras caminas puedes guardar el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que estás caminando para averiguar qué avisos anunciar a tu izquierda y a tu derecha. Cuando dejas de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; /* */ @@ -4342,7 +4342,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes mientras caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape , así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes Generales\", selecciona Voz para ajustar la velocidad de habla y la configuración de voz . Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en la aplicación Ajustes de iOS en Ajustes > Accesibilidad > Contenido leído > Voces.\n2. Distancia métrica: Soundscape te permite escuchar todas las distancias en pies o metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes Generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre dos opciones: Imperial (pies) y Métrico (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu supermercado preferido. Luego, Soundscape te indicará automáticamente los lugares marcados a medida que pases por ellos o te acerques a ellos, o también puedes usar el botón Marcadores cercanos en la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Estos marcadores seguirán siendo personales para ti y no estarán disponibles para nadie más.\n\nAdemás de lo anterior, las siguientes configuraciones de VoiceOver pueden influir en el comportamiento de Soundscape :\n\n1. Sugerencias de VoiceOver: cuando las sugerencias de VoiceOver están activadas, escucharás más información sobre todos los botones en la pantalla principal de Soundscape . Puedes activar las sugerencias de VoiceOver navegando a la aplicación Ajustes de iOS y yendo a Accesibilidad > VoiceOver > Verbosidad, y activando la configuración Leer indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, los avisos automáticos pueden resultar difíciles de oír si se utiliza VoiceOver simultáneamente. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos que se producen mientras interactúas con el teléfono. La atenuación de audio se puede desactivar en la configuración de VoiceOver o a través del rotor de VoiceOver.\n3. Desbloqueo con Touch ID o Face ID: configurar el teléfono para que se desbloquee con Touch ID o Face ID hará que desbloquear el teléfono sea rápido y fácil y, a su vez, te permitirá acceder a los botones Mi ubicación , Alrededor de mí y Delante de mí lo más rápido posible cuando estés en movimiento. Configura el desbloqueo con Touch ID o Face ID en la aplicación Configuración de iOS ."; +"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape , así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes Generales\", selecciona Voz para ajustar la velocidad de habla y la configuración de voz . Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en la aplicación Ajustes de iOS en Ajustes > Accesibilidad > Contenido leído > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar todas las distancias en pies o metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes Generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre dos opciones: Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados al pasar o acercarte a ellos, o también puedes usar el botón Marcadores cercanos en la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Estos marcadores seguirán siendo personales para ti y no estarán disponibles para nadie más.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver están activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver navegando a la aplicación Ajustes de iOS y yendo a Accesibilidad > VoiceOver > Verbosidad, y activando la configuración Leer indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, los avisos automáticos pueden resultar difíciles de oír si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los avisos de VoiceOver o a través del rotor de VoiceOver.\n3. Desbloqueo con Touch ID o Face ID: configurar el teléfono para que se desbloquee con Touch ID o Face ID hará que desbloquear el teléfono sea rápido y fácil y, a su vez, te permitirá acceder a los botones Mi ubicación , Alrededor de mí y Delante de mí lo más rápido posible cuando estés en movimiento. Configura el desbloqueo con Touch ID o Face ID en la aplicación Ajustes de iOS ."; /* */ @@ -4354,23 +4354,23 @@ /* */ -"faq.tip.beacon_quiet" = "Si te metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia qué dirección estás orientado. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; +"faq.tip.beacon_quiet" = "Si te metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia dónde estás mirando. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; /* */ -"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla de inicio, pulsa sobre la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, se mostrará una pantalla de \"Detalles de la ubicación\" con una opción para \"Iniciar señal de audio\" en la dirección. De este modo, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no estén en Open Street Map."; +"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla de inicio, pulsa sobre la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, aparecerá una pantalla de \"Detalles de la ubicación\" con la opción para \"Iniciar señal de audio\" en la dirección. De este modo, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no estén en Open Street Map."; /* */ -"faq.tip.finding_bus_stops" = "Para encontrar paradas de autobuses cercanos, selecciona el filtro \"Transporte público\" en la lista Lugares cercanos."; +"faq.tip.finding_bus_stops" = "Para encontrar paradas de autobús cercanos, selecciona el filtro \"Transporte público\" en la lista Lugares cercanos."; /* */ -"faq.tip.turning_beacon_off" = "Puedes activar y desactivar el sonido rítmico de la señal con el botón de silencio de la pantalla de inicio. Si la señal está silenciada, seguirás recibiendo actualizaciones sobre la distancia a tu destino cada 50 metros aproximadamente."; +"faq.tip.turning_beacon_off" = "Puedes activar y desactivar el sonido rítmico de la señal con el botón de silencio en la pantalla principal. Si la señal está silenciada, seguirás recibiendo actualizaciones sobre la distancia a tu destino cada 50 metros aproximadamente."; /* */ -"faq.tip.turning_off_auto_callouts" = "Si quieres seguir interactuando con Soundscape pero no quieres oír los avisos automáticos, puedes desactivarlos yendo a la sección \"Administrar Avisos\" de la pantalla \"Ajustes\" del menú y desactivando \"Permitir Avisos\". O, si no vas a utilizar Soundscape, puedes ponerlo en modo de reposo o de aplazamiento utilizando el botón \"Suspender\" de la pantalla de inicio."; +"faq.tip.turning_off_auto_callouts" = "Si quieres seguir interactuando con Soundscape pero no quieres oír los avisos automáticos, puedes desactivarlos yendo a la sección\"Administrar Avisos\" de la pantalla \"Ajustes\" del menú y desactivando \"Permitir Avisos\". O bien, si no vas a usar Soundscape, puedes ponerlo en el modo de suspensión o de aplazamiento con el botón \"Suspender\" en la pantalla principal."; /* */ @@ -4378,7 +4378,7 @@ /* */ -"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas regularmente, establece tus paradas de recogida y salida como Marcadores. De esta forma se guardarán para que puedas encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y Rutas\" desde la pantalla de inicio y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellos y recibirás actualizaciones periódicas sobre lo cerca que estás de tu parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás recibiendo actualizaciones de la distancia a lo largo del camino."; +"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas regularmente, establece tus paradas de recogida y salida como Marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y Rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y obtendrás actualizaciones periódicas sobre lo cerca que estás a tu parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás recibiendo actualizaciones de la distancia por el camino."; /* */ @@ -4434,13 +4434,13 @@ "devices.explain_ar.connected.boseframes" = "Tus Bose Frames están listas para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape está siguiendo la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano."; "help.using_headsets.bose_frames.title" = "Uso de Bose Frames"; "help.using_headsets.bose_frames.when" = "Puedes usar Bose Frames en cualquier momento con Soundscape. El uso de Bose Frames te proporciona un audio de alta calidad que no dificulta la audición ambiental y te permite tener una experiencia mayor de manos libres."; -"help.using_headsets.bose_frames.how.3" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén activados en la configuración de Soundscape, podrás usarlos en las Bose Frames para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; +"help.using_headsets.bose_frames.how.3" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén habilitados en la configuración de Soundscape, podrás usarlos en las Bose Frames para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; "help.using_headsets.bose_frames.how.1" = "Conexión de un dispositivo:
ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
Si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación de Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
La compatibilidad con las Bose Frames es nueva y nos encantaría escuchar tus comentarios. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; -"help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión frente a que dirección te encuentras. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. También puedes repetir esta calibración, en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; -"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza cuando se utilizan las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección frente a la cual te encuentras. Esto ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien."; +"help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión hacia dónde estás mirando. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. Puedes repetir esta calibración, en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; +"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien."; "whats_new.1_3_0.0.title" = "Compatibilidad con Bose Frames"; -"whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza cuando se utilizan las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección frente a la cual te encuentras. Esto ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; +"whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens."; @@ -4454,3 +4454,6 @@ "route_detail.action.start_reversed_route" = "Iniciar ruta de regreso"; "faq.tip.reverse_route" = "Cuando seleccionas \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden de regreso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; "help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y Rutas\" y, a continuación, \"Iniciar Ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior."; +"location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una Señal de audio según qué tan cerca esté esta ubicación."; +"beacon.suggest_navilens" = "Inicia NaviLens para obtener más información."; +"location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; From 8be138d7b1bdbccda834e5773054f411183bf032 Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Tue, 29 Apr 2025 21:44:25 -0400 Subject: [PATCH 20/76] Add NaviLens Codes as Nearby Places filter --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 3 +++ .../Assets/Localization/en-US.lproj/Localizable.strings | 3 +++ .../OSM Entity/GDASpatialDataResultEntity+Typeable.swift | 6 ++++++ .../Code/Data/Models/Helpers/Types/PrimaryType.swift | 1 + .../Visual UI/Helpers/Nearby Table/NearbyTableFilter.swift | 4 ++++ .../Data/Destination Manager/NearbyTableFilterTest.swift | 3 +++ 6 files changed, 20 insertions(+) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 6c5e43925..3c9a800b7 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -1876,6 +1876,9 @@ /* */ "filter.food_drink" = "Food & Drink"; +/* */ +"filter.navilens" = "NaviLens Codes"; + /* Filter, Parks */ "filter.parks" = "Parks"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 38a404f3f..64672de8c 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -1588,6 +1588,9 @@ /* Filters, Banks & ATMs */ "filter.banks" = "Banks & ATMs"; +/* Filters, NaviLens Codes */ +"filter.navilens" = "NaviLens Codes"; + /* Displayed next to the name of the filter to indicate that the filter is currently selected. %@ is the name of a filter */ "filter.selected" = "%@ (selected)"; diff --git a/apps/ios/GuideDogs/Code/Data/Models/Extensions/OSM Entity/GDASpatialDataResultEntity+Typeable.swift b/apps/ios/GuideDogs/Code/Data/Models/Extensions/OSM Entity/GDASpatialDataResultEntity+Typeable.swift index 79c4ac246..0002bb596 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Extensions/OSM Entity/GDASpatialDataResultEntity+Typeable.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Extensions/OSM Entity/GDASpatialDataResultEntity+Typeable.swift @@ -22,6 +22,8 @@ extension GDASpatialDataResultEntity: Typeable { return isBank() case .grocery: return isGrocery() + case .navilens: + return isNaviLens() } } @@ -75,4 +77,8 @@ extension GDASpatialDataResultEntity: Typeable { private func isGrocery() -> Bool { return isAnyOf(tags: ["convenience", "supermarket"]); } + + private func isNaviLens() -> Bool { + return superCategory == "navilens" + } } diff --git a/apps/ios/GuideDogs/Code/Data/Models/Helpers/Types/PrimaryType.swift b/apps/ios/GuideDogs/Code/Data/Models/Helpers/Types/PrimaryType.swift index 64b98c3fd..c66445080 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Helpers/Types/PrimaryType.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Helpers/Types/PrimaryType.swift @@ -15,6 +15,7 @@ enum PrimaryType: String, CaseIterable, Type { case park case bank case grocery + case navilens func matches(poi: POI) -> Bool { guard let typeable = poi as? Typeable else { diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Nearby Table/NearbyTableFilter.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Nearby Table/NearbyTableFilter.swift index ce7595562..e8da40914 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Nearby Table/NearbyTableFilter.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Nearby Table/NearbyTableFilter.swift @@ -24,6 +24,7 @@ struct NearbyTableFilter: Equatable { NearbyTableFilter(type: .park), NearbyTableFilter(type: .grocery), NearbyTableFilter(type: .bank), + NearbyTableFilter(type: .navilens), ] } @@ -70,6 +71,9 @@ struct NearbyTableFilter: Equatable { case .grocery: self.localizedString = GDLocalizedString("filter.groceries") self.image = UIImage(named: "Groceries & Convenience Stores") + case .navilens: + self.localizedString = GDLocalizedString("filter.navilens") + self.image = UIImage(named: "navilens") } } else { // There is no `PrimaryType` filter selected diff --git a/apps/ios/UnitTests/Data/Destination Manager/NearbyTableFilterTest.swift b/apps/ios/UnitTests/Data/Destination Manager/NearbyTableFilterTest.swift index 0065b9901..7467a7814 100644 --- a/apps/ios/UnitTests/Data/Destination Manager/NearbyTableFilterTest.swift +++ b/apps/ios/UnitTests/Data/Destination Manager/NearbyTableFilterTest.swift @@ -48,6 +48,9 @@ final class NearbyTableFilterTest: XCTestCase { case .grocery: XCTAssertEqual(filter.localizedString, GDLocalizedString("filter.groceries")) XCTAssertEqual(filter.image, UIImage(named: "Groceries & Convenience Stores ")) + case .navilens: + XCTAssertEqual(filter.localizedString, GDLocalizedString("filter.navilens")) + XCTAssertEqual(filter.image, UIImage(named: "navilens")) } } } From 46998c60e54081de9c0092f19718a3122ccc6650 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Wed, 30 Apr 2025 15:47:32 +0100 Subject: [PATCH 21/76] Bump version to 1.3.3 --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 227531481..e8316dbcf 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5531,7 +5531,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5562,7 +5562,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5820,7 +5820,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5852,7 +5852,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5880,7 +5880,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5910,7 +5910,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.3.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; From eba5e040e38667bfe05201bc3368e88b2ce65557 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Wed, 30 Apr 2025 16:39:30 +0200 Subject: [PATCH 22/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (English) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1168 of 1168 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1166 of 1166 strings) Translated using Weblate (English) Currently translated at 100.0% (1166 of 1166 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translation: Soundscape/iOS app --- .../es-ES.lproj/Localizable.strings | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 969b84244..f8d4e7756 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -2079,15 +2079,15 @@ /* */ -"directions.nearest_road_name_is_distance_direction" = "Carretera más cercana, %1$@, está a %2$@ %3$@"; +"directions.nearest_road_name_is_distance_direction" = "La carretera más cercana, %1$@, está a %2$@ %3$@"; /* */ -"directions.nearest_road_name_is_distance" = "Carretera más cercana, %1$@, está a %2$@ de distancia"; +"directions.nearest_road_name_is_distance" = "La carretera más cercana, %1$@, está a %2$@ de distancia"; /* */ -"directions.nearest_road_name_was_distance_direction" = "Carretera más cercana, %1$@, estaba a %2$@ %3$@"; +"directions.nearest_road_name_was_distance_direction" = "La carretera más cercana, %1$@, estaba a %2$@ %3$@"; /* */ @@ -2850,7 +2850,7 @@ /* */ -"devices.reachability.alert.description" = "Tu %@ puede indicarle a Soundscape en qué dirección estás mirando, y esto ayudará a Soundscape a mejorar tu experiencia de audio. Puedes activar el seguimiento de cabezas en los ajustes de Auriculares con seguimiento de cabeza."; +"devices.reachability.alert.description" = "Tu %@ puede indicarle a Soundscape en qué dirección estás mirando, y esto ayudará a Soundscape a mejorar tu experiencia de audio. Puedes activar el seguimiento de cabeza en los ajustes de Auriculares con seguimiento de cabeza."; /* */ @@ -3174,7 +3174,7 @@ /* */ -"tutorial.beacons.text.IntroPart1" = "Al establecer una señal en una ubicación, Soundscape reproducirá un sonido proveniente de la dirección de esta ubicación. Este tutorial te guiará por el establecimiento de una señal y cómo usarla."; +"tutorial.beacons.text.IntroPart1" = "Cuando estableces una señal en una ubicación, Soundscape reproducirá un sonido procedente de la dirección de esa ubicación. Este tutorial te guiará por el proceso de establecimiento de una señal y cómo usarla."; /* */ @@ -3234,7 +3234,7 @@ /* */ -"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal, mientras sigues manteniendo el teléfono en posición horizontal. El sonido del timbre se detendrá y la señal te mostrará dónde se encuentra @!destination!!. Pruébalo ahora."; +"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; /* */ @@ -3382,15 +3382,15 @@ /* */ -"terms_of_use.accept_checkbox.acc_label" = "Aceptar las condiciones de uso"; +"terms_of_use.accept_checkbox.acc_label" = "Aceptar los términos de uso"; /* */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"aceptar las condiciones de uso\"."; +"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"aceptar los términos de uso\"."; /* */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"aceptar las condiciones de uso\"."; +"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"aceptar los términos de uso\"."; /* */ @@ -3418,7 +3418,7 @@ /* */ -"first_launch.welcome_text" = "¡Bienvenido! Antes de comenzar, tenemos que pasar por algunos ajustes y aceptar varios permisos. Presiona el botón Siguiente para iniciar."; +"first_launch.welcome_text" = "¡Bienvenido! Antes de comenzar, tenemos que hacer algunos ajustes y pedir varios permisos. Presiona el botón Siguiente para iniciar."; /* */ @@ -4457,3 +4457,4 @@ "location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una Señal de audio según qué tan cerca esté esta ubicación."; "beacon.suggest_navilens" = "Inicia NaviLens para obtener más información."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; +"filter.navilens" = "Códigos NaviLens"; From 833bdec71be0637cf35098a2acf39f3cf39cfa55 Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Fri, 16 May 2025 18:16:28 -0400 Subject: [PATCH 23/76] Tweak wording for beacon-to-NaviLens transition --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 4 ++-- .../Assets/Localization/en-US.lproj/Localizable.strings | 8 ++++---- .../Assets/Localization/es-ES.lproj/Localizable.strings | 2 +- .../Code/Visual UI/Views/Beacon/BeaconToolbarView.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 3c9a800b7..6896a5f57 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -817,7 +817,7 @@ /* */ -"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; +"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; /* */ @@ -4485,7 +4485,7 @@ "whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; -"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; +"beacon.action.navilenst" = "Launch NaviLens"; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 64672de8c..09841b1ae 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -703,6 +703,9 @@ /* Button, Call out Beacon */ "beacon.action.callout_beacon" = "Call out Beacon"; +/* Button, Launch NaviLens */ +"beacon.action.navilens" = "Launch NaviLens"; + /* Notification, Double tap to unmute or mute the audio beacon */ "beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon."; @@ -722,7 +725,7 @@ "beacon.beacon_location_within_audio_beacon_muted" = "Beacon within %@. Audio beacon has been muted."; /* Suggest the user launch NaviLens for the remaining distance. Appended to beacon.beacon_location_within_audio_beacon_muted. */ -"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; +"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; //------------------------------------------------------------------------------ // MARK: - Preview @@ -915,9 +918,6 @@ /* Text displayed when street preview is disabled */ "location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; -/* Voiceover hint for the action to launch NaviLens */ -"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; - /* Voiceover hint for the action to get directions */ "location_detail.action.directions.hint" = "Double tap to open this location in an external maps app."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 3cef5efce..67489661a 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -4443,7 +4443,7 @@ "whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza cuando se utilizan las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección frente a la cual te encuentras. Esto ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; -"location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens."; +"beacon.action.navilens" = "Iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso."; diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift index 763518aaa..4b9166e89 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift @@ -147,7 +147,7 @@ struct BeaconToolbarView: View { }) .foregroundColor(.white) - .accessibilityLabel(GDLocalizedTextView("location_detail.action.navilens.hint")) + .accessibilityLabel(GDLocalizedTextView("beacon.action.navilens")) } Spacer() From ee157a17d0504a03600b8cdf5b550584790ee534 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Sat, 17 May 2025 14:40:28 +0100 Subject: [PATCH 24/76] Revert "Merge branch 'main' of https://github.com/soundscape-community/soundscape" This reverts commit 95fb8599ea8eea71fffd07d90444c89f75340d44, reversing changes made to 67d7d83bd82482b22350265bc767670bd639b0ae. --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 4 ++-- .../Assets/Localization/en-US.lproj/Localizable.strings | 8 ++++---- .../Assets/Localization/es-ES.lproj/Localizable.strings | 2 +- .../Code/Visual UI/Views/Beacon/BeaconToolbarView.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index dc7c7e730..3f512f5dd 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -817,7 +817,7 @@ /* */ -"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; +"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; /* */ @@ -4485,7 +4485,7 @@ "whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; -"beacon.action.navilenst" = "Launch NaviLens"; +"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 77dff7b24..50472bcc5 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -703,9 +703,6 @@ /* Button, Call out Beacon */ "beacon.action.callout_beacon" = "Call out Beacon"; -/* Button, Launch NaviLens */ -"beacon.action.navilens" = "Launch NaviLens"; - /* Notification, Double tap to unmute or mute the audio beacon */ "beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon."; @@ -725,7 +722,7 @@ "beacon.beacon_location_within_audio_beacon_muted" = "Beacon within %@. Audio beacon has been muted."; /* Suggest the user launch NaviLens for the remaining distance. Appended to beacon.beacon_location_within_audio_beacon_muted. */ -"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; +"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; //------------------------------------------------------------------------------ // MARK: - Preview @@ -918,6 +915,9 @@ /* Text displayed when street preview is disabled */ "location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; +/* Voiceover hint for the action to launch NaviLens */ +"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; + /* Voiceover hint for the action to get directions */ "location_detail.action.directions.hint" = "Double tap to open this location in an external maps app."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 063c91c1f..f8d4e7756 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -4443,7 +4443,7 @@ "whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; -"beacon.action.navilens" = "Iniciar NaviLens"; +"location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens."; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso."; diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift index 4b9166e89..763518aaa 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift @@ -147,7 +147,7 @@ struct BeaconToolbarView: View { }) .foregroundColor(.white) - .accessibilityLabel(GDLocalizedTextView("beacon.action.navilens")) + .accessibilityLabel(GDLocalizedTextView("location_detail.action.navilens.hint")) } Spacer() From c1a71103fa352779f2daaea4cb7ba3edae033ea6 Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Fri, 16 May 2025 18:16:28 -0400 Subject: [PATCH 25/76] Tweak wording for beacon-to-NaviLens transition --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 4 ++-- .../Assets/Localization/en-US.lproj/Localizable.strings | 8 ++++---- .../Assets/Localization/es-ES.lproj/Localizable.strings | 2 +- .../Code/Visual UI/Views/Beacon/BeaconToolbarView.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 3f512f5dd..dc7c7e730 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -817,7 +817,7 @@ /* */ -"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; +"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; /* */ @@ -4485,7 +4485,7 @@ "whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; -"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; +"beacon.action.navilenst" = "Launch NaviLens"; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 50472bcc5..77dff7b24 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -703,6 +703,9 @@ /* Button, Call out Beacon */ "beacon.action.callout_beacon" = "Call out Beacon"; +/* Button, Launch NaviLens */ +"beacon.action.navilens" = "Launch NaviLens"; + /* Notification, Double tap to unmute or mute the audio beacon */ "beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon."; @@ -722,7 +725,7 @@ "beacon.beacon_location_within_audio_beacon_muted" = "Beacon within %@. Audio beacon has been muted."; /* Suggest the user launch NaviLens for the remaining distance. Appended to beacon.beacon_location_within_audio_beacon_muted. */ -"beacon.suggest_navilens" = "Launch NaviLens for additional guidance."; +"beacon.suggest_navilens" = "Use the NaviLens button to take you to your destination."; //------------------------------------------------------------------------------ // MARK: - Preview @@ -915,9 +918,6 @@ /* Text displayed when street preview is disabled */ "location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; -/* Voiceover hint for the action to launch NaviLens */ -"location_detail.action.navilens.hint" = "Double tap to launch NaviLens."; - /* Voiceover hint for the action to get directions */ "location_detail.action.directions.hint" = "Double tap to open this location in an external maps app."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index f8d4e7756..063c91c1f 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -4443,7 +4443,7 @@ "whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; -"location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens."; +"beacon.action.navilens" = "Iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso."; diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift index 763518aaa..4b9166e89 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Beacon/BeaconToolbarView.swift @@ -147,7 +147,7 @@ struct BeaconToolbarView: View { }) .foregroundColor(.white) - .accessibilityLabel(GDLocalizedTextView("location_detail.action.navilens.hint")) + .accessibilityLabel(GDLocalizedTextView("beacon.action.navilens")) } Spacer() From 54cf79117970f25216e6cc972682ba7b345a9067 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Sat, 17 May 2025 14:09:51 +0100 Subject: [PATCH 26/76] Fix typo in translation key --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index dc7c7e730..83fdf0b37 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -4485,7 +4485,7 @@ "whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; -"beacon.action.navilenst" = "Launch NaviLens"; +"beacon.action.navilens" = "Launch NaviLens"; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; From 0ffe0bccc07668580067131938414771b835bb81 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Wed, 14 May 2025 07:01:55 +0200 Subject: [PATCH 27/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 99.6% (1165 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 99.6% (1165 of 1169 strings) Translated using Weblate (English) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 156 +++++----- .../en-US.lproj/Localizable.strings | 158 +++++----- .../es-ES.lproj/Localizable.strings | 275 +++++++++--------- 3 files changed, 295 insertions(+), 294 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 83fdf0b37..9395f1786 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -555,7 +555,7 @@ /* */ -"voice.apple.preview_hint" = "Double tap to select and play a preview."; +"voice.apple.preview_hint" = "Double tap to select and play a preview"; /* */ @@ -633,7 +633,7 @@ /* */ -"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones."; +"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones"; /* */ @@ -645,7 +645,7 @@ /* */ -"troubleshooting.cache.hint" = "Double tap to delete and reload stored map data."; +"troubleshooting.cache.hint" = "Double tap to delete and reload stored map data"; /* */ @@ -673,11 +673,11 @@ /* */ -"settings.new_feature.accept_button.acc_label" = "Double tap to close announcements."; +"settings.new_feature.accept_button.acc_label" = "Double tap to close announcements"; /* */ -"settings.new_feature.accept_button.acc_hint" = "Double tap to view next update announcement."; +"settings.new_feature.accept_button.acc_hint" = "Double tap to view next update announcement"; /* */ @@ -765,7 +765,7 @@ /* */ -"beacon.action.remove_beacon.double_tap.acc_hint" = "Double tap to remove the current audio beacon."; +"beacon.action.remove_beacon.double_tap.acc_hint" = "Double tap to remove the current audio beacon"; /* */ @@ -773,7 +773,7 @@ /* */ -"beacon.action.mute_beacon.acc_hint" = "Double tap to mute the audio beacon."; +"beacon.action.mute_beacon.acc_hint" = "Double tap to mute the audio beacon"; /* */ @@ -781,7 +781,7 @@ /* */ -"beacon.action.unmute_beacon.acc_hint" = "Double tap to unmute the audio beacon."; +"beacon.action.unmute_beacon.acc_hint" = "Double tap to unmute the audio beacon"; /* */ @@ -793,7 +793,7 @@ /* */ -"beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon."; +"beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon"; /* */ @@ -801,7 +801,7 @@ /* */ -"beacon.action.view_details.acc_hint.details" = "Double tap to view additional details."; +"beacon.action.view_details.acc_hint.details" = "Double tap to view additional details"; /* */ @@ -849,7 +849,7 @@ /* */ -"preview.content.edge.text.accessibility_hint" = "Double tap to move to the next intersection."; +"preview.content.edge.text.accessibility_hint" = "Double tap to move to the next intersection"; /* */ @@ -861,7 +861,7 @@ /* */ -"preview.go_back.accessibility_text" = "Double tap to go back to your previous intersection."; +"preview.go_back.accessibility_text" = "Double tap to go back to your previous intersection"; /* */ @@ -869,7 +869,7 @@ /* */ -"preview.search.accessibility_hint" = "Double tap to search or browse nearby places."; +"preview.search.accessibility_hint" = "Double tap to search or browse nearby places"; /* */ @@ -973,15 +973,15 @@ /* */ -"preview.include_unnamed_roads.hint.off" = "Double tap to include unnamed roads during Soundscape Street Preview."; +"preview.include_unnamed_roads.hint.off" = "Double tap to include unnamed roads during Soundscape Street Preview"; /* */ -"preview.include_unnamed_roads.hint.on" = "Double tap to exclude unnamed roads during Soundscape Street Preview."; +"preview.include_unnamed_roads.hint.on" = "Double tap to exclude unnamed roads during Soundscape Street Preview"; /* */ -"preview.tutorial.done.hint" = "Double tap to exit the tutorial."; +"preview.tutorial.done.hint" = "Double tap to exit the tutorial"; /* */ @@ -1031,35 +1031,35 @@ "location_detail.action.beacon_or_navilens" = "Start NaviLens or Audio Beacon"; /* */ -"location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location."; +"location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location"; /* */ -"location_detail.action.beacon.hint.disabled" = "Setting a new audio beacon is disabled while route guidance is active."; +"location_detail.action.beacon.hint.disabled" = "Setting a new audio beacon is disabled while route guidance is active"; /* */ -"location_detail.action.save.hint" = "Double tap to save this location as a marker."; +"location_detail.action.save.hint" = "Double tap to save this location as a marker"; /* */ -"location_detail.action.edit.hint" = "Double tap to edit marker."; +"location_detail.action.edit.hint" = "Double tap to edit marker"; /* */ -"location_detail.action.share.hint" = "Double tap to share this location."; +"location_detail.action.share.hint" = "Double tap to share this location"; /* */ -"location_detail.action.preview.hint" = "Double tap to start previewing at this location."; +"location_detail.action.preview.hint" = "Double tap to start previewing at this location"; /* */ -"location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; +"location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active"; /* */ -"location_detail.action.directions.hint" = "Double tap to open this location in an external maps app."; +"location_detail.action.directions.hint" = "Double tap to open this location in an external maps app"; /* */ @@ -1071,7 +1071,7 @@ /* */ -"location.select.hint" = "Double tap to select this location."; +"location.select.hint" = "Double tap to select this location"; /* */ @@ -1091,7 +1091,7 @@ /* */ -"location_detail.map.view.hint" = "Edit to select a new location."; +"location_detail.map.view.hint" = "Edit to select a new location"; /* */ @@ -1099,7 +1099,7 @@ /* */ -"location_detail.map.edit.hint" = "Move the map to the correct location."; +"location_detail.map.edit.hint" = "Move the map to the correct location"; /* */ @@ -1155,7 +1155,7 @@ /* */ -"location_detail.map.edit.accessibility.beacon.callout" = "Starting beacon to track marker location. Nudging, %@ of original location."; +"location_detail.map.edit.accessibility.beacon.callout" = "Starting beacon to track marker location. Nudging, %@ of original location"; /* */ @@ -1163,15 +1163,15 @@ /* */ -"location_detail.add_waypoint.existing.hint" = "Double tap to remove this marker from your route."; +"location_detail.add_waypoint.existing.hint" = "Double tap to remove this marker from your route"; /* */ -"location_detail.add_waypoint.new.hint" = "Double tap to add this marker to your route."; +"location_detail.add_waypoint.new.hint" = "Double tap to add this marker to your route"; /* */ -"location_detail.add_waypoint.marker.hint" = "Double tap to create a marker and add it as a waypoint."; +"location_detail.add_waypoint.marker.hint" = "Double tap to create a marker and add it as a waypoint"; /* */ @@ -1196,41 +1196,41 @@ "route_detail.action.edit" = "Edit Route"; /* */ -"route_detail.action.start_reversed_route.hint" = "Double tap to start this route in reverse."; +"route_detail.action.start_reversed_route.hint" = "Double tap to start this route in reverse"; /* */ -"route_detail.action.start_reversed_route.disabled.hint" = "Add waypoints before starting the route in reverse."; +"route_detail.action.start_reversed_route.disabled.hint" = "Add waypoints before starting the route in reverse"; /* */ -"route_detail.action.start_route.hint" = "Double tap to start this route."; +"route_detail.action.start_route.hint" = "Double tap to start this route"; /* */ -"route_detail.action.start_route.disabled.hint" = "Add waypoints before starting the route."; +"route_detail.action.start_route.disabled.hint" = "Add waypoints before starting the route"; /* */ -"route_detail.action.stop_route.hint" = "Double tap to stop this route."; +"route_detail.action.stop_route.hint" = "Double tap to stop this route"; /* */ -"route_detail.action.start_event.hint" = "Double tap to start this activity."; +"route_detail.action.start_event.hint" = "Double tap to start this activity"; /* */ -"route_detail.action.stop_event.hint" = "Double tap to stop this activity and save your progress."; +"route_detail.action.stop_event.hint" = "Double tap to stop this activity and save your progress"; /* */ -"route_detail.action.reset.hint" = "Double tap to reset this activity and download any available updates."; +"route_detail.action.reset.hint" = "Double tap to reset this activity and download any available updates"; /* */ -"route_detail.action.share.hint" = "Double tap to share this route."; +"route_detail.action.share.hint" = "Double tap to share this route"; /* */ -"route_detail.action.edit.hint" = "Double tap to edit this route."; +"route_detail.action.edit.hint" = "Double tap to edit this route"; /* */ @@ -1238,7 +1238,7 @@ /* */ -"route_detail.action.create.hint" = "Double tap to create a new route."; +"route_detail.action.create.hint" = "Double tap to create a new route"; /* */ @@ -1310,7 +1310,7 @@ /* */ -"route_detail.action.previous.hint" = "Double tap to set the beacon on the previous waypoint."; +"route_detail.action.previous.hint" = "Double tap to set the beacon on the previous waypoint"; /* */ @@ -1318,7 +1318,7 @@ /* */ -"route_detail.action.next.hint" = "Double tap to set the beacon on the next waypoint."; +"route_detail.action.next.hint" = "Double tap to set the beacon on the next waypoint"; /* */ @@ -1426,7 +1426,7 @@ /* */ -"tour.progress.distance.accessibility" = "Beacon set on %1$@, %2$@, %3$@ waypoints remaining"; +"tour.progress.distance.accessibility" = "Beacon set on %1$@. %2$@. %3$@ waypoints remaining"; /* */ @@ -1442,7 +1442,7 @@ /* */ -"tour.progress.distance.accessibility.singular" = "Beacon set on %1$@, %2$@, 1 waypoint remaining"; +"tour.progress.distance.accessibility.singular" = "Beacon set on %1$@. %2$@. 1 waypoint remaining"; /* */ @@ -1470,7 +1470,7 @@ /* */ -"waypoint.callout.button.hint" = "Double tap to hear additional details."; +"waypoint.callout.button.hint" = "Double tap to hear additional details"; /* */ @@ -1642,7 +1642,7 @@ /* */ -"routes.sort.by_name.hint" = "Double tap to sort by name."; +"routes.sort.by_name.hint" = "Double tap to sort by name"; /* */ @@ -1650,7 +1650,7 @@ /* */ -"routes.sort.by_distance.hint" = "Double tap to sort by distance."; +"routes.sort.by_distance.hint" = "Double tap to sort by distance"; /* */ @@ -1726,7 +1726,7 @@ /* */ -"markers.edit_screen.done_button.acc_hint" = "Double tap to save this marker."; +"markers.edit_screen.done_button.acc_hint" = "Double tap to save this marker"; /* */ @@ -1834,15 +1834,15 @@ /* */ -"search.button.markers.accessibility_hint" = "Double tap to select or edit your saved markers and routes."; +"search.button.markers.accessibility_hint" = "Double tap to select or edit your saved markers and routes"; /* */ -"search.button.nearby.accessibility_hint" = "Double tap to explore nearby restaurants, public transport and more."; +"search.button.nearby.accessibility_hint" = "Double tap to explore nearby restaurants, public transport and more"; /* */ -"search.button.current_location.accessibility_hint" = "Double tap to preview, mark, or share your current location with a friend."; +"search.button.current_location.accessibility_hint" = "Double tap to preview, mark, or share your current location with a friend"; /* */ @@ -1858,11 +1858,11 @@ /* */ -"filter.clear.hint" = "Double tap to clear selected filter."; +"filter.clear.hint" = "Double tap to clear selected filter"; /* */ -"filter.double_tap_places_category" = "Double tap to filter places by category."; +"filter.double_tap_places_category" = "Double tap to filter places by category"; /* */ @@ -1993,7 +1993,7 @@ /* */ -"callouts.hardware.low_battery" = "%1$@ only has %2$@ percent battery remaining."; +"callouts.hardware.low_battery" = "%1$@ only has %2$@ percent battery remaining"; /* */ @@ -2025,7 +2025,7 @@ /* */ -"sleep.sleep.acc_hint" = "Double tap to put Soundscape to sleep."; +"sleep.sleep.acc_hint" = "Double tap to put Soundscape to sleep"; /* */ @@ -2592,7 +2592,7 @@ /* */ -"ui.action_button.my_location.acc_hint" = "Double tap to hear about your current location."; +"ui.action_button.my_location.acc_hint" = "Double tap to hear about your current location"; /* */ @@ -2600,7 +2600,7 @@ /* */ -"ui.action_button.nearby_markers.acc_hint" = "Double tap to hear about nearby places that you have marked."; +"ui.action_button.nearby_markers.acc_hint" = "Double tap to hear about nearby places that you have marked"; /* */ @@ -2608,7 +2608,7 @@ /* */ -"ui.action_button.around_me.acc_hint" = "Double tap to hear about places in the four quadrants around you."; +"ui.action_button.around_me.acc_hint" = "Double tap to hear about places in the four quadrants around you"; /* */ @@ -2616,7 +2616,7 @@ /* */ -"ui.action_button.ahead_of_me.acc_hint" = "Double tap to hear about places in front of you."; +"ui.action_button.ahead_of_me.acc_hint" = "Double tap to hear about places in front of you"; /* */ @@ -2624,7 +2624,7 @@ /* */ -"ui.menu.hint" = "Double tap to open the menu."; +"ui.menu.hint" = "Double tap to open the menu"; /* */ @@ -2704,7 +2704,7 @@ /* */ -"poi_cell.accessibility_hint.suggested_search" = "Double tap to search for: %@."; +"poi_cell.accessibility_hint.suggested_search" = "Double tap to search for: %@"; /* */ @@ -2716,7 +2716,7 @@ /* */ -"location_callout_cell.nearest_road" = "Nearest road, %@."; +"location_callout_cell.nearest_road" = "Nearest road, %@"; /* */ @@ -2815,7 +2815,7 @@ /* */ -"devices.connect_headset.completed.test.hint" = "Double tap to check your %@."; +"devices.connect_headset.completed.test.hint" = "Double tap to check your %@"; /* */ @@ -3107,7 +3107,7 @@ /* */ -"action.double_tap_to_repeat" = "Double tap to repeat."; +"action.double_tap_to_repeat" = "Double tap to repeat"; /* */ @@ -3155,7 +3155,7 @@ /* */ -"tutorial.markers.mark_location.acc_hint" = "Double tap to mark this location."; +"tutorial.markers.mark_location.acc_hint" = "Double tap to mark this location"; /* */ @@ -3195,7 +3195,7 @@ /* */ -"tutorial.beacon.mark_location.acc_hint" = "Double tap to use this location for the beacon tutorial."; +"tutorial.beacon.mark_location.acc_hint" = "Double tap to use this location for the beacon tutorial"; /* */ @@ -3307,7 +3307,7 @@ /* */ -"tutorial.beacons.text.MuteRepeat" = "Double tap with two fingers anywhere on the screen."; +"tutorial.beacons.text.MuteRepeat" = "Double tap with two fingers anywhere on the screen"; /* */ @@ -3431,11 +3431,11 @@ /* */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to tick the \"accept the terms of use\" checkbox."; +"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to tick the \"accept the terms of use\" checkbox"; /* */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to untick the \"accept the terms of use\" checkbox."; +"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to untick the \"accept the terms of use\" checkbox"; /* */ @@ -3455,11 +3455,11 @@ /* */ -"terms_of_use.accept.new_features.accessibility_hint" = "Double tap to accept and close announcements."; +"terms_of_use.accept.new_features.accessibility_hint" = "Double tap to accept and close announcements"; /* */ -"first_launch.get_started_button.off.acc_hint" = "You must tick the \"accept the terms of use\" checkbox before you can press this button."; +"first_launch.get_started_button.off.acc_hint" = "You must tick the \"accept the terms of use\" checkbox before you can press this button"; /* */ @@ -3471,7 +3471,7 @@ /* */ -"first_launch.permission_required" = "This permission is required."; +"first_launch.permission_required" = "This permission is required"; /* */ @@ -3575,7 +3575,7 @@ /* */ -"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk."; +"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk"; /* */ @@ -3603,7 +3603,7 @@ /* */ -"first_launch.permissions.required" = "This permission is required."; +"first_launch.permissions.required" = "This permission is required"; /* */ @@ -4103,7 +4103,7 @@ /* */ -"banner.custom_behavior.scavenger_hunt.hint" = "Double tap to read about or pause the scavenger hunt."; +"banner.custom_behavior.scavenger_hunt.hint" = "Double tap to read about or pause the scavenger hunt"; /* */ @@ -4457,7 +4457,7 @@ "whats_new.1_2_0.0.description" = "You can now shake your device to repeat the last callout. To enable this feature, switch on the 'Repeat Callouts' toggle in settings."; "whats_new.1_2_0.1.title" = "Beacon Mute Distance Setting"; "whats_new.1_2_0.2.title" = "Categories in Places Nearby"; -"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as public transport, Food & Drink, etc."; +"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as Public Transport, Food & Drink, etc."; "settings.about.title.copyright" = "Copyright Notices"; "first_launch.permissions.motion" = "Motion & Fitness"; "osm.tag.bar" = "Bar"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 77dff7b24..887aa0c6c 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -490,7 +490,7 @@ "voice.apple.preview" = "This is %@. How does this sound?"; /* Hint explaining that if the user double taps a voice in the list of voices, it will be selected and a preview will be played. */ -"voice.apple.preview_hint" = "Double tap to select and play a preview."; +"voice.apple.preview_hint" = "Double tap to select and play a preview"; /* This is the title of an alert presented to the user when they selecte a default version of a voice which has an enhanced version to inform them that they can download an enhanced version from the iOS Settings app */ "voice.settings.enhanced_available.title" = "Enhanced Voice Available!"; @@ -569,7 +569,7 @@ "troubleshooting.check_audio" = "Check Audio"; /* Voiceover hint that explains the action of the "Check Audio" button. */ -"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones."; +"troubleshooting.check_audio.hint" = "Double tap to check the status of your headphones"; /* Explanation of what the "Check Audio" button does, displayed below the button */ "troubleshooting.check_audio.explanation" = "Tap this button to hear about the status of the headphones you are using with Soundscape."; @@ -578,7 +578,7 @@ "troubleshooting.cache" = "Map Data"; /* VoiceOver hint that explains the action of the "Delete Stored Map Data" button */ -"troubleshooting.cache.hint" = "Double tap to delete and reload stored map data."; +"troubleshooting.cache.hint" = "Double tap to delete and reload stored map data"; /* Explanation of what the "Delete Stored Map Data" button does, displayed below the button */ "troubleshooting.cache.explanation" = "Soundscape downloads map data as you walk around so that it can tell you about the things and places around you. If you are having issues with Soundscape or it is using too much memory, you can clear the stored map data and Soundscape will only redownload the map data near your current location."; @@ -610,10 +610,10 @@ "settings.new_feature.num_of_num" = "%1$@ of %2$@"; /* Settings new feature, instruction to double tap to close announcements */ -"settings.new_feature.accept_button.acc_label" = "Double tap to close announcements."; +"settings.new_feature.accept_button.acc_label" = "Double tap to close announcements"; /* Settings new feature, instruction to double tap to view next update announcement */ -"settings.new_feature.accept_button.acc_hint" = "Double tap to view next update announcement."; +"settings.new_feature.accept_button.acc_hint" = "Double tap to view next update announcement"; /* Settings New Feature, title Recent Updates */ "settings.new_feature.recent_updates" = "Recent Updates"; @@ -683,19 +683,19 @@ "beacon.action.remove_beacon" = "Remove Beacon"; /* Notification, Double tap this button to remove current audio beacon */ -"beacon.action.remove_beacon.double_tap.acc_hint" = "Double tap to remove the current audio beacon."; +"beacon.action.remove_beacon.double_tap.acc_hint" = "Double tap to remove the current audio beacon"; /* Button, Mute Beacon */ "beacon.action.mute_beacon" = "Mute Beacon"; /* Notification, Double tap to mute the audio beacon */ -"beacon.action.mute_beacon.acc_hint" = "Double tap to mute the audio beacon."; +"beacon.action.mute_beacon.acc_hint" = "Double tap to mute the audio beacon"; /* Button, Unmute Beacon */ "beacon.action.unmute_beacon" = "Unmute Beacon"; /* Notification, Double tap to unmute the audio beacon */ -"beacon.action.unmute_beacon.acc_hint" = "Double tap to unmute the audio beacon."; +"beacon.action.unmute_beacon.acc_hint" = "Double tap to unmute the audio beacon"; /* Button, Mute or Unmute Beacon */ "beacon.action.mute_unmute_beacon" = "Mute or Unmute Beacon"; @@ -707,13 +707,13 @@ "beacon.action.navilens" = "Launch NaviLens"; /* Notification, Double tap to unmute or mute the audio beacon */ -"beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon."; +"beacon.action.mute_unmute_beacon.acc_hint" = "Double tap to mute or unmute the audio beacon"; /* Title text of the button used to view the detail view */ "beacon.action.view_details" = "View Details"; /* Hint text of the button used to view the detail view */ -"beacon.action.view_details.acc_hint.details" = "Double tap to view additional details."; +"beacon.action.view_details.acc_hint.details" = "Double tap to view additional details"; /* Button, Beacon Distance Update */ "beacon.distance_update" = "Beacon Distance Update"; @@ -753,7 +753,7 @@ "preview.content.edge.text" = "%1$@ on %2$@"; /* Accessibility hint for the button to select a direction of travel */ -"preview.content.edge.text.accessibility_hint" = "Double tap to move to the next intersection."; +"preview.content.edge.text.accessibility_hint" = "Double tap to move to the next intersection"; /* Title for button to go to the next intersection */ "preview.go.title" = "Go"; @@ -762,13 +762,13 @@ "preview.go_back.title" = "Previous"; /* Accessibility hint for button to go back */ -"preview.go_back.accessibility_text" = "Double tap to go back to your previous intersection."; +"preview.go_back.accessibility_text" = "Double tap to go back to your previous intersection"; /* Text for the "Search" button */ "preview.search.label" = "Explore Nearby"; /* Accessibility hint for the "Explore" button */ -"preview.search.accessibility_hint" = "Double tap to search or browse nearby places."; +"preview.search.accessibility_hint" = "Double tap to search or browse nearby places"; /* Title for the alert displayed when ther user tries to restart the preview experience at a new location */ "preview.alert.restart.title" = "Preview Already in Progress"; @@ -846,13 +846,13 @@ "preview.include_unnamed_roads.label.on" = "Disable Unnamed Roads"; /* Voiceover hint for a button to turn on a setting to include unnamed roads. {NumberedPlaceholder="Soundscape Street Preview"} */ -"preview.include_unnamed_roads.hint.off" = "Double tap to include unnamed roads during Soundscape Street Preview."; +"preview.include_unnamed_roads.hint.off" = "Double tap to include unnamed roads during Soundscape Street Preview"; /* Voiceover hint for a button to turn off a setting to include unnamed roads. {NumberedPlaceholder="Soundscape Street Preview"} */ -"preview.include_unnamed_roads.hint.on" = "Double tap to exclude unnamed roads during Soundscape Street Preview."; +"preview.include_unnamed_roads.hint.on" = "Double tap to exclude unnamed roads during Soundscape Street Preview"; /* Accessibility hint for the button to end the preview tutorial */ -"preview.tutorial.done.hint" = "Double tap to exit the tutorial."; +"preview.tutorial.done.hint" = "Double tap to exit the tutorial"; /* Title for the first set of tutorial content. {NumberedPlaceholder="Soundscape Street Preview"} */ "preview.tutorial.title.1" = "Welcome to Soundscape Street Preview!"; @@ -895,31 +895,31 @@ "location_detail.action.beacon_or_navilens" = "Start NaviLens or Audio Beacon"; /* Voiceover hint for the action to set a beacon */ -"location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location."; +"location_detail.action.beacon.hint" = "Double tap to set an audio beacon at this location"; /* Voiceover hint for the action to set a beacon or launch NaviLens */ -"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; +"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is"; /* Text displayed when audio beacon action is disabled */ -"location_detail.action.beacon.hint.disabled" = "Setting a new audio beacon is disabled while route guidance is active."; +"location_detail.action.beacon.hint.disabled" = "Setting a new audio beacon is disabled while route guidance is active"; /* Voiceover hint for the action to save marker */ -"location_detail.action.save.hint" = "Double tap to save this location as a marker."; +"location_detail.action.save.hint" = "Double tap to save this location as a marker"; /* Voiceover hint for the action to edit marker */ -"location_detail.action.edit.hint" = "Double tap to edit marker."; +"location_detail.action.edit.hint" = "Double tap to edit marker"; /* Voiceover hint for the action to share */ -"location_detail.action.share.hint" = "Double tap to share this location."; +"location_detail.action.share.hint" = "Double tap to share this location"; /* Voiceover hint for the action to preview */ -"location_detail.action.preview.hint" = "Double tap to start previewing at this location."; +"location_detail.action.preview.hint" = "Double tap to start previewing at this location"; /* Text displayed when street preview is disabled */ -"location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active."; +"location_detail.action.preview.hint.disabled" = "Street Preview is disabled while route guidance is active"; /* Voiceover hint for the action to get directions */ -"location_detail.action.directions.hint" = "Double tap to open this location in an external maps app."; +"location_detail.action.directions.hint" = "Double tap to open this location in an external maps app"; /* Default address for a location */ "location_detail.default.address" = "Address unknown"; @@ -928,7 +928,7 @@ "location_detail.default.annotation" = "No marker annotation"; /* Accessibility hint to select a location */ -"location.select.hint" = "Double tap to select this location."; +"location.select.hint" = "Double tap to select this location"; /* Text displayed when the location cannot be saved as a marker */ "location_detail.disabled.save" = "Saving a marker at this location is currently unavailable"; @@ -943,13 +943,13 @@ "location_detail.map.view.title" = "Selected Location"; /* Hint text displayed when the user is viewing the expanded map view */ -"location_detail.map.view.hint" = "Edit to select a new location."; +"location_detail.map.view.hint" = "Edit to select a new location"; /* Title text displayed when the user is selecting a location via the expanded map view */ "location_detail.map.edit.title" = "Edit Location"; /* Hint text displayed when the user is selecting a location via the expanded map view */ -"location_detail.map.edit.hint" = "Move the map to the correct location."; +"location_detail.map.edit.hint" = "Move the map to the correct location"; /* Accessibility label used when the user is moving the marker location via custom Voiceover experience, Here, "nudge" means moving a small distance. */ "location_detail.map.edit.accessibility_label" = "Nudge Marker"; @@ -991,19 +991,19 @@ "location_detail.map.edit.accessibility_action.current_location" = "Move to current location"; /* Callout made when starting the audio beacon while the user is moving a marker via custom Voiceover experience, %@ is a localized distance / direction string, "Nudging, 15 meters northwest of original location", Here, "nudge" means moving a small distance, {NumberedPlaceholder="%@"} */ -"location_detail.map.edit.accessibility.beacon.callout" = "Starting beacon to track marker location. Nudging, %@ of original location."; +"location_detail.map.edit.accessibility.beacon.callout" = "Starting beacon to track marker location. Nudging, %@ of original location"; /* Accessibility label for the icon which displays the number of the waypoint. %@ is the index of the waypoint. (e.g., "Waypoint 1") {NumberedPlaceholder="%@"} */ "location_detail.waypoint" = "Waypoint %@"; /* Accessibility hint for markers in a list which has already been added to a route */ -"location_detail.add_waypoint.existing.hint" = "Double tap to remove this marker from your route."; +"location_detail.add_waypoint.existing.hint" = "Double tap to remove this marker from your route"; /* Accessibility hint for markers in a list that can be added to a list */ -"location_detail.add_waypoint.new.hint" = "Double tap to add this marker to your route."; +"location_detail.add_waypoint.new.hint" = "Double tap to add this marker to your route"; /* Accessibility hint for markers in a list that can be created abd added to a list */ -"location_detail.add_waypoint.marker.hint" = "Double tap to create a marker and add it as a waypoint."; +"location_detail.add_waypoint.marker.hint" = "Double tap to create a marker and add it as a waypoint"; //------------------------------------------------------------------------------ // MARK: - Route Detail @@ -1028,40 +1028,40 @@ "route_detail.action.edit" = "Edit Route"; /* Accessibility hint for the reversed route button on the Route Detail screen */ -"route_detail.action.start_reversed_route.hint" = "Double tap to start this route in reverse."; +"route_detail.action.start_reversed_route.hint" = "Double tap to start this route in reverse"; /* Voiceover hint for the action to start the route in reverse when the action is disabled. This action is only disabled when no waypoints have been added to a route yet. */ -"route_detail.action.start_reversed_route.disabled.hint" = "Add waypoints before starting the route in reverse."; +"route_detail.action.start_reversed_route.disabled.hint" = "Add waypoints before starting the route in reverse"; /* Voiceover hint for the action to start the route */ -"route_detail.action.start_route.hint" = "Double tap to start this route."; +"route_detail.action.start_route.hint" = "Double tap to start this route"; /* Voiceover hint for the action to start the route when the action is disabled. This action is only disabled when no waypoints have been added to a route yet. */ -"route_detail.action.start_route.disabled.hint" = "Add waypoints before starting the route."; +"route_detail.action.start_route.disabled.hint" = "Add waypoints before starting the route"; /* Voiceover hint for the action to stop the route */ -"route_detail.action.stop_route.hint" = "Double tap to stop this route."; +"route_detail.action.stop_route.hint" = "Double tap to stop this route"; /* Voiceover hint for the action to start the recreational activity. In this context, "activity" is referring to outdoor recreational activities like hiking, kayaking, snoeshoeing, etc. */ -"route_detail.action.start_event.hint" = "Double tap to start this activity."; +"route_detail.action.start_event.hint" = "Double tap to start this activity"; /* Voiceover hint for the action to pause the recreational activity. In this context, "activity" is referring to outdoor recreational activities like hiking, kayaking, snoeshoeing, etc. */ -"route_detail.action.stop_event.hint" = "Double tap to stop this activity and save your progress."; +"route_detail.action.stop_event.hint" = "Double tap to stop this activity and save your progress"; /* Voiceover hint for the action to reset the recreational activity so that the user can try it again. In this context, "activity" is referring to outdoor recreational activities like hiking, kayaking, snoeshoeing, etc. */ -"route_detail.action.reset.hint" = "Double tap to reset this activity and download any available updates."; +"route_detail.action.reset.hint" = "Double tap to reset this activity and download any available updates"; /* Voiceover hint for the action to share */ -"route_detail.action.share.hint" = "Double tap to share this route."; +"route_detail.action.share.hint" = "Double tap to share this route"; /* Accessibility hint for the edit button on the Route Detail screen */ -"route_detail.action.edit.hint" = "Double tap to edit this route."; +"route_detail.action.edit.hint" = "Double tap to edit this route"; /* Add button on the Route list screen */ "route_detail.action.create" = "New Route"; /* VoiceOver hint for the add button on the Route list screen */ -"route_detail.action.create.hint" = "Double tap to create a new route."; +"route_detail.action.create.hint" = "Double tap to create a new route"; /* Accessbility label for the index of a waypoint in a route and an indication that the audio beacon is currently playing on this waypoint's location, %@ is the index, "Waypoint 2. Current beacon." {NumberedPlaceholder="%@"} */ "route_detail.waypoint.current_beacon" = "Waypoint %@. Current beacon."; @@ -1115,13 +1115,13 @@ "route_detail.action.previous" = "Previous Waypoint"; /* Hint text of the button used to move to the previous waypoint */ -"route_detail.action.previous.hint" = "Double tap to set the beacon on the previous waypoint."; +"route_detail.action.previous.hint" = "Double tap to set the beacon on the previous waypoint"; /* Title text of the button used to move to the next waypoint */ "route_detail.action.next" = "Next Waypoint"; /* Hint text of the button used to move to the next waypoint */ -"route_detail.action.next.hint" = "Double tap to set the beacon on the next waypoint."; +"route_detail.action.next.hint" = "Double tap to set the beacon on the next waypoint"; /* Text displayed in cluster annotations on the map. %@ is the index of the first clustered annotation and the +... indicates that there are additional annotations in that cluster {NumberedPlaceholder="%@"} */ "waypoint_detail.annotation.cluster.title" = "%@,..."; @@ -1206,7 +1206,7 @@ "tour.progress.elapsed_distance.accessibility" = "Beacon set on %1$@. %2$@. %3$@ elapsed. %4$@ waypoints remaining"; /* Accessibility label for the progress view, %1$@ is the waypoint name, %2$@ is the distance, %3$@ is the number of remaining waypoints, "Beacon set on home. 450 feet NW. 2 waypoints remaining." {NumberedPlaceholder="%1$@","%2$@","%3$@"} */ -"tour.progress.distance.accessibility" = "Beacon set on %1$@, %2$@, %3$@ waypoints remaining"; +"tour.progress.distance.accessibility" = "Beacon set on %1$@. %2$@. %3$@ waypoints remaining"; /* Accessibility label for the progress view, %1$@ is the waypoint name, %2$@ is the time elapsed, %3$@ is the number of remaining waypoints, "Beacon set on home. 02:31 elapsed. 2 waypionts remaining." {NumberedPlaceholder="%1$@","%2$@","%3$@"} */ "tour.progress.elapsed.accessibility" = "Beacon set on %1$@. %2$@ elapsed. %3$@ waypoints remaining"; @@ -1218,7 +1218,7 @@ "tour.progress.elapsed_distance.accessibility.singular" = "Beacon set on %1$@. %2$@. %3$@ elapsed. 1 waypoint remaining"; /* Accessibility label for the progress view, %1$@ is the waypoint name, %2$@ is the distance, "Beacon set on home. 450 feet NW. 1 waypoint remaining." {NumberedPlaceholder="%1$@","%2$@"} */ -"tour.progress.distance.accessibility.singular" = "Beacon set on %1$@, %2$@, 1 waypoint remaining"; +"tour.progress.distance.accessibility.singular" = "Beacon set on %1$@. %2$@. 1 waypoint remaining"; /* Accessibility label for the progress view, %1$@ is the waypoint name, %2$@ is the time elapsed, "Beacon set on home. 02:31 elapsed. 1 waypoint remaining." {NumberedPlaceholder="%1$@","%2$@"} */ "tour.progress.elapsed.accessibility.singular" = "Beacon set on %1$@. %2$@ elapsed. 1 waypoint remaining"; @@ -1239,7 +1239,7 @@ "waypoint.callout.button.title" = "Call out waypoint"; /* Voiceover hint to callout the current waypoint */ -"waypoint.callout.button.hint" = "Double tap to hear additional details."; +"waypoint.callout.button.hint" = "Double tap to hear additional details"; //------------------------------------------------------------------------------ // MARK: - Recommender @@ -1392,13 +1392,13 @@ "routes.sort.by_name" = "Sort by Name"; /* VoiceOver hint for a button that will cause the list of routes to be sorted by their names */ -"routes.sort.by_name.hint" = "Double tap to sort by name."; +"routes.sort.by_name.hint" = "Double tap to sort by name"; /* Text for a button that will cause the list of routes to be sorted by their distance from the user */ "routes.sort.by_distance" = "Sort by Distance"; /* VoiceOver hint for a button that will cause the list of routes to be sorted by their distance from the user */ -"routes.sort.by_distance.hint" = "Double tap to sort by distance."; +"routes.sort.by_distance.hint" = "Double tap to sort by distance"; /* Title of an alert for imporing routes */ "routes.import.alert.title" = "Route Error"; @@ -1459,7 +1459,7 @@ "markers.edit_screen.title.edit" = "Edit Marker"; /* Notification, Double tap to save this marker */ -"markers.edit_screen.done_button.acc_hint" = "Double tap to save this marker."; +"markers.edit_screen.done_button.acc_hint" = "Double tap to save this marker"; /* This is a label that is displayed on the Save Marker screen when the user is saving a new marker and adding it to a route. %@ is the name of the route. Example: "Saving to Route: Home to Grocery Store" (where "Home to Grocery Store" is the name of a route the user created {NumberedPlaceholder="%@"} */ "markers.edit_screen.route" = "Saving to Route: %@"; @@ -1544,13 +1544,13 @@ "search.view_markers" = "Markers & Routes"; /* Accessibility hint when the user selects the markers button on the home screen */ -"search.button.markers.accessibility_hint" = "Double tap to select or edit your saved markers and routes."; +"search.button.markers.accessibility_hint" = "Double tap to select or edit your saved markers and routes"; /* Accessibility hint when the user selects the nearby places button on the home screen */ -"search.button.nearby.accessibility_hint" = "Double tap to explore nearby restaurants, transit stops and more."; +"search.button.nearby.accessibility_hint" = "Double tap to explore nearby restaurants, transit stops and more"; /* Accessibility hint when the user selects the current location button on the home screen */ -"search.button.current_location.accessibility_hint" = "Double tap to preview, mark, or share your current location with a friend."; +"search.button.current_location.accessibility_hint" = "Double tap to preview, mark, or share your current location with a friend"; /* Search filter alert title */ "filter.alert_title" = "Filter places by category"; @@ -1562,10 +1562,10 @@ "filter.clear.capital" = "Clear Filter"; /* Accessibility hint for the "Clear Filter" button */ -"filter.clear.hint" = "Double tap to clear selected filter."; +"filter.clear.hint" = "Double tap to clear selected filter"; /* Search filter button description */ -"filter.double_tap_places_category" = "Double tap to filter places by category."; +"filter.double_tap_places_category" = "Double tap to filter places by category"; /* Filters, All Places */ "filter.all" = "All Places"; @@ -1672,7 +1672,7 @@ "callouts.action.more_info" = "More Info"; /* Callouts notification, A hardware device only has a certain amount of battery remaining, %1$@ name of device %2$@ percent of battery remaining, "Soundscape remote only has 20 percent battery remaining." {NumberedPlaceholder="%1$@", "%2$@"} */ -"callouts.hardware.low_battery" = "%1$@ only has %2$@ percent battery remaining."; +"callouts.hardware.low_battery" = "%1$@ only has %2$@ percent battery remaining"; /* Title for callouts that happen when departing a location */ "callouts.departure" = "Departure Callout"; @@ -1700,7 +1700,7 @@ "sleep.sleeping.message" = "Soundscape is currently sleeping. This prevents Soundscape from using Location Services or downloading data. This conserves battery when you are not using Soundscape. Tap the button below to wake up Soundscape."; /* Sleep Notification, Double tap to put Soundscape to sleep. Putting the app in an idle state for a period of time. {NumberedPlaceholder="Soundscape"} */ -"sleep.sleep.acc_hint" = "Double tap to put Soundscape to sleep."; +"sleep.sleep.acc_hint" = "Double tap to put Soundscape to sleep"; /* Sleep Button, restore the app from a sleep (idle) state when a user leaves his location. */ "sleep.wake_up_when_i_leave" = "Wake Up When I Leave"; @@ -2154,31 +2154,31 @@ "ui.action_button.my_location" = "My\nLocation"; /* Accessibility Notification, Double tap to hear about your current location. */ -"ui.action_button.my_location.acc_hint" = "Double tap to hear about your current location."; +"ui.action_button.my_location.acc_hint" = "Double tap to hear about your current location"; /* Similar to `callouts.nearby_markers`. Text that is shown in a small square button. It should be constrained to two lines with up to 8 characters each. Use "\n" to represent a new line character. {NumberedPlaceholder="\n"} */ "ui.action_button.nearby_markers" = "Nearby\nMarkers"; /* Accessibility Notification, Double tap to hear about nearby places that you have marked */ -"ui.action_button.nearby_markers.acc_hint" = "Double tap to hear about nearby places that you have marked."; +"ui.action_button.nearby_markers.acc_hint" = "Double tap to hear about nearby places that you have marked"; /* Similar to `help.orient.page_title`. Text that is shown in a small square button. It should be constrained to two lines with up to 8 characters each. Use "\n" to represent a new line character. {NumberedPlaceholder="\n"} */ "ui.action_button.around_me" = "Around\nMe"; /* Accessibility Notification, Double tap to hear about places in the four quadrants around you */ -"ui.action_button.around_me.acc_hint" = "Double tap to hear about places in the four quadrants around you."; +"ui.action_button.around_me.acc_hint" = "Double tap to hear about places in the four quadrants around you"; /* Similar to `help.explore.page_title`. Text that is shown in a small square button. It should be constrained to two lines with up to 8 characters each. Use "\n" to represent a new line character. {NumberedPlaceholder="\n"} */ "ui.action_button.ahead_of_me" = "Ahead\nof Me"; /* Accessibility Notification, Double tap to hear about places in front of you */ -"ui.action_button.ahead_of_me.acc_hint" = "Double tap to hear about places in front of you."; +"ui.action_button.ahead_of_me.acc_hint" = "Double tap to hear about places in front of you"; /* Title, Menu */ "ui.menu" = "Menu"; /* VoiceOver hint for the menu button */ -"ui.menu.hint" = "Double tap to open the menu."; +"ui.menu.hint" = "Double tap to open the menu"; /* Button title, Close Menu */ "ui.menu.close" = "Close Menu"; @@ -2249,7 +2249,7 @@ "poi_cell.accessibility_label.suggested_search" = "Suggested search: %@"; /* Accessibility hint for a search result that is a suggested search query, %@ suggested search query, "Double tap to search for: " {NumberedPlaceholder="%@"} */ -"poi_cell.accessibility_hint.suggested_search" = "Double tap to search for: %@."; +"poi_cell.accessibility_hint.suggested_search" = "Double tap to search for: %@"; /* Header for recent callouts section */ "poi_screen.header.recent.callouts" = "Recent Callouts"; @@ -2262,7 +2262,7 @@ "location_callout_cell.marked_location" = "Marked Location"; /* Location Callout Cell for the nearest road, %@ road name, "Nearest road, <27th Avenue West>" {NumberedPlaceholder="%@"} */ -"location_callout_cell.nearest_road" = "Nearest road, %@."; +"location_callout_cell.nearest_road" = "Nearest road, %@"; /* Location Callout Cell, Nearest road and beacon set on, %1$@ road name %2$@ location, "Nearest road, <27th Avenue West>. Beacon was set on ." {NumberedPlaceholder="%1$@", "%2$@"} */ "location_callout_cell.nearest_road.beacon_set_on" = "Nearest road, %1$@. Beacon was set on %2$@."; @@ -2347,7 +2347,7 @@ "devices.connect_headset.completed.test" = "Check Your Headphones"; /* VoiceOver hint for the button that allows users to test their newly connected headset, %@ is the type of headset, "Double tap to check your AirPods Pro". {NumberedPlaceholder="%@"} */ -"devices.connect_headset.completed.test.hint" = "Double tap to check your %@."; +"devices.connect_headset.completed.test.hint" = "Double tap to check your %@"; /* Title of the Check Headset screen */ "devices.test_headset.title" = "Headphones Check"; @@ -2588,7 +2588,7 @@ "text.cleaning_things" = "Cleaning things up…"; /* Notification, Double tap to repeat */ -"action.double_tap_to_repeat" = "Double tap to repeat."; +"action.double_tap_to_repeat" = "Double tap to repeat"; /* Title, Location. Used as screen title for a location detail page. Also used as the default name for markers when a more specific default cannot be generated. */ "location" = "Location"; @@ -2632,7 +2632,7 @@ "tutorial.markers.your_marker" = "your marker"; /* Tutorial notification, Double tap to mark this location */ -"tutorial.markers.mark_location.acc_hint" = "Double tap to mark this location."; +"tutorial.markers.mark_location.acc_hint" = "Double tap to mark this location"; //------------------------------------------------------------------------------ // MARK: Tutorials (Markers Texts) @@ -2670,7 +2670,7 @@ "tutorial.beacon.your_destination" = "your destination"; /* Tutorial notification, Double tap to use location selected for the beacon tutorial */ -"tutorial.beacon.mark_location.acc_hint" = "Double tap to use this location for the beacon tutorial."; +"tutorial.beacon.mark_location.acc_hint" = "Double tap to use this location for the beacon tutorial"; /* Tutorial notification, %@ is a location, "You selected as the location for the beacon." {NumberedPlaceholder="%@"} */ "tutorial.beacon.poi_selected" = "You have selected %@ as the location for the beacon."; @@ -2758,7 +2758,7 @@ "tutorial.beacons.text.Mute" = "If you need the app to be quiet for any reason, you can either use the mute beacon button or the sleep button on the home screen, or you can double tap with two fingers anywhere on the screen. A double tap with two fingers will stop any current callouts and will mute the audio beacon. Give it a try now."; /* Tutorial, Mute Beacon Repeat */ -"tutorial.beacons.text.MuteRepeat" = "Double tap with two fingers anywhere on the screen."; +"tutorial.beacons.text.MuteRepeat" = "Double tap with two fingers anywhere on the screen"; /* Tutorial, Beacon Wrap Up */ "tutorial.beacons.text.WrapUp" = "It looks like you've got it! If you want to repeat this tutorial, you can access it at any time on the Help and Tutorials screen. The beacon you've set for this tutorial will now be cleared and you will be returned to the previous screen."; @@ -2862,10 +2862,10 @@ "terms_of_use.accept_checkbox.acc_label" = "Accept Terms of Use"; /* Double tap to check the accept terms of use checkbox. Quotes written as \" */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to check the \"accept the terms of use\" checkbox."; +"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to check the \"accept the terms of use\" checkbox"; /* Double tap to uncheck the accept terms of use checkbox. Quotes written as \" */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to uncheck the \"accept the terms of use\" checkbox."; +"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to uncheck the \"accept the terms of use\" checkbox"; /* Terms of use accept checkbox has been checked */ "terms_of_use.accept_checkbox.on.acc_value" = "Checked"; @@ -2880,14 +2880,14 @@ "terms_of_use.accept.new_features" = "Accept"; /* Accessibility hint for the accept button that will be displayed as a new feature annoucement to existing users */ -"terms_of_use.accept.new_features.accessibility_hint" = "Double tap to accept and close announcements."; +"terms_of_use.accept.new_features.accessibility_hint" = "Double tap to accept and close announcements"; //------------------------------------------------------------------------------ // MARK: - First Launch //------------------------------------------------------------------------------ /* Button title accessibility hint. Quotes written as \" */ -"first_launch.get_started_button.off.acc_hint" = "You must check the \"accept the terms of use\" checkbox before you can press this button."; +"first_launch.get_started_button.off.acc_hint" = "You must check the \"accept the terms of use\" checkbox before you can press this button"; /* Notification, Welcome message */ "first_launch.welcome_text" = "Welcome! Before we get started, we need to go through some setup and ask for several permissions. Press the Next button to start."; @@ -2896,7 +2896,7 @@ "first_launch.welcome_audio_text" = "Welcome! Soundscape helps you stay aware of where you are and where you're going by using unique audio guidance and by calling out roads, intersections, and places as you approach them. Press the Next button to begin."; /* Notification, Permission is required */ -"first_launch.permission_required" = "This permission is required."; +"first_launch.permission_required" = "This permission is required"; /* Notification, Soundscap Language {NumberedPlaceholder="Soundscape"} */ "first_launch.soundscape_language" = "Soundscape Language"; @@ -2974,7 +2974,7 @@ "first_launch.callouts.listen.accessibility_label" = "Listen"; /* Accessibility hint for button that plays example callouts {NumberedPlaceholder="Soundscape"} */ -"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk."; +"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk"; /* Example callout for a coffee shop / cafe */ "first_launch.callouts.example.1" = "Cafe"; @@ -2998,7 +2998,7 @@ "first_launch.permissions.motion" = "Motion & Fitness"; /* Text to indicate that a permission is required */ -"first_launch.permissions.required" = "This permission is required."; +"first_launch.permissions.required" = "This permission is required"; /* Title text for screen to choose an audio beacon */ "first_launch.beacon.title" = "Choose an Audio Beacon"; @@ -3435,7 +3435,7 @@ "banner.custom_behavior.scavenger_hunt" = "Scavenger hunt is active."; /* Scavenger Hunt Banner, Hint */ -"banner.custom_behavior.scavenger_hunt.hint" = "Double tap to read about or pause the scavenger hunt."; +"banner.custom_behavior.scavenger_hunt.hint" = "Double tap to read about or pause the scavenger hunt"; /* Default banner when offline */ "banner.offline_default.message" = "Soundscape is working offline. Learn more"; @@ -3500,7 +3500,7 @@ "whats_new.1_2_0.2.title" = "Categories in Places Nearby"; /* Description of the categories in places nearby feature */ -"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as public transport, Food & Drink, etc."; +"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as Public Transit, Food & Drink, etc."; /* Title of the Bose Frames support feature */ "whats_new.1_3_0.0.title" = "Bose Frames Support"; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 063c91c1f..a5eba7ddb 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -359,7 +359,7 @@ /* */ -"settings.clear_cache.alert_message" = "Soundscape almacena datos de mapas para reducir el uso de datos móviles y el consumo de la batería. La eliminación de los datos almacenados requerirá que Soundscape vuelva a cargar los datos."; +"settings.clear_cache.alert_message" = "Soundscape almacena datos de mapas para reducir el uso de datos móviles y el consumo de la batería. Eliminar los datos almacenados requerirá que Soundscape vuelva a cargar los datos."; /* */ @@ -555,7 +555,7 @@ /* */ -"voice.apple.preview_hint" = "Pulsa dos veces la voz para seleccionarla y reproducir una muestra."; +"voice.apple.preview_hint" = "Pulsa dos veces la voz para seleccionarla y reproducir una muestra"; /* */ @@ -631,11 +631,11 @@ /* */ -"troubleshooting.check_audio.hint" = "Pulsa dos veces para comprobar el estado de los auriculares."; +"troubleshooting.check_audio.hint" = "Pulsa dos veces para comprobar el estado de los auriculares"; /* */ -"troubleshooting.check_audio.explanation" = "Pulsa en este botón para conocer el estado de los auriculares que usas con Soundscape."; +"troubleshooting.check_audio.explanation" = "Pulsa este botón para oír sobre el estado de los auriculares que usas con Soundscape."; /* */ @@ -643,7 +643,7 @@ /* */ -"troubleshooting.cache.hint" = "Pulsa dos veces para eliminar y volver a cargar datos de mapas almacenados."; +"troubleshooting.cache.hint" = "Pulsa dos veces para eliminar y volver a cargar datos de mapas almacenados"; /* */ @@ -671,11 +671,11 @@ /* */ -"settings.new_feature.accept_button.acc_label" = "Pulsa dos veces para cerrar anuncios."; +"settings.new_feature.accept_button.acc_label" = "Pulsa dos veces para cerrar anuncios"; /* */ -"settings.new_feature.accept_button.acc_hint" = "Pulsa dos veces para ver el anuncio de la siguiente actualización."; +"settings.new_feature.accept_button.acc_hint" = "Pulsa dos veces para ver el anuncio de la siguiente actualización"; /* */ @@ -763,7 +763,7 @@ /* */ -"beacon.action.remove_beacon.double_tap.acc_hint" = "Pulsa dos veces para quitar la señal de audio actual."; +"beacon.action.remove_beacon.double_tap.acc_hint" = "Pulsa dos veces para quitar la señal de audio actual"; /* */ @@ -771,7 +771,7 @@ /* */ -"beacon.action.mute_beacon.acc_hint" = "Pulsa dos veces para silenciar la señal de audio."; +"beacon.action.mute_beacon.acc_hint" = "Pulsa dos veces para silenciar la señal de audio"; /* */ @@ -779,7 +779,7 @@ /* */ -"beacon.action.unmute_beacon.acc_hint" = "Pulsa dos veces para reactivar la señal de audio."; +"beacon.action.unmute_beacon.acc_hint" = "Pulsa dos veces para reactivar la señal de audio"; /* */ @@ -791,7 +791,7 @@ /* */ -"beacon.action.mute_unmute_beacon.acc_hint" = "Pulsa dos veces para silenciar o reactivar la señal de audio."; +"beacon.action.mute_unmute_beacon.acc_hint" = "Pulsa dos veces para silenciar o reactivar la señal de audio"; /* */ @@ -799,7 +799,7 @@ /* */ -"beacon.action.view_details.acc_hint.details" = "Pulsa dos veces para ver detalles adicionales."; +"beacon.action.view_details.acc_hint.details" = "Pulsa dos veces para ver detalles adicionales"; /* */ @@ -843,7 +843,7 @@ /* */ -"preview.content.edge.text.accessibility_hint" = "Pulsa dos veces para pasar al siguiente cruce."; +"preview.content.edge.text.accessibility_hint" = "Pulsa dos veces para pasar al siguiente cruce"; /* */ @@ -855,7 +855,7 @@ /* */ -"preview.go_back.accessibility_text" = "Pulsa dos veces para volver a tu cruce anterior."; +"preview.go_back.accessibility_text" = "Pulsa dos veces para volver a tu cruce anterior"; /* */ @@ -863,7 +863,7 @@ /* */ -"preview.search.accessibility_hint" = "Pulsa dos veces para buscar o examinar lugares cercanos."; +"preview.search.accessibility_hint" = "Pulsa dos veces para buscar o examinar lugares cercanos"; /* */ @@ -967,15 +967,15 @@ /* */ -"preview.include_unnamed_roads.hint.off" = "Pulsa dos veces para incluir carreteras sin nombre durante la vista previa de calle de Soundscape."; +"preview.include_unnamed_roads.hint.off" = "Pulsa dos veces para incluir carreteras sin nombre durante la vista previa de calle de Soundscape"; /* */ -"preview.include_unnamed_roads.hint.on" = "Pulsa dos veces para excluir carreteras sin nombre durante la vista previa de calle de Soundscape."; +"preview.include_unnamed_roads.hint.on" = "Pulsa dos veces para excluir carreteras sin nombre durante la vista previa de calle de Soundscape"; /* */ -"preview.tutorial.done.hint" = "Pulsa dos veces para salir del tutorial."; +"preview.tutorial.done.hint" = "Pulsa dos veces para salir del tutorial"; /* */ @@ -999,7 +999,7 @@ /* */ -"preview.tutorial.content.3" = "En cada cruce, puedes usar el teléfono de nuevo para elegir qué carretera recorrer o puedes explorar tu entorno inmediato con los botones habituales de Soundscape de la parte inferior de la pantalla. Puedes pulsar en \"Explorar cerca\" para iniciar la señal de audio en cualquier punto de interés, cambiar tu ubicación o simplemente explorar el área con mayor detalle."; +"preview.tutorial.content.3" = "En cada cruce, puedes usar el teléfono de nuevo para elegir qué carretera recorrer, o puedes explorar tu entorno inmediato con los botones habituales de Soundscape de la parte inferior de la pantalla. Puedes pulsar en \"Explorar cerca\" para iniciar la señal de audio en cualquier punto de interés, cambiar tu ubicación o simplemente explorar el área con mayor detalle."; /* */ @@ -1015,7 +1015,7 @@ /* */ -"location_detail.title.waypoint" = "Detalles de punto de ruta"; +"location_detail.title.waypoint" = "Detalles del punto de ruta"; /* */ @@ -1023,35 +1023,35 @@ /* */ -"location_detail.action.beacon.hint" = "Pulsa dos veces para establecer una señal de audio en esta ubicación."; +"location_detail.action.beacon.hint" = "Pulsa dos veces para establecer una señal de audio en esta ubicación"; /* */ -"location_detail.action.beacon.hint.disabled" = "Establecer una nueva señal de audio está deshabilitado mientras la guía de ruta está activa."; +"location_detail.action.beacon.hint.disabled" = "Establecer una nueva señal de audio está deshabilitado mientras la guía de ruta está activa"; /* */ -"location_detail.action.save.hint" = "Pulsa dos veces para guardar esta ubicación como marcador."; +"location_detail.action.save.hint" = "Pulsa dos veces para guardar esta ubicación como marcador"; /* */ -"location_detail.action.edit.hint" = "Pulsa dos veces para editar el marcador."; +"location_detail.action.edit.hint" = "Pulsa dos veces para editar el marcador"; /* */ -"location_detail.action.share.hint" = "Pulsa dos veces para compartir esta ubicación."; +"location_detail.action.share.hint" = "Pulsa dos veces para compartir esta ubicación"; /* */ -"location_detail.action.preview.hint" = "Pulsa dos veces para iniciar la vista previa en esta ubicación."; +"location_detail.action.preview.hint" = "Pulsa dos veces para iniciar la vista previa en esta ubicación"; /* */ -"location_detail.action.preview.hint.disabled" = "La vista previa de calle está deshabilitada mientras la guía de la ruta está activa."; +"location_detail.action.preview.hint.disabled" = "La vista previa de calle está deshabilitada mientras la guía de la ruta está activa"; /* */ -"location_detail.action.directions.hint" = "Pulsa dos veces para abrir esta ubicación en una aplicación de mapas externa."; +"location_detail.action.directions.hint" = "Pulsa dos veces para abrir esta ubicación en una aplicación de mapas externa"; /* */ @@ -1063,7 +1063,7 @@ /* */ -"location.select.hint" = "Pulsa dos veces para seleccionar esta ubicación."; +"location.select.hint" = "Pulsa dos veces para seleccionar esta ubicación"; /* */ @@ -1083,7 +1083,7 @@ /* */ -"location_detail.map.view.hint" = "Edita para seleccionar una nueva ubicación."; +"location_detail.map.view.hint" = "Editar para seleccionar una nueva ubicación"; /* */ @@ -1091,7 +1091,7 @@ /* */ -"location_detail.map.edit.hint" = "Mueve el mapa a la ubicación correcta."; +"location_detail.map.edit.hint" = "Mover el mapa a la ubicación correcta"; /* */ @@ -1099,7 +1099,7 @@ /* */ -"location_detail.map.edit.compass.accessibility_hint" = "Pulsa dos veces para posicionar el marcador en la dirección en que apunta el teléfono. Usa acciones para posicionar en una dirección diferente."; +"location_detail.map.edit.compass.accessibility_hint" = "Pulsa dos veces para posicionar el marcador en la dirección en la que apunta el teléfono. Usa acciones para posicionar en una dirección diferente."; /* */ @@ -1147,7 +1147,7 @@ /* */ -"location_detail.map.edit.accessibility.beacon.callout" = "Iniciando señal para realizar el seguimiento de la ubicación del marcador. Posicionando, %@ de la ubicación original."; +"location_detail.map.edit.accessibility.beacon.callout" = "Iniciando señal para realizar el seguimiento de la ubicación del marcador. Posicionando, %@ de la ubicación original"; /* */ @@ -1155,15 +1155,15 @@ /* */ -"location_detail.add_waypoint.existing.hint" = "Pulsa dos veces para eliminar este marcador de tu ruta."; +"location_detail.add_waypoint.existing.hint" = "Pulsa dos veces para eliminar este marcador de tu ruta"; /* */ -"location_detail.add_waypoint.new.hint" = "Pulsa dos veces para agregar este marcador a tu ruta."; +"location_detail.add_waypoint.new.hint" = "Pulsa dos veces para agregar este marcador a tu ruta"; /* */ -"location_detail.add_waypoint.marker.hint" = "Pulsa dos veces para crear un marcador y agregarlo como punto de referencia."; +"location_detail.add_waypoint.marker.hint" = "Pulsa dos veces para crear un marcador y agregarlo como punto de referencia"; /* */ @@ -1187,35 +1187,35 @@ /* */ -"route_detail.action.start_route.hint" = "Pulsa dos veces para iniciar esta ruta."; +"route_detail.action.start_route.hint" = "Pulsa dos veces para iniciar esta ruta"; /* */ -"route_detail.action.start_route.disabled.hint" = "Añade puntos a la ruta antes de iniciarla."; +"route_detail.action.start_route.disabled.hint" = "Añadir puntos a la ruta antes de iniciarla"; /* */ -"route_detail.action.stop_route.hint" = "Pulsa dos veces para detener esta ruta."; +"route_detail.action.stop_route.hint" = "Pulsa dos veces para detener esta ruta"; /* */ -"route_detail.action.start_event.hint" = "Pulsa dos veces para iniciar esta actividad."; +"route_detail.action.start_event.hint" = "Pulsa dos veces para iniciar esta actividad"; /* */ -"route_detail.action.stop_event.hint" = "Pulsa dos veces para detener esta actividad y guardar el progreso."; +"route_detail.action.stop_event.hint" = "Pulsa dos veces para detener esta actividad y guardar el progreso"; /* */ -"route_detail.action.reset.hint" = "Pulsa dos veces para restablecer esta actividad y descargar las actualizaciones disponibles."; +"route_detail.action.reset.hint" = "Pulsa dos veces para restablecer esta actividad y descargar las actualizaciones disponibles"; /* */ -"route_detail.action.share.hint" = "Pulsa dos veces para compartir esta ruta."; +"route_detail.action.share.hint" = "Pulsa dos veces para compartir esta ruta"; /* */ -"route_detail.action.edit.hint" = "Pulsa dos veces para editar esta ruta."; +"route_detail.action.edit.hint" = "Pulsa dos veces para editar esta ruta"; /* */ @@ -1223,7 +1223,7 @@ /* */ -"route_detail.action.create.hint" = "Pulsa dos veces para crear una nueva ruta."; +"route_detail.action.create.hint" = "Pulsa dos veces para crear una nueva ruta"; /* */ @@ -1271,11 +1271,11 @@ /* */ -"route.end.completed.summary" = "Puntos de ruta alcanzados de %@・Último punto de ruta cerca"; +"route.end.completed.summary" = "%@ puntos de ruta alcanzados・Último punto de ruta cerca"; /* */ -"route.end.completed.summary.accessibility" = "Puntos de ruta alcanzados de %@, último punto de ruta cerca"; +"route.end.completed.summary.accessibility" = "%@ puntos de ruta alcanzados, último punto de ruta cerca"; /* */ @@ -1295,7 +1295,7 @@ /* */ -"route_detail.action.previous.hint" = "Pulsa dos veces para establecer la señal en el punto de ruta anterior."; +"route_detail.action.previous.hint" = "Pulsa dos veces para establecer la señal en el punto de ruta anterior"; /* */ @@ -1303,7 +1303,7 @@ /* */ -"route_detail.action.next.hint" = "Pulsa dos veces para establecer la señal en el siguiente punto de ruta."; +"route_detail.action.next.hint" = "Pulsa dos veces para establecer la señal en el siguiente punto de ruta"; /* */ @@ -1403,7 +1403,7 @@ /* */ -"tour.progress.distance.accessibility" = "Señal establecida en %1$@, %2$@, %3$@ puntos de ruta restantes"; +"tour.progress.distance.accessibility" = "Señal establecida en %1$@. %2$@. %3$@ puntos de ruta restantes"; /* */ @@ -1419,11 +1419,11 @@ /* */ -"tour.progress.distance.accessibility.singular" = "Señal establecida en %1$@, %2$@, 1 punto restante"; +"tour.progress.distance.accessibility.singular" = "Señal establecida en %1$@. %2$@. 1 punto de ruta restante"; /* */ -"tour.progress.elapsed.accessibility.singular" = "Señal establecida en %1$@. Han transcurrido %2$@. 1 punto de ruta restante"; +"tour.progress.elapsed.accessibility.singular" = ";Señal establecida en %1$@. Han transcurrido %2$@. 1 punto de ruta restante"; /* */ @@ -1447,7 +1447,7 @@ /* */ -"waypoint.callout.button.hint" = "Pulsa dos veces para escuchar información adicional."; +"waypoint.callout.button.hint" = "Pulsa dos veces para escuchar información adicional"; /* */ @@ -1559,7 +1559,7 @@ /* */ -"url_resource.alert.route.import_existing.message" = "¿Deseas reemplazarla? Al sustituir esta ruta también se reemplazarán los marcadores usados en esta ruta."; +"url_resource.alert.route.import_existing.message" = "¿Deseas reemplazarla? Al sustituir esta ruta, también se reemplazarán los marcadores usados en esta ruta."; /* */ @@ -1591,7 +1591,7 @@ /* */ -"routes.no_routes.hint.2" = "Mientras te encuentres en una ruta con Soundscape, se te informará a la llegada a cada uno de los puntos de ruta y la señal de audio avanzará automáticamente hasta el siguiente punto de ruta."; +"routes.no_routes.hint.2" = "Mientras te encuentres en una ruta con Soundscape, se te informará a la llegada a cada uno de los puntos de ruta, y la señal de audio avanzará automáticamente hasta el siguiente punto de ruta."; /* */ @@ -1619,7 +1619,7 @@ /* */ -"routes.sort.by_name.hint" = "Pulsa dos veces para ordenar por nombre."; +"routes.sort.by_name.hint" = "Pulsa dos veces para ordenar por nombre"; /* */ @@ -1627,7 +1627,7 @@ /* */ -"routes.sort.by_distance.hint" = "Pulsa dos veces para ordenar por distancia."; +"routes.sort.by_distance.hint" = "Pulsa dos veces para ordenar por distancia"; /* */ @@ -1699,7 +1699,7 @@ /* */ -"markers.edit_screen.done_button.acc_hint" = "Pulsa dos veces para guardar este marcador."; +"markers.edit_screen.done_button.acc_hint" = "Pulsa dos veces para guardar este marcador"; /* */ @@ -1807,15 +1807,15 @@ /* */ -"search.button.markers.accessibility_hint" = "Pulsa dos veces para seleccionar o editar tus marcadores y rutas guardados."; +"search.button.markers.accessibility_hint" = "Pulsa dos veces para seleccionar o editar tus marcadores y rutas guardados"; /* */ -"search.button.nearby.accessibility_hint" = "Pulsa Dos Veces para explorar restaurantes cercanos, paradas y más."; +"search.button.nearby.accessibility_hint" = "Pulsa Dos Veces para explorar restaurantes cercanos, paradas y más"; /* */ -"search.button.current_location.accessibility_hint" = "Pulsa dos veces para obtener una vista previa, marcar o compartir tu ubicación actual con un amigo."; +"search.button.current_location.accessibility_hint" = "Pulsa dos veces para obtener una vista previa, marcar o compartir tu ubicación actual con un amigo"; /* */ @@ -1831,11 +1831,11 @@ /* */ -"filter.clear.hint" = "Pulsa dos veces para borrar el filtro seleccionado."; +"filter.clear.hint" = "Pulsa dos veces para borrar el filtro seleccionado"; /* */ -"filter.double_tap_places_category" = "Pulsa dos veces para filtrar lugares por categoría."; +"filter.double_tap_places_category" = "Pulsa dos veces para filtrar lugares por categoría"; /* */ @@ -1903,7 +1903,7 @@ /* */ -"callouts.mobility.info" = "Información de transporte e intersecciones"; +"callouts.mobility.info" = "Información de transporte y cruces"; /* */ @@ -1955,7 +1955,7 @@ /* */ -"callouts.hardware.low_battery" = "%1$@ solo tiene un %2$@ por ciento restante."; +"callouts.hardware.low_battery" = "%1$@ solo tiene un %2$@ por ciento restante"; /* */ @@ -1979,15 +1979,15 @@ /* */ -"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Esto usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa en el botón siguiente para reactivar ahora."; +"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Esto usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa el botón siguiente para reactivar ahora."; /* */ -"sleep.sleeping.message" = "Soundscape se encuentra actualmente en modo de suspensión. Esto evita que Soundscape use Localización o descargue datos. Esto ahorra batería cuando no se usa Soundscape. Pulsa en el botón siguiente para reactivar Soundscape."; +"sleep.sleeping.message" = "Soundscape se encuentra actualmente en modo de suspensión. Esto evita que Soundscape use Localización o descargue datos y ahorra batería cuando no se usa Soundscape. Pulsa el botón siguiente para reactivar Soundscape."; /* */ -"sleep.sleep.acc_hint" = "Pulsa dos veces para poner en suspensión a Soundscape."; +"sleep.sleep.acc_hint" = "Pulsa dos veces para poner Soundscape en suspensión"; /* */ @@ -2107,7 +2107,7 @@ /* */ -"directions.roundabout_with_exits_distance" = "Rotonda con %1$@ salidas, a %2$@ de distancia"; +"directions.roundabout_with_exits_distance" = "Rotonda con %1$@ salidas a %2$@ de distancia"; /* */ @@ -2554,7 +2554,7 @@ /* */ -"ui.action_button.my_location.acc_hint" = "Pulsa dos veces para conocer tu ubicación actual."; +"ui.action_button.my_location.acc_hint" = "Pulsa dos veces para conocer tu ubicación actual"; /* */ @@ -2562,7 +2562,7 @@ /* */ -"ui.action_button.nearby_markers.acc_hint" = "Pulsa dos veces para oír hablar de los lugares cercanos que has marcado."; +"ui.action_button.nearby_markers.acc_hint" = "Pulsa dos veces para oír hablar de los lugares cercanos que has marcado"; /* */ @@ -2570,7 +2570,7 @@ /* */ -"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares en los cuatro cuadrantes que te rodean."; +"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares en los cuatro cuadrantes que te rodean"; /* */ @@ -2578,7 +2578,7 @@ /* */ -"ui.action_button.ahead_of_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares que se encuentran delante."; +"ui.action_button.ahead_of_me.acc_hint" = "Pulsa dos veces para oír hablar de los lugares que se encuentran delante"; /* */ @@ -2586,7 +2586,7 @@ /* */ -"ui.menu.hint" = "Pulsa dos veces para abrir el menú."; +"ui.menu.hint" = "Pulsa dos veces para abrir el menú"; /* */ @@ -2666,7 +2666,7 @@ /* */ -"poi_cell.accessibility_hint.suggested_search" = "Pulsa dos veces para buscar: %@."; +"poi_cell.accessibility_hint.suggested_search" = "Pulsa dos veces para buscar: %@"; /* */ @@ -2678,7 +2678,7 @@ /* */ -"location_callout_cell.nearest_road" = "Carretera más cercana, %@."; +"location_callout_cell.nearest_road" = "Carretera más cercana, %@"; /* */ @@ -2710,7 +2710,7 @@ /* */ -"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo.\n\nPulsa en el botón siguiente para conectar un dispositivo."; +"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo.\n\nPulsa el botón siguiente para conectar un dispositivo."; /* */ @@ -2718,7 +2718,7 @@ /* */ -"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Por favor asegúrate de que tus auriculares están encendidos y cerca de tu teléfono."; +"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Por favor, asegúrate de que tus auriculares están encendidos y cerca de tu teléfono."; /* */ @@ -2742,7 +2742,7 @@ /* */ -"devices.connect_headset.unsupported_firmware" = "Los cascos de realidad aumentada deben actualizarse antes de que puedan conectarse a Soundscape. Ve a la aplicación Cortana para actualizar los auriculares."; +"devices.connect_headset.unsupported_firmware" = "Tus AR Headphones deben actualizarse antes de que puedan conectarse a Soundscape. Ve a la aplicación Cortana para actualizar los auriculares."; /* */ @@ -2778,7 +2778,7 @@ /* */ -"devices.connect_headset.completed.test.hint" = "Pulsa dos veces para comprobar los %@."; +"devices.connect_headset.completed.test.hint" = "Pulsa dos veces para comprobar los %@"; /* */ @@ -2786,7 +2786,7 @@ /* */ -"devices.test_headset.explanation" = "Hemos colocado una señal de audio a tu derecha. Escucha dónde se encuentra y gira la cabeza hacia ella. Observa cómo puedes hacer esto incluso con el teléfono en el bolsillo. Cuando hayas terminado, pulsa en el botón siguiente para volver a Soundscape y disfruta de tu próximo paseo con tus nuevos auriculares con seguimiento de cabeza."; +"devices.test_headset.explanation" = "Hemos colocado una señal de audio a tu derecha. Escucha dónde se encuentra y gira la cabeza hacia ella. Observa cómo puedes hacer esto incluso con el teléfono en el bolsillo. Cuando hayas terminado, pulsa el botón siguiente para volver a Soundscape y disfruta de tu próximo paseo con tus nuevos auriculares con seguimiento de cabeza."; /* */ @@ -2890,7 +2890,7 @@ /* */ -"behavior.experiences.reset.prompt" = "Al restablecer esta actividad se eliminará tu progreso actual y te permitirá iniciarla de nuevo. También puedes buscar actualizaciones. De esta manera, se descargará información actualizada para esta actividad si hay actualizaciones disponibles."; +"behavior.experiences.reset.prompt" = "Restablecer esta actividad eliminará tu progreso actual y te permitirá iniciar la actividad de nuevo. También puedes buscar actualizaciones. De esta manera, se descargará información actualizada para esta actividad si hay actualizaciones disponibles."; /* */ @@ -3038,7 +3038,7 @@ /* */ -"icloud.kv_store.quota_violation_alert.message" = "El almacenamiento de iCloud para esta aplicación está completo. Para crear un nuevo marcador, necesitarás liberar espacio quitando algunos de tus marcadores existentes."; +"icloud.kv_store.quota_violation_alert.message" = "El almacenamiento de iCloud para esta aplicación está lleno. Para crear un nuevo marcador, necesitarás liberar espacio quitando algunos de tus marcadores existentes."; /* */ @@ -3062,7 +3062,7 @@ /* */ -"action.double_tap_to_repeat" = "Pulsa dos veces para repetir."; +"action.double_tap_to_repeat" = "Pulsa dos veces para repetir"; /* */ @@ -3110,7 +3110,7 @@ /* */ -"tutorial.markers.mark_location.acc_hint" = "Pulsa dos veces para marcar esta ubicación."; +"tutorial.markers.mark_location.acc_hint" = "Pulsa dos veces para marcar esta ubicación"; /* */ @@ -3130,7 +3130,7 @@ /* */ -"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará y volverás a la pantalla anterior."; +"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y volverás a la pantalla anterior."; /* */ @@ -3150,7 +3150,7 @@ /* */ -"tutorial.beacon.mark_location.acc_hint" = "Pulsa dos veces para usar esta ubicación para el tutorial de señales."; +"tutorial.beacon.mark_location.acc_hint" = "Pulsa dos veces para usar esta ubicación para el tutorial de señales"; /* */ @@ -3186,7 +3186,7 @@ /* */ -"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla mirando hacia arriba y con la parte superior del teléfono señalando justo delante de ti."; +"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla mirando hacia arriba y con la parte superior del teléfono apuntando justo delante de ti."; /* */ @@ -3202,7 +3202,7 @@ /* */ -"tutorial.beacons.text.HoldingPhone.great" = "¡Excelente! Mantener el teléfono en posición horizontal de esta manera solo es necesario cuando no te mueves. Mientras camines, puedes colocar el teléfono en un bolso o un bolsillo al que puedas tener fácil acceso."; +"tutorial.beacons.text.HoldingPhone.great" = "¡Excelente! Mantener el teléfono en posición horizontal de esta manera solo es necesario cuando no te mueves. Mientras caminas, puedes colocar el teléfono en un bolso o un bolsillo al que puedas tener fácil acceso."; /* */ @@ -3230,11 +3230,11 @@ /* */ -"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido normal de la señal. Eso significa que estás mirando directamente hacia @!destination!!."; +"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente, oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido normal de la señal. Eso significa que estás mirando directamente hacia @!destination!!."; /* */ -"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; +"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal, manteniendo todavía el teléfono en posición horizontal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; /* */ @@ -3254,7 +3254,7 @@ /* */ -"tutorial.beacons.text.HomeScreen" = "La información de la distancia también aparece en la pantalla principal junto con la dirección de la ubicación de la señal si la tenemos. Soundscape te notificará cuando te acerques a la ubicación de la señal y cuando te encuentres en ella la señal de audio se silenciará."; +"tutorial.beacons.text.HomeScreen" = "La información de la distancia también aparece en la pantalla principal junto con la dirección de la ubicación de la señal si la tenemos. Soundscape te notificará cuando te acerques a la ubicación de la señal, y cuando te encuentres en ella la señal de audio se silenciará."; /* */ @@ -3262,11 +3262,11 @@ /* */ -"tutorial.beacons.text.MuteRepeat" = "Pulsa dos veces con dos dedos en cualquier lugar de la pantalla."; +"tutorial.beacons.text.MuteRepeat" = "Pulsa dos veces con dos dedos en cualquier lugar de la pantalla"; /* */ -"tutorial.beacons.text.WrapUp" = "¡Parece que lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que ha establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.beacons.text.WrapUp" = "¡Parece que ya lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que ha establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3294,7 +3294,7 @@ /* */ -"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación Ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación Ajustes de iOS tienes que ir a Accesibilidad > Contenido leído > Voces y pulsar en una voz. En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: pulsa en \"Ajustes\" desde el menú principal y, a continuación, en \"Ajustes Generales\", selecciona \"Voz\"."; +"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación Ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación Ajustes de iOS, tienes que ir a Accesibilidad > Contenido leído > Voces y pulsar en una voz. En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: pulsa en \"Ajustes\" desde el menú principal y, a continuación, en \"Ajustes Generales\", selecciona \"Voz\"."; /* */ @@ -3386,11 +3386,11 @@ /* */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"aceptar los términos de uso\"."; +"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"aceptar los términos de uso\""; /* */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"aceptar los términos de uso\"."; +"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"aceptar los términos de uso\""; /* */ @@ -3410,11 +3410,11 @@ /* */ -"terms_of_use.accept.new_features.accessibility_hint" = "Pulsa dos veces para aceptar y cerrar los anuncios."; +"terms_of_use.accept.new_features.accessibility_hint" = "Pulsa dos veces para aceptar y cerrar los anuncios"; /* */ -"first_launch.get_started_button.off.acc_hint" = "Debes marcar la casilla \"aceptar los términos de uso\" antes de poder pulsar este botón."; +"first_launch.get_started_button.off.acc_hint" = "Debes marcar la casilla \"aceptar los términos de uso\" antes de poder pulsar este botón"; /* */ @@ -3426,7 +3426,7 @@ /* */ -"first_launch.permission_required" = "Este permiso es obligatorio."; +"first_launch.permission_required" = "Este permiso es obligatorio"; /* */ @@ -3474,7 +3474,7 @@ /* */ -"first_launch.setting_off_way.text" = "Guarda el teléfono y camina. Soundscape te ayudará a estar informado de tu ubicación y te avisará de carreteras, cruces y puntos de referencia conforme te acerques a ellos. Los avisos se pueden configurar en los ajustes."; +"first_launch.setting_off_way.text" = "Guarda el teléfono y camina. Soundscape te ayudará a estar informado de dónde te encuentras avisando de carreteras, cruces y puntos de referencia conforme te acerques a ellos. Los avisos se pueden configurar en los ajustes."; /* */ @@ -3530,7 +3530,7 @@ /* */ -"first_launch.callouts.listen.accessibility_hint" = "Pulsa dos veces para escuchar un ejemplo de lo que Soundscape podría decir en tu próximo paseo."; +"first_launch.callouts.listen.accessibility_hint" = "Pulsa dos veces para escuchar un ejemplo de lo que Soundscape podría decir en tu próximo paseo"; /* */ @@ -3562,7 +3562,7 @@ /* */ -"first_launch.permissions.required" = "Este permiso es obligatorio."; +"first_launch.permissions.required" = "Este permiso es obligatorio"; /* */ @@ -3594,7 +3594,7 @@ /* */ -"first_launch.beacon.callout.standard" = "Colocando la señal a tu derecha. Gira el teléfono para seguir su sonido y experimentar el audio espacial de la señal."; +"first_launch.beacon.callout.standard" = "Colocando la señal a tu derecha. Gira el teléfono para seguir su sonido y probar el audio espacial de la señal."; /* */ @@ -3622,7 +3622,7 @@ /* */ -"first_launch.prompt.message" = "Estás listo para tu primer paseo con Soundscape. Para probarlo ahora, simplemente elige un destino cercano, inicia la señal de audio y lo escucharás en la dirección de tu destino."; +"first_launch.prompt.message" = "Estás listo para tu primer paseo con Soundscape. Para probarlo ahora, simplemente elige un destino cercano, inicia la señal de audio y la escucharás en la dirección de tu destino."; /* */ @@ -3638,11 +3638,11 @@ /* */ -"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia conocido mientras exploras una zona nueva o cuando vas a algún lugar y deseas estar informado de tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar donde te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes, e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas."; +"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia conocido mientras exploras una zona nueva o cuando vas a algún lugar y deseas estar informado de tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar donde te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas."; /* */ -"help.text.destination_beacons.how.1" = "Para establecer una señal:
Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando en uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la Ubicación\", selecciona el botón \"Iniciar Señal de Audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerán ahora en la pantalla principal."; +"help.text.destination_beacons.how.1" = "Para establecer una señal:
Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la Ubicación\", selecciona el botón \"Iniciar Señal de Audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerán ahora en la pantalla principal."; /* */ @@ -3654,7 +3654,7 @@ /* */ -"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos que se encuentran a tu alrededor conforme te acercas a ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobús e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\" y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; +"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos que se encuentran a tu alrededor conforme te acercas a ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobús e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\", y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; /* */ @@ -3662,23 +3662,23 @@ /* */ -"help.text.automatic_callouts.when.2" = "Caminar hasta una ubicación específica:
cuando te dirijas a una ubicación concreta, los avisos automáticos para cruces pueden ser especialmente útiles. Los avisos de cruces te informan de la disposición de los cruces cuando te aproximas a ellos y confirman la carretera en la que te encuentras al salir de ellos."; +"help.text.automatic_callouts.when.2" = "Caminar hasta una ubicación específica:
cuando te dirijas a una ubicación concreta, los avisos automáticos para cruces pueden ser especialmente útiles. Los avisos de cruces te informan de la disposición de los cruces cuando te aproximas a ellos, y confirman la carretera en la que te encuentras al salir de ellos."; /* */ -"help.text.automatic_callouts.when.3" = "Cuando necesites silencio:
cuando estés a punto de cruzar una carretera o simplemente necesites que la aplicación esté en silencio, puedes desactivar los avisos. Cuando los avisos estén desactivados, la aplicación solo te dará información si pulsas manualmente en uno de los botones \"Mi ubicación\", \"Marcadores cercanos\", \"Alrededor de mí\" o \"Delante de mí\"."; +"help.text.automatic_callouts.when.3" = "Cuando necesites silencio:
cuando estés a punto de cruzar una carretera o simplemente necesites que la aplicación esté en silencio, puedes desactivar los avisos. Cuando los avisos estén desactivados, la aplicación solo te dará información si pulsas manualmente uno de los botones \"Mi ubicación\", \"Marcadores cercanos\", \"Alrededor de mí\" o \"Delante de mí\"."; /* */ -"help.text.automatic_callouts.how.1" = "Activación o desactivación de avisos:
Al desactivar los avisos, se silenciará la aplicación. Los avisos se pueden activar o desactivar yendo a la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", y, a continuación, pulsando en el botón \"Permitir Avisos\". También puedes activar o desactivar los avisos con el comando \"saltar adelante\" (pulsa dos veces y mantén pulsado) si tus auriculares tienen botones de control multimedia. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla principal para evitar que Soundscape haga avisos hasta que lo reactives."; +"help.text.automatic_callouts.how.1" = "Activación o desactivación de avisos:
Desactivar los avisos silenciará la aplicación. Los avisos se pueden activar o desactivar yendo a la sección \"Administrar Avisos\" de la pantalla \"Ajustes\", y, a continuación, pulsando el botón \"Permitir Avisos\". También puedes activar o desactivar los avisos con el comando \"saltar adelante\" (pulsa dos veces y mantén pulsado) si tus auriculares tienen botones de control multimedia. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla principal para evitar que Soundscape haga avisos hasta que lo reactives."; /* */ -"help.text.automatic_callouts.how.2" = "Administración de los avisos que oyes:
Para elegir los tipos de elementos de los que Soundscape avisará automáticamente, ve a la pantalla \"Ajustes\" desde el menú principal. La sección \"Administrar Avisos\" de la pantalla \"Ajustes\" contiene una lista de tipos de elementos de los que puede avisar la aplicación. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, pulsa en el botón \"Permitir Avisos\" en la parte superior de la lista."; +"help.text.automatic_callouts.how.2" = "Administración de los avisos que oyes:
Para elegir los tipos de elementos de los que Soundscape avisará automáticamente, ve a la pantalla \"Ajustes\" desde el menú principal. La sección \"Administrar Avisos\" de la pantalla \"Ajustes\" contiene una lista de tipos de elementos de los que puede avisar la aplicación. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, pulsa el botón \"Permitir Avisos\" en la parte superior de la lista."; /* */ -"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección en la que estás mirando, dónde se encuentran cruces o carreteras cercanas, y dónde hay puntos de interés cercanos."; +"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección en la que estás mirando, dónde se encuentran cruces o carreteras cercanas y dónde hay puntos de interés cercanos."; /* */ @@ -3746,7 +3746,7 @@ /* */ -"help.text.markers.content.3" = "Para que conozcas los lugares marcados, Soundscape avisará automáticamente de ellos mientras pasas a pie o te aproximas a ellos o bien, puedes usar el botón Marcadores cercanos de la parte inferior de la pantalla principal para oír un aviso espacial de los lugares marcados a tu alrededor. Además, puedes establecer una señal de audio en cualquier lugar marcado. Cuando hagas esto, se oirá la señal de audio de Soundscape que conoces y puedes actuar de la manera habitual."; +"help.text.markers.content.3" = "Para que conozcas los lugares marcados, Soundscape avisará automáticamente de ellos mientras pasas a pie o te aproximas a ellos o bien, puedes usar el botón Marcadores cercanos de la parte inferior de la pantalla principal para oír un aviso espacial de los lugares marcados a tu alrededor. Además, puedes establecer una señal de audio en cualquier lugar marcado. Cuando hagas esto, se oirá la señal de audio de Soundscape que conoces y podrá actuar de la manera habitual."; /* */ @@ -3766,7 +3766,7 @@ /* */ -"help.text.routes.content.what" = "Las rutas son una serie de puntos de referencia. Se te informará a la llegada a cada uno de ellos y la señal de audio avanzará automáticamente hasta el siguiente."; +"help.text.routes.content.what" = "Las rutas son una serie de puntos de referencia. Se te informará a la llegada a cada uno de ellos, y la señal de audio avanzará automáticamente hasta el siguiente."; /* */ @@ -3774,7 +3774,7 @@ /* */ -"help.text.routes.content.how.1" = "Creación de una ruta:
en primer lugar, ve a \"Marcadores y rutas\", y selecciona la pestaña \"Rutas\" y el botón \"Nueva ruta\". Asigna un nombre y una descripción opcional a la ruta, luego agrega puntos de ruta a medida que avanza o elígelos en tu lista de marcadores. Puedes reorganizar el orden de los puntos de ruta a lo largo de una ruta en cualquier momento editando la ruta."; +"help.text.routes.content.how.1" = "Creación de una ruta:
en primer lugar, ve a \"Marcadores y rutas\", y selecciona la pestaña \"Rutas\" y el botón \"Nueva ruta\". Asigna un nombre y una descripción opcional a la ruta, luego agrega puntos de ruta a medida que avances o elígelos en tu lista de marcadores. Puedes reorganizar el orden de los puntos de ruta a lo largo de una ruta en cualquier momento editando la ruta."; /* */ @@ -3942,7 +3942,7 @@ /* */ -"osm.tag.post_box" = "Casilla de correos"; +"osm.tag.post_box" = "Buzón de correo"; /* */ @@ -4058,7 +4058,7 @@ /* */ -"banner.custom_behavior.scavenger_hunt.hint" = "Pulsa dos veces para leer sobre la búsqueda del tesoro o para pausarla."; +"banner.custom_behavior.scavenger_hunt.hint" = "Pulsa dos veces para leer sobre la búsqueda del tesoro o para pausarla"; /* */ @@ -4134,7 +4134,7 @@ /* */ -"faq.when_to_use_soundscape.answer" = "Soundscape tiene características y ventajas que abarcan varios escenarios y escalas de tiempo. Además, el valor de que te aporta Soundscape puede evolucionar con el tiempo; cómo lo uses hoy puede ser diferente a la manera en que lo usarás dentro de tres meses. Los usuarios piensan en las aplicaciones en cuanto a qué problema les resuelven. Sin duda, Soundscape se puede usar caso por caso cuando se tiene una necesidad informativa específica, por ejemplo, realizar el seguimiento de un destino mientras se llega allí, como ayuda para orientarse al salir de una estación de metro o de un coche, o para encontrar los nombres de las calles para el siguiente cruce o la distancia hasta llegar a él. Sin embargo, la filosofía tras Soundscape es la de \"iluminar tu mundo con sonido\" y se ha diseñado para usarlo en cualquier momento en que te encuentres fuera para un reconocimiento del entorno, por ejemplo, para saber los nombres de las calles en las que te encuentras, la dirección a la que te diriges y los nombres de los negocios que pasas. En este modo de uso, nuestros usuarios se han referido a Soundscape como una \"buena aplicación complementaria\", con la que se pueden encontrar lugares fantásticos por casualidad, para \"llenar lagunas en su mapa mental\" y que proporciona más \"confianza al caminar\". Estos son algunos otros ejemplos de cómo nuestros usuarios están incorporando Soundscape a su vida:\n\n\"Soundscape me ha ayudado a volver a mi ruta después de haberme bajado del autobús y haber caminado en la dirección equivocada.\"\n\n\"Incluso ahora en la ciudad en la que llevo viviendo 3 años conozco mejor lo que me rodea [con Soundscape].\"\n\n\"El sonido 3D mejora mi experiencia al caminar, ya que me siento más conectado con mi entorno… Es más probable que pruebe una ruta nueva ahora que tengo la aplicación.\"\n\n\"Echo de menos caminar y encontrar cosas por casualidad. Tener Soundscape está bien; no resulta un esfuerzo oír las cosas que me rodean. La información relacional es útil y resulta una aplicación excelente para reconocer las situaciones y explorar los pasillos comerciales.\"\n\n\"[Usé Soundscape] para encontrar un pub en medio de York. [I] Usé varias de sus opciones para localizarlo primero y después encontrarlo. Me llevó a 3 metros de la puerta, lo cual es fantástico.\""; +"faq.when_to_use_soundscape.answer" = "Soundscape tiene características y ventajas que abarcan varios escenarios y escalas de tiempo. Además, el valor de que te aporta Soundscape puede evolucionar con el tiempo; cómo lo uses hoy puede ser diferente a la manera en que lo usarás dentro de tres meses. Los usuarios piensan en las aplicaciones en cuanto a qué problema les resuelven. Sin duda, Soundscape se puede usar caso por caso cuando se tiene una necesidad informativa específica, por ejemplo, realizar el seguimiento de un destino mientras se llega allí, como ayuda para orientarse al salir de una estación de metro o de un coche, o para encontrar los nombres de las calles para el siguiente cruce o la distancia hasta llegar a él. Sin embargo, la filosofía tras Soundscape es la de \"iluminar tu mundo con sonido\", y se ha diseñado para usarlo en cualquier momento en que te encuentres fuera para un reconocimiento del entorno, por ejemplo, para saber los nombres de las calles en las que te encuentras, la dirección a la que te diriges y los nombres de los negocios que pasas. En este modo de uso, nuestros usuarios se han referido a Soundscape como una \"buena aplicación complementaria\", con la que se pueden encontrar lugares fantásticos por casualidad, para \"llenar lagunas en su mapa mental\" y que proporciona más \"confianza al caminar\". Estos son algunos otros ejemplos de cómo nuestros usuarios están incorporando Soundscape a su vida:\n\n\"Soundscape me ha ayudado a volver a mi ruta después de haberme bajado del autobús y haber caminado en la dirección equivocada.\"\n\n\"Incluso ahora en la ciudad en la que llevo viviendo 3 años, conozco mejor lo que me rodea [con Soundscape].\"\n\n\"El sonido 3D mejora mi experiencia al caminar, ya que me siento más conectado con mi entorno… Es más probable que pruebe una ruta nueva ahora que tengo la aplicación.\"\n\n\"Echo de menos caminar y encontrar cosas por casualidad. Tener Soundscape está bien; no resulta un esfuerzo oír las cosas que me rodean. La información relacional es útil y resulta una aplicación excelente para reconocer las situaciones y explorar los pasillos comerciales.\"\n\n\"[Usé Soundscape] para encontrar un pub en medio de York. [I] Usé varias de sus opciones para localizarlo primero y después encontrarlo. Me llevó a 3 metros de la puerta, lo cual es fantástico.\""; /* */ @@ -4154,7 +4154,7 @@ /* */ -"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como baliza. Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando en uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerá ahora en la pantalla principal."; +"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como señal. Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerá ahora en la pantalla principal."; /* */ @@ -4162,7 +4162,7 @@ /* */ -"faq.how_to_use_beacon.answer" = "Piensa en la señal de audio como un \"faro para los oídos\", que te notifica la distancia de tu destino en relación con tu ubicación, a vuelo de pájaro. Como haría un faro, no indica cómo llegar; es posible que necesites muchas opciones de navegación en el trayecto, de la misma manera que un barco tendrá muchas \"indicaciones\" estratégicas para acercarse al faro. El sonido rítmico continuo de la señal proviene de la dirección del destino y te ayuda a estar al tanto de su ubicación en relación contigo mientras caminas. Cuando vayas caminando directamente hacia el destino, o apuntes el teléfono hacia él, oirás un \"tono\" más agudo. Esta característica te permitirá identificar la dirección del destino, puesto que la dirección del sonido rítmico a veces puede ser difícil de percibir en entornos ruidosos. Al buscar el \"tono\" más alto, mantén el teléfono en posición horizontal y realiza un movimiento de barrido con el teléfono lentamente. Gira la cabeza hacia la misma dirección que el teléfono para asegurarte de que disfruta de la mejor experiencia de audio espacial.\n\nLa metáfora del faro para el diseño de la señal tiene varias implicaciones naturales:\n\n1. No hay ninguna dirección \"correcta\" en la que viajar al usar la señal, en tu lugar, con Soundscape eliges cómo llegar allí.\n2. El \"tono\" más agudo solo te ayuda a identificar la dirección del destino, pero no es una indicación de cómo llegar allí.\n3. Si normalmente sabes cómo llegar a tu destino, puede que desees silenciar la señal para la mayor parte del trayecto y activarla solo cuando te acerques."; +"faq.how_to_use_beacon.answer" = "Piensa en la señal de audio como un \"faro para los oídos\", que te notifica la distancia de tu destino en relación con tu ubicación, a vuelo de pájaro. Como haría un faro, no indica cómo llegar; es posible que necesites muchas opciones de navegación en el trayecto, de la misma manera que un barco tendrá muchas \"indicaciones\" estratégicas para acercarse al faro. El sonido rítmico continuo de la señal proviene de la dirección del destino, y te ayuda a estar al tanto de su ubicación en relación contigo mientras caminas. Cuando vayas caminando directamente hacia el destino, o apuntes el teléfono hacia él, oirás un \"tono\" más agudo. Esta característica te permitirá identificar la dirección del destino, puesto que la dirección del sonido rítmico a veces puede ser difícil de percibir en entornos ruidosos. Al buscar el \"tono\" más agudo, mantén el teléfono en posición horizontal y realiza un movimiento de barrido con el teléfono lentamente. Gira la cabeza hacia la misma dirección que el teléfono para asegurarte de que disfrutas de la mejor experiencia de audio espacial.\n\nLa metáfora del faro para el diseño de la señal tiene varias implicaciones naturales:\n\n1. No hay ninguna dirección \"correcta\" en la que se deba viajar al usar la señal, en su lugar, con Soundscape eliges cómo llegar allí.\n2. El \"tono\" más agudo solo te ayuda a identificar la dirección del destino, pero no es una indicación de cómo llegar allí.\n3. Si normalmente sabes cómo llegar a tu destino, puede que desees silenciar la señal para la mayor parte del trayecto y activarla solo cuando te acerques."; /* */ @@ -4170,7 +4170,7 @@ /* */ -"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección en la que estás mirando. Cuando Soundscape no está seguro de hacia donde estás mirando, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apunta en dirección contraria a ti."; +"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección en la que estás mirando. Cuando Soundscape no está seguro de hacia donde estás mirando, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apuntas en dirección contraria a ti."; /* */ @@ -4210,7 +4210,7 @@ /* */ -"faq.road_names.answer" = "Para adaptarse a una variedad de formas de intersecciones, Soundscape describe los cruces como segmentos de carreteras que parten de un punto común. Soundscape usa audio espacial para indicar el nombre de la carretera que va a la izquierda, el nombre de la carretera que continúa de frente y el nombre de la carretera que va a la derecha, en ese orden. Si la descripción del cruce comienza con la carretera en la que te encuentras en lugar de una a la derecha, la intersección es una T con la carretera en la que te encuentras continuando adelante y una carretera que cruza desde la derecha. De manera similar, si la descripción solo incluye una carretera a la izquierda y a la derecha, sabrás que la carretera en la que te encuentras termina en una T delante de ti. Este método de describir cruces también admite la situación de una carretera que cambia de nombre en un cruce."; +"faq.road_names.answer" = "Para adaptarse a una variedad de formas de intersecciones, Soundscape describe los cruces como segmentos de carreteras que parten de un punto común. Soundscape usa audio espacial para indicar el nombre de la carretera que va a la izquierda, el nombre de la carretera que continúa de frente y el nombre de la carretera que va a la derecha, en ese orden. Si la descripción del cruce comienza con la carretera en la que te encuentras en lugar de una a la izquierda, la intersección es una T con la carretera en la que te encuentras continuando adelante y una carretera que cruza desde la derecha. De manera similar, si la descripción solo incluye una carretera a la izquierda y a la derecha, sabrás que la carretera en la que te encuentras termina en una T delante de ti. Este método de describir cruces también admite la situación de una carretera que cambia de nombre en un cruce."; /* */ @@ -4254,7 +4254,7 @@ /* */ -"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal y cada opción tiene sus ventajas y desventajas. El único requisito es usar auriculares estéreos para beneficiarte de los avisos acústicos espaciales 3D de Soundscape."; +"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal, y cada opción tiene sus ventajas y desventajas. El único requisito es usar auriculares estéreos para beneficiarte de los avisos acústicos espaciales 3D de Soundscape."; /* */ @@ -4282,11 +4282,11 @@ /* */ -"faq.headset_battery_impact.question" = "¿En qué afecta los auriculares que elija a la duración de la batería del teléfono?"; +"faq.headset_battery_impact.question" = "¿¿Cómo afectan los auriculares que elijo a la duración de la batería del teléfono?"; /* */ -"faq.headset_battery_impact.answer" = "En nuestras pruebas, el consumo de la batería de auriculares Bluetooth es comparable a auriculares con cable y no debería ser un factor importante que se debe tener en cuenta a la hora de seleccionar estos auriculares, es decir, tanto los auriculares intrauditivos como los de conducción ósea tienen opciones de modelos por cable e inalámbricos."; +"faq.headset_battery_impact.answer" = "En nuestras pruebas, el consumo de la batería de los auriculares Bluetooth es comparable al de los auriculares con cable, y no debería ser un factor importante que se debe tener en cuenta al seleccionar unos auriculares. Dicho Esto, tanto los auriculares intrauditivos como los de conducción ósea tienen opciones de modelos por cable e inalámbricos."; /* */ @@ -4302,7 +4302,7 @@ /* */ -"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado Soundscape para que utilice solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, por medio de puntos de ahorro mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que vuelvas a un punto donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a una red Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para suspender Soundscape, o bien cierra totalmente la aplicación."; +"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado Soundscape para que consuma solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, guardando puntos mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que regreses a un sitio donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a una red Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para suspender Soundscape, o bien cierra totalmente la aplicación."; /* */ @@ -4326,7 +4326,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias formas de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: Pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente cuando te acerques al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: Cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar Avisos\".\n3. Detener la señal: Hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras recibir actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; +"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias formas de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: Pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente al aproximarse al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: Cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar Avisos\".\n3. Detener la señal: Hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras recibir actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; /* */ @@ -4334,7 +4334,7 @@ /* */ -"faq.holding_phone_flat.answer" = "¡No, no! Mientras caminas puedes guardar el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que estás caminando para averiguar qué avisos anunciar a tu izquierda y a tu derecha. Cuando dejas de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; +"faq.holding_phone_flat.answer" = "¡No, no! Mientras caminas puedes guardar el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que estás caminando para averiguar qué avisos emitirá a tu izquierda y a tu derecha. Cuando dejas de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; /* */ @@ -4358,7 +4358,7 @@ /* */ -"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla de inicio, pulsa sobre la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, aparecerá una pantalla de \"Detalles de la ubicación\" con la opción para \"Iniciar señal de audio\" en la dirección. De este modo, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no estén en Open Street Map."; +"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla de inicio, pulsa en la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, aparecerá una pantalla de \"Detalles de la ubicación\" con la opción para \"Iniciar señal de audio\" en la dirección. De este modo, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no estén en Open Street Map."; /* */ @@ -4382,7 +4382,7 @@ /* */ -"faq.tip.two_finger_double_tap" = "Para silenciar los avisos activos, pulsa la pantalla dos veces con dos dedos."; +"faq.tip.two_finger_double_tap" = "Para silenciar los avisos activos, pulsa en la pantalla dos veces con dos dedos."; @@ -4418,7 +4418,7 @@ "whats_new.1_2_0.0.title" = "Agitar para repetir el último aviso"; "whats_new.1_2_0.1.title" = "Configuración de la distancia de silenciar la señal"; "whats_new.1_2_0.2.title" = "Categorías en lugares cercanos"; -"whats_new.1_2_0.2.description" = "Ahora puedes filtrar la lista de lugares cercanos por categorías como transporte público, comida y bebida, etc."; +"whats_new.1_2_0.2.description" = "Ahora puedes filtrar la lista de lugares cercanos por categorías como Transporte público, Comida y bebida, etc."; "osm.tag.bar" = "Bar"; "osm.tag.fast_food" = "Comida rápida"; "osm.tag.ice_cream" = "Heladería"; @@ -4444,17 +4444,18 @@ "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "beacon.action.navilens" = "Iniciar NaviLens"; +"location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; -"route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso."; +"route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso"; "route_detail.reverse.error.title" = "Falla de ruta de regreso"; -"route_detail.action.start_reversed_route.disabled.hint" = "Añade puntos antes de iniciar la ruta de regreso."; +"route_detail.action.start_reversed_route.disabled.hint" = "Añadir puntos antes de iniciar la ruta de regreso"; "route_detail.reverse.error.message" = "Se ha producido un error al intentar invertir la ruta. Inténtalo de nuevo."; "routes.reverse_name_format" = "%@ de regreso"; "route_detail.action.start_reversed_route" = "Iniciar ruta de regreso"; "faq.tip.reverse_route" = "Cuando seleccionas \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden de regreso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; -"help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y Rutas\" y, a continuación, \"Iniciar Ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior."; -"location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una Señal de audio según qué tan cerca esté esta ubicación."; -"beacon.suggest_navilens" = "Inicia NaviLens para obtener más información."; +"help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y Rutas\" y, a continuación, \"Iniciar Ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vayas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior."; +"location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una Señal de audio según qué tan cerca esté esta ubicación"; +"beacon.suggest_navilens" = "Inicia NaviLens para obtener más ayuda."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; "filter.navilens" = "Códigos NaviLens"; From 9c18e9768cb66aedf014697c4b0a10ac0f3e559e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 18 May 2025 18:02:01 +0200 Subject: [PATCH 28/76] Update translation files Updated by "Cleanup translation files" hook in Weblate. Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/ Translation: Soundscape/iOS app --- .../Assets/Localization/es-ES.lproj/Localizable.strings | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index a5eba7ddb..e7afc5a27 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -4444,7 +4444,6 @@ "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "beacon.action.navilens" = "Iniciar NaviLens"; -"location_detail.action.navilens.hint" = "Pulsa dos veces para iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso"; From 92c5fdc58d0abcd30f3af7f46024ecde55e7921b Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Sun, 18 May 2025 18:02:04 +0200 Subject: [PATCH 29/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1169 of 1169 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1169 of 1169 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translation: Soundscape/iOS app --- .../Localization/en-GB.lproj/Localizable.strings | 2 +- .../Localization/es-ES.lproj/Localizable.strings | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 9395f1786..434c64e20 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -4486,6 +4486,6 @@ "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; "beacon.action.navilens" = "Launch NaviLens"; -"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is."; +"location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is"; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index e7afc5a27..9b0d96816 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -1423,7 +1423,7 @@ /* */ -"tour.progress.elapsed.accessibility.singular" = ";Señal establecida en %1$@. Han transcurrido %2$@. 1 punto de ruta restante"; +"tour.progress.elapsed.accessibility.singular" = "Señal establecida en %1$@. Han transcurrido %2$@. 1 punto de ruta restante"; /* */ @@ -2059,7 +2059,7 @@ /* */ -"directions.unknown_address" = "Dirección desconocida"; +"directions.unknown_address" = "La dirección es desconocida"; /* */ @@ -3130,7 +3130,7 @@ /* */ -"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y volverás a la pantalla anterior."; +"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y Rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y Tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3266,7 +3266,7 @@ /* */ -"tutorial.beacons.text.WrapUp" = "¡Parece que ya lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que ha establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.beacons.text.WrapUp" = "¡Parece que ya lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -4282,7 +4282,7 @@ /* */ -"faq.headset_battery_impact.question" = "¿¿Cómo afectan los auriculares que elijo a la duración de la batería del teléfono?"; +"faq.headset_battery_impact.question" = "¿Cómo afectan los auriculares que elijo a la duración de la batería del teléfono?"; /* */ @@ -4455,6 +4455,6 @@ "faq.tip.reverse_route" = "Cuando seleccionas \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden de regreso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; "help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y Rutas\" y, a continuación, \"Iniciar Ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vayas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior."; "location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una Señal de audio según qué tan cerca esté esta ubicación"; -"beacon.suggest_navilens" = "Inicia NaviLens para obtener más ayuda."; +"beacon.suggest_navilens" = "Usa el botón NaviLens para llegar a tu destino."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; "filter.navilens" = "Códigos NaviLens"; From 2dd8cb885cbd80b63ffeb5fa095a70b41493acef Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Mon, 19 May 2025 16:41:28 +0100 Subject: [PATCH 30/76] bump build number --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index e8316dbcf..c3bd1cf2b 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5531,7 +5531,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5820,7 +5820,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5880,7 +5880,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; From e6479ec26c59968e9766c2b81373b963ae3c6368 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Tue, 3 Jun 2025 23:33:25 +0100 Subject: [PATCH 31/76] Trouble shooting: allow user to delete all markers and routes. (#189) --- .../en-GB.lproj/Localizable.strings | 6 +- .../en-US.lproj/Localizable.strings | 15 ++++- .../Settings/StatusTableViewController.swift | 64 +++++++++++-------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 434c64e20..e47d88aa4 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -363,12 +363,10 @@ /* */ -"settings.clear_cache.markers.alert_title" = "Keep Markers and Routes?"; - +"settings.clear_cache.markers.alert_title" = "Delete Markers and Routes?"; /* */ -"settings.clear_cache.markers.alert_message" = "Choose \"Delete\" to remove markers, beacons and routes, or \"Keep\" to only remove map data. \"Delete\" will reset the app back to a freshly installed state and cannot be undone!"; - +"settings.clear_cache.markers.alert_message" = "Are you sure you want to delete all markers and routes? Choosing \"Delete\" will reset the app back to a freshly installed state and cannot be undone!"; /* */ "settings.clear_cache.no_service.title" = "Unable to Clear Stored Map Data"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 887aa0c6c..db76031c4 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -330,10 +330,10 @@ "settings.clear_cache.alert_message" = "Soundscape stores map data to reduce cellular data and battery consumption. Deleting stored data will require Soundscape to reload the data."; /* Alert, would you like to keep saved markers */ -"settings.clear_cache.markers.alert_title" = "Keep Markers and Routes?"; +"settings.clear_cache.markers.alert_title" = "Delete Markers and Routes?"; -/* Message, chose delete or keep. Quotes written as \" Delete removes markers and beacons resetting the app to a new installation build and cannot be undone. Keep only removes map data. */ -"settings.clear_cache.markers.alert_message" = "Choose \"Delete\" to remove markers, beacons and routes, or \"Keep\" to only remove map data. \"Delete\" will reset the app back to a freshly installed state and cannot be undone!"; +/* Quotes written as \" Delete removes markers and beacons resetting the app to a new installation build and cannot be undone. */ +"settings.clear_cache.markers.alert_message" = "Are you sure you want to delete all markers and routes? Choosing \"Delete\" will reset the app back to a freshly installed state and cannot be undone!"; /* Alert title, the stored data wasn't deleted */ "settings.clear_cache.no_service.title" = "Unable to Clear Stored Map Data"; @@ -583,6 +583,15 @@ /* Explanation of what the "Delete Stored Map Data" button does, displayed below the button */ "troubleshooting.cache.explanation" = "Soundscape downloads map data as you walk around so that it can tell you about the things and places around you. If you are having issues with Soundscape or it is using too much memory, you can clear the stored map data and Soundscape will only redownload the map data near your current location."; +/* Title for the user data section in troubleshooting */ +"troubleshooting.user_data" = "User Data"; + +/* Label for the button that allows user to delete all map data, including saved markers and routes */ +"troubleshooting.user_data.button" = "Delete All markers and routes"; + +/* Explanation for the user data section in troubleshooting */ +"troubleshooting.user_data.explanation" = "Delete all map data, including saved markers and routes. This action cannot be undone."; + //------------------------------------------------------------------------------ // MARK: Settings (About) //------------------------------------------------------------------------------ diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/StatusTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/StatusTableViewController.swift index f32fcff1a..4e8dc9256 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/StatusTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/StatusTableViewController.swift @@ -16,6 +16,7 @@ class StatusTableViewController: BaseTableViewController { static let audio = 1 static let url = 2 static let cache = 3 + static let userData = 4 } private struct CellIdentifier { @@ -73,7 +74,7 @@ class StatusTableViewController: BaseTableViewController { // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { - return 4 + return 5 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -82,6 +83,7 @@ class StatusTableViewController: BaseTableViewController { case Section.audio: return 1 case Section.url: return 1 case Section.cache: return 1 + case Section.userData: return 1 default: return 0 } } @@ -92,6 +94,7 @@ class StatusTableViewController: BaseTableViewController { case Section.audio: return GDLocalizedString("troubleshooting.check_audio") case Section.url: return GDLocalizedString("troubleshooting.tile_server_url") case Section.cache: return GDLocalizedString("troubleshooting.cache") + case Section.userData: return GDLocalizedString("troubleshooting.user_data") default: return nil } } @@ -107,6 +110,7 @@ class StatusTableViewController: BaseTableViewController { case Section.audio: return GDLocalizedString("troubleshooting.check_audio.explanation") case Section.url: return GDLocalizedString("troubleshooting.tile_server_url.explanation") case Section.cache: return GDLocalizedString("troubleshooting.cache.explanation") + case Section.userData: return GDLocalizedString("troubleshooting.user_data.explanation") default: return nil } } @@ -133,8 +137,7 @@ class StatusTableViewController: BaseTableViewController { let cell: ButtonTableViewCell = tableView.dequeueReusableCell(forIndexPath: indexPath) cell.backgroundColor = Colors.Background.quaternary - cell.button.removeTarget(self, action: #selector(urlTouchUpInside), for: .touchUpInside) - cell.button.removeTarget(self, action: #selector(clearCacheTouchUpInside), for: .touchUpInside) + cell.button.removeTarget(nil, action: nil, for: .touchUpInside) cell.button.addTarget(self, action: #selector(crosscheckTouchUpInside), for: .touchUpInside) cell.button.accessibilityLabel = GDLocalizedString("troubleshooting.check_audio") cell.button.accessibilityHint = GDLocalizedString("troubleshooting.check_audio.hint") @@ -147,8 +150,7 @@ class StatusTableViewController: BaseTableViewController { let cell: ButtonTableViewCell = tableView.dequeueReusableCell(forIndexPath: indexPath) cell.backgroundColor = Colors.Background.quaternary - cell.button.removeTarget(self, action: #selector(clearCacheTouchUpInside), for: .touchUpInside) - cell.button.removeTarget(self, action: #selector(crosscheckTouchUpInside), for: .touchUpInside) + cell.button.removeTarget(nil, action: nil, for: .touchUpInside) cell.button.addTarget(self, action: #selector(urlTouchUpInside), for: .touchUpInside) cell.button.accessibilityLabel = GDLocalizedString("troubleshooting.tile_server_url") cell.button.accessibilityHint = GDLocalizedString("troubleshooting.tile_server_url.explanation") @@ -162,8 +164,7 @@ class StatusTableViewController: BaseTableViewController { let cell: ButtonTableViewCell = tableView.dequeueReusableCell(forIndexPath: indexPath) cell.backgroundColor = Colors.Background.quaternary - cell.button.removeTarget(self, action: #selector(urlTouchUpInside), for: .touchUpInside) - cell.button.removeTarget(self, action: #selector(crosscheckTouchUpInside), for: .touchUpInside) + cell.button.removeTarget(nil, action: nil, for: .touchUpInside) cell.button.addTarget(self, action: #selector(clearCacheTouchUpInside), for: .touchUpInside) cell.button.accessibilityLabel = GDLocalizedString("settings.clear_data") cell.button.accessibilityHint = GDLocalizedString("troubleshooting.cache.hint") @@ -172,6 +173,17 @@ class StatusTableViewController: BaseTableViewController { return cell + case Section.userData: + let cell: ButtonTableViewCell = tableView.dequeueReusableCell(forIndexPath: indexPath) + cell.backgroundColor = Colors.Background.quaternary + cell.button.removeTarget(nil, action: nil, for: .touchUpInside) + cell.button.addTarget(self, action: #selector(deleteUserDataTouchUpInside), for: .touchUpInside) + cell.button.accessibilityLabel = GDLocalizedString("troubleshooting.user_data.button") + cell.button.accessibilityHint = GDLocalizedString("troubleshooting.user_data.explanation") + cell.button.backgroundColor = Colors.Background.error + cell.label.text = GDLocalizedString("troubleshooting.user_data.button") + return cell + default: fatalError() } @@ -262,9 +274,20 @@ extension StatusTableViewController { present(alert, animated: true, completion: nil) } - /// ask the user if they want to keep the markers. - /// This is not used, but could be reenabled for debug builds in the future. - private func displayMarkersPrompt() { + @objc func deleteUserDataTouchUpInside() { + // Only allow the cache to be deleted if we have a network connection to reload the cache + guard AppContext.shared.offlineContext.state != .offline else { + let alert = UIAlertController(title: GDLocalizedString("general.error.network_connection_required"), + message: GDLocalizedString("general.error.network_connection_required.deleting_data"), + preferredStyle: UIAlertController.Style.alert) + + alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.dismiss"), style: .cancel, handler: nil)) + + present(alert, animated: true, completion: nil) + + return + } + let alert = UIAlertController(title: GDLocalizedString("settings.clear_cache.markers.alert_title"), message: GDLocalizedString("settings.clear_cache.markers.alert_message"), preferredStyle: UIAlertController.Style.actionSheet) @@ -275,22 +298,13 @@ extension StatusTableViewController { } })) - alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.keep"), style: .default, handler: { _ in - self.performSegue(withIdentifier: Segue.showLoadingModal, sender: self) - - // Check that tiles can be downloaded before we attempt to delete the cache - AppContext.shared.spatialDataContext.checkServiceConnection { [weak self] (success) in - guard success else { - self?.displayUnableToClearCacheWarning() - return - } - - // Clear the cache and keep the markers - self?.clearCache(false) - } - })) - alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.delete"), style: .destructive, handler: { _ in + AppContext.shared.eventProcessor.hush(playSound: false) + + if SettingsContext.shared.automaticCalloutsEnabled { + self.reenableCalloutsAfterReload = true + SettingsContext.shared.automaticCalloutsEnabled = false + } self.performSegue(withIdentifier: Segue.showLoadingModal, sender: self) // Check that tiles can be downloaded before we attempt to delete the cache From 881223203092511620929839b52efa033866daba Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Sat, 7 Jun 2025 08:06:16 -0400 Subject: [PATCH 32/76] Silence Soundscape before launching NaviLens --- .../ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift index edf56edb2..86582089c 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Integrations.swift @@ -7,6 +7,12 @@ // func launchNaviLens(detail: LocationDetail) { + // Silence Soundscape before launching NaviLens + // Find the home screen in the view stack and trigger the sleep button + let rootVc = AppContext.rootViewController as? UINavigationController; + let homeVc = rootVc?.viewControllers.first as? HomeViewController; + homeVc?.onSleepTouchUpInside(); + // Launch NaviLens app, or open App Store listing if not installed let navilensUrl = URL(string: "navilens://")! let appStoreUrl = URL(string: "https://apps.apple.com/us/app/navilens/id1273704914")! From a1e98444674bf05b21c93e922f8f2c19aef3f6e7 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Wed, 11 Jun 2025 10:10:08 +0100 Subject: [PATCH 33/76] Cleanup: remove AppCenter dependency and telemetry setting. (#191) Setting commented out with the view to re-adding telemetry with a different service in the future. --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 25 ------------------- .../GuideDogs/Code/App/BuildSettings.swift | 6 ++--- .../Code/App/Logging/GDATelemetry.swift | 7 ++---- .../Launch/DynamicLaunchViewController.swift | 8 ------ .../Settings/SettingsViewController.swift | 19 +++++++------- 5 files changed, 14 insertions(+), 51 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index c3bd1cf2b..60aaf5d6c 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -103,8 +103,6 @@ 285C8B83230496D900E466DF /* GlyphCallout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285C8B82230496D900E466DF /* GlyphCallout.swift */; }; 286145EB2625099F000E5525 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 286145EA2625099F000E5525 /* SDWebImage */; }; 2866A7C12625013400EBA2D8 /* DZNEmptyDataSet in Frameworks */ = {isa = PBXBuildFile; productRef = 2866A7C02625013400EBA2D8 /* DZNEmptyDataSet */; }; - 2866A7C72625020600EBA2D8 /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 2866A7C62625020600EBA2D8 /* AppCenterAnalytics */; }; - 2866A7C92625020600EBA2D8 /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = 2866A7C82625020600EBA2D8 /* AppCenterCrashes */; }; 2866A7CF2625028600EBA2D8 /* Reachability in Frameworks */ = {isa = PBXBuildFile; productRef = 2866A7CE2625028600EBA2D8 /* Reachability */; }; 2866A7D5262502D500EBA2D8 /* CocoaLumberjackSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 2866A7D4262502D500EBA2D8 /* CocoaLumberjackSwift */; }; 286708D125005912002F962B /* street_non_1c.wav in Resources */ = {isa = PBXBuildFile; fileRef = 286708D025005912002F962B /* street_non_1c.wav */; }; @@ -1596,9 +1594,7 @@ buildActionMask = 2147483647; files = ( 283B0307264B03920092F74F /* SDWebImageSwiftUI in Frameworks */, - 2866A7C72625020600EBA2D8 /* AppCenterAnalytics in Frameworks */, 2866A7CF2625028600EBA2D8 /* Reachability in Frameworks */, - 2866A7C92625020600EBA2D8 /* AppCenterCrashes in Frameworks */, 286F409D2624FF6000C3F80B /* NVActivityIndicatorView in Frameworks */, 2866A7D5262502D500EBA2D8 /* CocoaLumberjackSwift in Frameworks */, 91172A732AD8D56D00E6E8E9 /* CoreGPX in Frameworks */, @@ -4505,8 +4501,6 @@ packageProductDependencies = ( 286F409C2624FF6000C3F80B /* NVActivityIndicatorView */, 2866A7C02625013400EBA2D8 /* DZNEmptyDataSet */, - 2866A7C62625020600EBA2D8 /* AppCenterAnalytics */, - 2866A7C82625020600EBA2D8 /* AppCenterCrashes */, 2866A7CE2625028600EBA2D8 /* Reachability */, 2866A7D4262502D500EBA2D8 /* CocoaLumberjackSwift */, 28F1ECE1262505DC00E964C0 /* Realm */, @@ -4585,7 +4579,6 @@ packageReferences = ( 286F409B2624FF6000C3F80B /* XCRemoteSwiftPackageReference "NVActivityIndicatorView" */, 2866A7BF2625013400EBA2D8 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */, - 2866A7C52625020600EBA2D8 /* XCRemoteSwiftPackageReference "AppCenter-SDK-Apple" */, 2866A7CD2625028600EBA2D8 /* XCRemoteSwiftPackageReference "Reachability" */, 2866A7D3262502D500EBA2D8 /* XCRemoteSwiftPackageReference "CocoaLumberjack" */, 28F1ECE0262505DC00E964C0 /* XCRemoteSwiftPackageReference "realm-cocoa" */, @@ -5987,14 +5980,6 @@ revision = 9bffa69a83a9fa58a14b3cf43cb6dd8a63774179; }; }; - 2866A7C52625020600EBA2D8 /* XCRemoteSwiftPackageReference "AppCenter-SDK-Apple" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/Microsoft/AppCenter-SDK-Apple"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 4.4.3; - }; - }; 2866A7CD2625028600EBA2D8 /* XCRemoteSwiftPackageReference "Reachability" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ashleymills/Reachability.swift"; @@ -6058,16 +6043,6 @@ package = 2866A7BF2625013400EBA2D8 /* XCRemoteSwiftPackageReference "DZNEmptyDataSet" */; productName = DZNEmptyDataSet; }; - 2866A7C62625020600EBA2D8 /* AppCenterAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 2866A7C52625020600EBA2D8 /* XCRemoteSwiftPackageReference "AppCenter-SDK-Apple" */; - productName = AppCenterAnalytics; - }; - 2866A7C82625020600EBA2D8 /* AppCenterCrashes */ = { - isa = XCSwiftPackageProductDependency; - package = 2866A7C52625020600EBA2D8 /* XCRemoteSwiftPackageReference "AppCenter-SDK-Apple" */; - productName = AppCenterCrashes; - }; 2866A7CE2625028600EBA2D8 /* Reachability */ = { isa = XCSwiftPackageProductDependency; package = 2866A7CD2625028600EBA2D8 /* XCRemoteSwiftPackageReference "Reachability" */; diff --git a/apps/ios/GuideDogs/Code/App/BuildSettings.swift b/apps/ios/GuideDogs/Code/App/BuildSettings.swift index e108c0255..8c44acf43 100644 --- a/apps/ios/GuideDogs/Code/App/BuildSettings.swift +++ b/apps/ios/GuideDogs/Code/App/BuildSettings.swift @@ -20,9 +20,9 @@ class BuildSettings { enum Source: String { case local - case appCenter case testFlight case appStore + case adhoc } // MARK: Properties @@ -41,8 +41,6 @@ class BuildSettings { switch configuration { case .debug: return .local - case .adhoc: - return .appCenter case .release: // TestFlight builds contain an App Store receipt file named "sandboxReceipt" // Other sources have a receipt file named "receipt" @@ -52,6 +50,8 @@ class BuildSettings { } else { return .appStore } + case .adhoc: + return .adhoc } } diff --git a/apps/ios/GuideDogs/Code/App/Logging/GDATelemetry.swift b/apps/ios/GuideDogs/Code/App/Logging/GDATelemetry.swift index 417f79a9d..053c23863 100644 --- a/apps/ios/GuideDogs/Code/App/Logging/GDATelemetry.swift +++ b/apps/ios/GuideDogs/Code/App/Logging/GDATelemetry.swift @@ -5,9 +5,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // +// This is just a stub, MS used AppCenter which is being depricated. import Foundation -import AppCenterAnalytics public class GDATelemetry { @@ -21,8 +21,7 @@ public class GDATelemetry { } set { SettingsContext.shared.telemetryOptout = !newValue - Analytics.enabled = newValue - } + } } class func trackScreenView(_ screenName: String, with properties: [String: String]? = nil) { @@ -48,8 +47,6 @@ public class GDATelemetry { if debugLog { print("[TEL] Event tracked: \(eventName)" + (propertiesToSend.isEmpty ? "" : " \(propertiesToSend)")) } - - Analytics.trackEvent(eventName, withProperties: propertiesToSend) } } diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Launch/DynamicLaunchViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Launch/DynamicLaunchViewController.swift index d991326eb..14eab6e16 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Launch/DynamicLaunchViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Launch/DynamicLaunchViewController.swift @@ -8,9 +8,6 @@ import UIKit -import AppCenter -import AppCenterAnalytics -import AppCenterCrashes import Combine class DynamicLaunchViewController: UIViewController { @@ -43,11 +40,6 @@ class DynamicLaunchViewController: UIViewController { SpatialDataCache.useDefaultGeocoder() } - if !testEnvironment, !UIDeviceManager.isSimulator { - AppCenter.start(withAppSecret: "<#Secret#>", services: [Analytics.self, Crashes.self]) - Analytics.enabled = !SettingsContext.shared.telemetryOptout - Crashes.enabled = !SettingsContext.shared.telemetryOptout - } } /// Notifies the view controller that its view was added to a view hierarchy. diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index ffd310357..d5e5ef20c 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -8,7 +8,6 @@ import UIKit -import AppCenterAnalytics class SettingsViewController: BaseTableViewController { @@ -19,7 +18,7 @@ class SettingsViewController: BaseTableViewController { case streetPreview = 3 case troubleshooting = 4 case about = 5 - case telemetry = 6 + // case telemetry = 6 } private enum CalloutsRow: Int, CaseIterable { @@ -49,7 +48,7 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: 0, section: Section.streetPreview.rawValue): "streetPreview", IndexPath(row: 0, section: Section.troubleshooting.rawValue): "troubleshooting", IndexPath(row: 0, section: Section.about.rawValue): "about", - IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry" + // IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry" ] private static let collapsibleCalloutIndexPaths: [IndexPath] = [ @@ -89,7 +88,7 @@ class SettingsViewController: BaseTableViewController { case .streetPreview: return 1 case .troubleshooting: return 1 case .about: return 1 - case .telemetry: return 1 + // case .telemetry: return 1 } } @@ -117,11 +116,11 @@ class SettingsViewController: BaseTableViewController { return cell - case .telemetry: - let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! TelemetrySettingsTableViewCell - cell.parent = self + // case .telemetry: + // let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! TelemetrySettingsTableViewCell + // cell.parent = self - return cell + // return cell case .audio: let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) as! MixAudioSettingCell @@ -146,7 +145,7 @@ class SettingsViewController: BaseTableViewController { case .about: return GDLocalizedString("settings.section.about") case .streetPreview: return GDLocalizedString("preview.title") case .troubleshooting: return GDLocalizedString("settings.section.troubleshooting") - case .telemetry: return GDLocalizedString("settings.section.telemetry") + // case .telemetry: return GDLocalizedString("settings.section.telemetry") } } @@ -156,7 +155,7 @@ class SettingsViewController: BaseTableViewController { switch sectionType { case .audio: return GDLocalizedString("settings.audio.mix_with_others.description") case .streetPreview: return GDLocalizedString("preview.include_unnamed_roads.subtitle") - case .telemetry: return GDLocalizedString("settings.section.telemetry.footer") + // case .telemetry: return GDLocalizedString("settings.section.telemetry.footer") default: return nil } } From ec4763cc4b14308785465e4a602aca7168183871 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Tue, 24 Jun 2025 16:53:06 +0100 Subject: [PATCH 34/76] ios: add a workflow and script to build and upload to appstore connect (#183) Triggers an upload to testflight on every commit to main where the unit tests are successful. --- .github/workflows/build-for-testflight.yml | 75 ++++++++++++++------ .github/workflows/ios-tests.yml | 3 + apps/ios/GuideDogs.xcodeproj/project.pbxproj | 6 +- apps/ios/Scripts/ci/ExportOptions.plist | 23 ++++++ apps/ios/Scripts/ci/archive-upload.sh | 59 +++++++++++++++ 5 files changed, 142 insertions(+), 24 deletions(-) create mode 100644 apps/ios/Scripts/ci/ExportOptions.plist create mode 100755 apps/ios/Scripts/ci/archive-upload.sh diff --git a/.github/workflows/build-for-testflight.yml b/.github/workflows/build-for-testflight.yml index e7930320c..a74a22c2e 100644 --- a/.github/workflows/build-for-testflight.yml +++ b/.github/workflows/build-for-testflight.yml @@ -1,26 +1,59 @@ name: "build and submit to testflight" on: - push: - branches: [ "main" ] - paths: - - 'apps/ios/**' - - '.github/workflows/build-for-testflight.yml' + workflow_run: + workflows: + - "ios-tests" + types: + - completed + branches: + - main workflow_dispatch: jobs: - build: - runs-on: macos-13 + build-and-upload: + if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} + runs-on: macos-14 + environment: Development + steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup ssh agent and deploy key(s) - uses: webfactory/ssh-agent@v0.8.0 - with: - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - - name: Install gems - working-directory: apps/ios - run: bundle install - - name: setup and build with fastlane - working-directory: apps/ios - env: - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} - run: bundle exec fastlane beta + # Check out code with push permissions (needed for commit) + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: true + + - name: Bump build number + run: | + cd apps/ios + agvtool bump + + # Commit and push the version change (avoid loop with [skip ci]) + - name: Commit bump + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add -A + git commit -m "chore(ci): bump build number [skip ci]" || echo "Nothing to commit" + git push + + # 4 Select the latest stable Xcode version + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "latest-stable" + + # install the developer certificate in the signing_temp keychain + - name: install certificate + id: install-certificates + uses: apple-actions/import-codesign-certs@v3 + with: + p12-file-base64: ${{ secrets.APPSTORE_CERTIFICATES_FILE_BASE64 }} + p12-password: ${{ secrets.APPSTORE_CERTIFICATES_PASSWORD }} + + - name: build and upload to testflight + env: + APPSTORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_P8_BASE64 }} + APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_ISSUER_ID }} + APPSTORE_CONNECT_KEY_ID: ${{ secrets.APP_store_KEY_ID }} + KEYCHAIN_PASSWORD: ${{ steps.install-certificates.outputs.keychain-password }} + run: "apps/ios/Scripts/ci/archive-upload.sh | xcpretty && exit ${PIPESTATUS[0]}" diff --git a/.github/workflows/ios-tests.yml b/.github/workflows/ios-tests.yml index 224e5f51c..65886aefd 100644 --- a/.github/workflows/ios-tests.yml +++ b/.github/workflows/ios-tests.yml @@ -12,6 +12,9 @@ on: paths: - 'apps/ios/**' workflow_dispatch: +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true jobs: unit-tests: runs-on: macos-14 diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 60aaf5d6c..692d58974 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5583,7 +5583,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -5619,7 +5619,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5651,7 +5651,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; diff --git a/apps/ios/Scripts/ci/ExportOptions.plist b/apps/ios/Scripts/ci/ExportOptions.plist new file mode 100644 index 000000000..272d4889d --- /dev/null +++ b/apps/ios/Scripts/ci/ExportOptions.plist @@ -0,0 +1,23 @@ + + + + + destination + upload + method + app-store-connect + signingStyle + automatic + stripSwiftSymbols + + uploadSymbols + + teamID + X4H33NKGKY + thinning + <none> + manageAppVersionAndBuildNumber + + + + diff --git a/apps/ios/Scripts/ci/archive-upload.sh b/apps/ios/Scripts/ci/archive-upload.sh new file mode 100755 index 000000000..d9a41bc59 --- /dev/null +++ b/apps/ios/Scripts/ci/archive-upload.sh @@ -0,0 +1,59 @@ +#!/bin/zsh +# This script archives the app and uploads it to App Store Connect. +# It can be run interactively or in a CI environment. +# In a CI environment: +# - the developer certificate should be in a keychain called signing_temp.keychain-db +# - it will use the keychain password from the environment variable KEYCHAIN_PASSWORD. +# - the appstore authentication key should be base64 encoded in $APPSTORE_CONNECT_API_KEY +# the Appstore key id is $APPSTORE_CONNECT_KEY_ID +# - the appstore issuer id is $APPSTORE_CONNECT_ISSUER_ID +set -e + +SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)" +APP_PROJECT="$SCRIPTDIR/../../GuideDogs.xcodeproj" +APP_SCHEME=Soundscape +APP_ARCHIVE_PATH="$SCRIPTDIR/build/$APP_SCHEME.xcarchive" +EXTRA_ARGS=() +if [ -t 0 ]; then +# if stdin is a terminal, then we are running interactively + export APP_KEYCHAIN="$HOME/Library/Keychains/login.keychain-db" + security unlock-keychain "$HOME/Library/Keychains/login.keychain-db" +else + # we are running in CI + export APP_KEYCHAIN="$HOME/Library/Keychains/signing_temp.keychain-db" + if [ -z "$KEYCHAIN_PASSWORD" ]; then + echo "Error: KEYCHAIN_PASSWORD is not set." >&2 + exit 1 + fi + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$APP_KEYCHAIN" + security default-keychain -s "$APP_KEYCHAIN" + authenticationKeyPath="$(mktemp)" + echo "$APPSTORE_CONNECT_API_KEY" | base64 --decode > "$authenticationKeyPath" + # clean up the key after use + trap 'rm -f "$authenticationKeyPath"' EXIT + EXTRA_ARGS=( + -authenticationKeyPath "$authenticationKeyPath" + -authenticationKeyID "$APPSTORE_CONNECT_KEY_ID" + -authenticationIssuerID "$APPSTORE_CONNECT_ISSUER_ID" + ) +fi + +xcodebuild archive \ + -project "$APP_PROJECT" \ + -scheme "$APP_SCHEME" \ + -configuration Release \ + -destination 'generic/platform=iOS' \ + -allowProvisioningUpdates \ + -archivePath "$APP_ARCHIVE_PATH" \ + "${EXTRA_ARGS[@]}" + + +# use xcodebuild to export and upload the archive +xcodebuild \ + -exportArchive \ + -archivePath "$APP_ARCHIVE_PATH" \ + -exportOptionsPlist "$SCRIPTDIR/ExportOptions.plist" \ + -exportPath "$SCRIPTDIR/build" \ + -allowProvisioningUpdates \ + "${EXTRA_ARGS[@]}" + From 30b33fc251b6ccb4b730586ff2368d28d02c740d Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Tue, 24 Jun 2025 17:06:16 +0100 Subject: [PATCH 35/76] Bump Version to 1.7.1 --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 692d58974..c1367f882 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5524,7 +5524,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5555,7 +5555,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.3; + MARKETING_VERSION = 1.7.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5813,7 +5813,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5845,7 +5845,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.3; + MARKETING_VERSION = 1.7.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5873,7 +5873,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5903,7 +5903,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.3.3; + MARKETING_VERSION = 1.7.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; From 3c2c2cb86fb510c6bcae76f69a0fc4e74790600d Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Tue, 24 Jun 2025 17:18:11 +0100 Subject: [PATCH 36/76] Add write permission for GitHub token in build-for-testflight.yml --- .github/workflows/build-for-testflight.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-for-testflight.yml b/.github/workflows/build-for-testflight.yml index a74a22c2e..9351dbec9 100644 --- a/.github/workflows/build-for-testflight.yml +++ b/.github/workflows/build-for-testflight.yml @@ -8,6 +8,8 @@ on: branches: - main workflow_dispatch: +permissions: + contents: write jobs: build-and-upload: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} From 0406d9f0ae2383d443ba32952dc41111eb7f8137 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:29:28 +0000 Subject: [PATCH 37/76] chore(ci): bump build number [skip ci] --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index c1367f882..d4cc51b31 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5524,7 +5524,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5583,7 +5583,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -5619,7 +5619,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5651,7 +5651,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5813,7 +5813,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5873,7 +5873,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; From bc2b28d90a6a65f722fdb05ce1dfbec43ba67c2c Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Tue, 24 Jun 2025 17:33:41 +0100 Subject: [PATCH 38/76] archive-upload.sh: fix typo [skip ci] --- apps/ios/Scripts/ci/archive-upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/Scripts/ci/archive-upload.sh b/apps/ios/Scripts/ci/archive-upload.sh index d9a41bc59..8509eaa47 100755 --- a/apps/ios/Scripts/ci/archive-upload.sh +++ b/apps/ios/Scripts/ci/archive-upload.sh @@ -34,7 +34,7 @@ else EXTRA_ARGS=( -authenticationKeyPath "$authenticationKeyPath" -authenticationKeyID "$APPSTORE_CONNECT_KEY_ID" - -authenticationIssuerID "$APPSTORE_CONNECT_ISSUER_ID" + -authenticationKeyIssuerID "$APPSTORE_CONNECT_ISSUER_ID" ) fi From 60522fc57c20dd3d7468067c6dc27da010161520 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:38:22 +0000 Subject: [PATCH 39/76] chore(ci): bump build number [skip ci] --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index d4cc51b31..ac93defa4 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5524,7 +5524,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5583,7 +5583,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -5619,7 +5619,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5651,7 +5651,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5813,7 +5813,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5873,7 +5873,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; From 671b314967136114c98c1aeef2bda0edf4d6bfd8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:45:01 +0000 Subject: [PATCH 40/76] chore(ci): bump build number [skip ci] --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index ac93defa4..f8de74b3e 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5524,7 +5524,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5583,7 +5583,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -5619,7 +5619,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5651,7 +5651,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5813,7 +5813,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5873,7 +5873,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; From 1aa16c10b8d7fc2cb7aae58e5fc535cf324d227b Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Tue, 24 Jun 2025 18:02:38 +0100 Subject: [PATCH 41/76] .github/workflows/build-for-testflight.yml Try with production environment --- .github/workflows/build-for-testflight.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-for-testflight.yml b/.github/workflows/build-for-testflight.yml index 9351dbec9..b6783e360 100644 --- a/.github/workflows/build-for-testflight.yml +++ b/.github/workflows/build-for-testflight.yml @@ -14,7 +14,7 @@ jobs: build-and-upload: if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} runs-on: macos-14 - environment: Development + environment: Production steps: # Check out code with push permissions (needed for commit) @@ -56,6 +56,6 @@ jobs: env: APPSTORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_P8_BASE64 }} APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_ISSUER_ID }} - APPSTORE_CONNECT_KEY_ID: ${{ secrets.APP_store_KEY_ID }} + APPSTORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_KEY_ID }} KEYCHAIN_PASSWORD: ${{ steps.install-certificates.outputs.keychain-password }} run: "apps/ios/Scripts/ci/archive-upload.sh | xcpretty && exit ${PIPESTATUS[0]}" From 6a84924d63fc0a2542abac51d8c823832f0330d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:07:23 +0000 Subject: [PATCH 42/76] chore(ci): bump build number [skip ci] --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index f8de74b3e..59e4c0ae6 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5524,7 +5524,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5583,7 +5583,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -5619,7 +5619,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5651,7 +5651,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = X4H33NKGKY; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -5813,7 +5813,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5873,7 +5873,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; From 0302d7d8ba326d24594ce817c6c7e37a6ff875af Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Tue, 1 Jul 2025 16:15:38 -0400 Subject: [PATCH 43/76] Edited CalloutSettingsCellView --- .../Settings/CalloutSettingsCellView.swift | 64 +++++++++-------- .../Code/Visual UI/Views/Settings.storyboard | 70 +++++++++++++++++++ 2 files changed, 103 insertions(+), 31 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift b/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift index 8b6d09251..f3f25dc89 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift @@ -14,36 +14,41 @@ protocol CalloutSettingsCellViewDelegate: AnyObject { internal enum CalloutSettingCellType { case all, poi, mobility, beacon, shake + case transportation + case intersection + case safety } + class CalloutSettingsCellView: UITableViewCell { weak var delegate: CalloutSettingsCellViewDelegate? var type: CalloutSettingCellType! { - didSet { - guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { - return - } - - // Update the switch - settingSwitch.isEnabled = type == .all || SettingsContext.shared.automaticCalloutsEnabled - + didSet { + guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { + return + } + + settingSwitch.isEnabled = type == .all || SettingsContext.shared.automaticCalloutsEnabled + switch type { case .all: settingSwitch.isOn = SettingsContext.shared.automaticCalloutsEnabled - return case .poi: settingSwitch.isOn = SettingsContext.shared.placeSenseEnabled - return case .mobility: settingSwitch.isOn = SettingsContext.shared.mobilitySenseEnabled - return case .beacon: settingSwitch.isOn = SettingsContext.shared.destinationSenseEnabled - return case .shake: settingSwitch.isOn = SettingsContext.shared.shakeCalloutsEnabled + case .transportation: + settingSwitch.isOn = SettingsContext.shared.mobilitySenseEnabled + case .intersection: + settingSwitch.isOn = SettingsContext.shared.intersectionSenseEnabled + case .safety: + settingSwitch.isOn = SettingsContext.shared.safetySenseEnabled } } } @@ -52,51 +57,48 @@ class CalloutSettingsCellView: UITableViewCell { guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { return } - - defer { - delegate?.onCalloutSettingChanged(type) - } - + + defer { delegate?.onCalloutSettingChanged(type) } + let isOn = settingSwitch.isOn - - let log: ([String]) -> Void = { (categories: [String]) in + + let log: ([String]) -> Void = { categories in for category in categories { GDLogActionInfo("Toggled \(category) callouts to: \(isOn)") - GDATelemetry.track("settings.autocallouts_\(category)", value: isOn.description) } } - + switch type { case .all: SettingsContext.shared.automaticCalloutsEnabled = isOn GDATelemetry.track("settings.allow_callouts", value: isOn.description) - return - case .poi: - // Places, Landmark, and Information Senses SettingsContext.shared.placeSenseEnabled = isOn SettingsContext.shared.landmarkSenseEnabled = isOn SettingsContext.shared.informationSenseEnabled = isOn log(["places", "landmarks", "info"]) - return - case .mobility: - // Mobility, Safety, and Intersection Sense SettingsContext.shared.mobilitySenseEnabled = isOn SettingsContext.shared.safetySenseEnabled = isOn SettingsContext.shared.intersectionSenseEnabled = isOn log(["mobility", "safety", "intersections"]) - return - case .beacon: - // Destination sense SettingsContext.shared.destinationSenseEnabled = isOn log(["destination"]) - return case .shake: SettingsContext.shared.shakeCalloutsEnabled = isOn GDATelemetry.track("settings.shake_callouts", value: isOn.description) + case .transportation: + SettingsContext.shared.mobilitySenseEnabled = isOn + log(["mobility"]) + case .intersection: + SettingsContext.shared.intersectionSenseEnabled = isOn + log(["intersections"]) + case .safety: + SettingsContext.shared.safetySenseEnabled = isOn + log(["safety"]) } } + } diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard index ebc77e8fb..a6446a436 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard @@ -315,6 +315,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ed2a339898e39f7193797f57c2000c9ae4242174 Mon Sep 17 00:00:00 2001 From: "Daniel W. Steinbrook" Date: Wed, 2 Jul 2025 21:44:00 -0400 Subject: [PATCH 44/76] check_non_osm_ingested: Avoid double-slashes in URLs --- svcs/data/non_osm_scripts/check_non_osm_ingested.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/svcs/data/non_osm_scripts/check_non_osm_ingested.py b/svcs/data/non_osm_scripts/check_non_osm_ingested.py index c90e4128c..2fe7f9eba 100644 --- a/svcs/data/non_osm_scripts/check_non_osm_ingested.py +++ b/svcs/data/non_osm_scripts/check_non_osm_ingested.py @@ -10,6 +10,7 @@ from pathlib import Path import random import sys +from urllib.parse import urljoin import requests @@ -41,7 +42,7 @@ def osm_deg2num(lat_deg, lon_deg, zoom): # Determine tile that would contain feature x, y = osm_deg2num( float(some_row['latitude']), float(some_row["longitude"]), args.zoom) - url = f"{args.tile_server}/{args.zoom}/{x}/{y}.json" + url = urljoin(args.tile_server, f"{args.zoom}/{x}/{y}.json") print(f"Fetching {url}...") response = requests.get(url) features = response.json()["features"] From 56da1e356891ef2a6dc1fa626887b678d8236a10 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Fri, 18 Jul 2025 01:52:07 +0100 Subject: [PATCH 45/76] Fix expiry of guided tours. (#198) --- .../ios/GuideDogs/Code/Behaviors/Guided Tour/TourDetail.swift | 4 ++++ .../Visual UI/Helpers/Guided Tours/GuidedTourAction.swift | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Code/Behaviors/Guided Tour/TourDetail.swift b/apps/ios/GuideDogs/Code/Behaviors/Guided Tour/TourDetail.swift index 4cdd212b0..8831e988a 100644 --- a/apps/ios/GuideDogs/Code/Behaviors/Guided Tour/TourDetail.swift +++ b/apps/ios/GuideDogs/Code/Behaviors/Guided Tour/TourDetail.swift @@ -41,6 +41,10 @@ class TourDetail: RouteDetailProtocol { var id: String { return event.id } + + var isExpired: Bool { + return event.isExpired + } var displayName: String { if let name = name, name.isEmpty == false { diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Guided Tours/GuidedTourAction.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Guided Tours/GuidedTourAction.swift index 58452b0d0..f1ac31d19 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Guided Tours/GuidedTourAction.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Guided Tours/GuidedTourAction.swift @@ -64,7 +64,7 @@ enum GuidedTourAction: String, Action { if detail.isGuidanceActive { return [GuidedTourActionState(.stopTour)] } else { - return [GuidedTourActionState(.startTour, isEnabled: isDefaultBehaviorActive), GuidedTourActionState(.checkForUpdates)] + return [GuidedTourActionState(.startTour, isEnabled: (isDefaultBehaviorActive && !detail.isExpired)), GuidedTourActionState(.checkForUpdates)] } } } From 57fa124561c24ea3d445f71c5e0412219bed3035 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Fri, 18 Jul 2025 02:01:26 +0100 Subject: [PATCH 46/76] Bump version to 1.7.2 --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 59e4c0ae6..93e22a649 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5555,7 +5555,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.1; + MARKETING_VERSION = 1.7.2; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5845,7 +5845,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.1; + MARKETING_VERSION = 1.7.2; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5903,7 +5903,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.1; + MARKETING_VERSION = 1.7.2; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; From a05cfb316c3695342e0c85182cab10e64fffc12b Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Fri, 25 Jul 2025 15:24:07 -0400 Subject: [PATCH 47/76] Updated the Mobility Category --- .../Settings/CalloutSettingsCellView.swift | 27 +-- .../Settings/SettingsViewController.swift | 217 ++++++++++-------- .../Code/Visual UI/Views/Settings.storyboard | 72 ++++++ 3 files changed, 198 insertions(+), 118 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift b/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift index f3f25dc89..a1661f0b1 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Controls/Settings/CalloutSettingsCellView.swift @@ -13,32 +13,29 @@ protocol CalloutSettingsCellViewDelegate: AnyObject { } internal enum CalloutSettingCellType { - case all, poi, mobility, beacon, shake + case all, poi, beacon, shake case transportation case intersection case safety } - class CalloutSettingsCellView: UITableViewCell { - + weak var delegate: CalloutSettingsCellViewDelegate? - + var type: CalloutSettingCellType! { - didSet { - guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { - return - } + didSet { + guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { + return + } - settingSwitch.isEnabled = type == .all || SettingsContext.shared.automaticCalloutsEnabled + settingSwitch.isEnabled = type == .all || SettingsContext.shared.automaticCalloutsEnabled switch type { case .all: settingSwitch.isOn = SettingsContext.shared.automaticCalloutsEnabled case .poi: settingSwitch.isOn = SettingsContext.shared.placeSenseEnabled - case .mobility: - settingSwitch.isOn = SettingsContext.shared.mobilitySenseEnabled case .beacon: settingSwitch.isOn = SettingsContext.shared.destinationSenseEnabled case .shake: @@ -52,7 +49,7 @@ class CalloutSettingsCellView: UITableViewCell { } } } - + @IBAction func onSettingValueChanged(_ sender: Any) { guard let type = type, let settingSwitch = self.accessoryView as? UISwitch else { return @@ -78,11 +75,6 @@ class CalloutSettingsCellView: UITableViewCell { SettingsContext.shared.landmarkSenseEnabled = isOn SettingsContext.shared.informationSenseEnabled = isOn log(["places", "landmarks", "info"]) - case .mobility: - SettingsContext.shared.mobilitySenseEnabled = isOn - SettingsContext.shared.safetySenseEnabled = isOn - SettingsContext.shared.intersectionSenseEnabled = isOn - log(["mobility", "safety", "intersections"]) case .beacon: SettingsContext.shared.destinationSenseEnabled = isOn log(["destination"]) @@ -100,5 +92,4 @@ class CalloutSettingsCellView: UITableViewCell { log(["safety"]) } } - } diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift index c7f880254..46f37b82d 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/SettingsViewController.swift @@ -21,14 +21,18 @@ class SettingsViewController: BaseTableViewController { case telemetry = 6 } + /// Now 7 rows in the "Callouts" section: All, Places, Mobility, Safety, Intersections, Beacon, Shake private enum CalloutsRow: Int, CaseIterable { case all = 0 case poi = 1 case mobility = 2 - case beacon = 3 - case shake = 4 + case safety = 3 + case intersection = 4 + case beacon = 5 + case shake = 6 } + /// Map each indexPath to its storyboard reuseIdentifier private static let cellIdentifiers: [IndexPath: String] = [ IndexPath(row: 0, section: Section.general.rawValue): "languageAndRegion", IndexPath(row: 1, section: Section.general.rawValue): "voice", @@ -36,24 +40,30 @@ class SettingsViewController: BaseTableViewController { IndexPath(row: 3, section: Section.general.rawValue): "volumeSettings", IndexPath(row: 4, section: Section.general.rawValue): "manageDevices", IndexPath(row: 5, section: Section.general.rawValue): "siriShortcuts", - + IndexPath(row: 0, section: Section.audio.rawValue): "mixAudio", - + + // Callouts section IndexPath(row: CalloutsRow.all.rawValue, section: Section.callouts.rawValue): "allCallouts", IndexPath(row: CalloutsRow.poi.rawValue, section: Section.callouts.rawValue): "poiCallouts", IndexPath(row: CalloutsRow.mobility.rawValue, section: Section.callouts.rawValue): "mobilityCallouts", + IndexPath(row: CalloutsRow.safety.rawValue, section: Section.callouts.rawValue): "safetyCallouts", + IndexPath(row: CalloutsRow.intersection.rawValue, section: Section.callouts.rawValue): "intersectionCallouts", IndexPath(row: CalloutsRow.beacon.rawValue, section: Section.callouts.rawValue): "beaconCallouts", IndexPath(row: CalloutsRow.shake.rawValue, section: Section.callouts.rawValue): "shakeCallouts", - + IndexPath(row: 0, section: Section.streetPreview.rawValue): "streetPreview", IndexPath(row: 0, section: Section.troubleshooting.rawValue): "troubleshooting", IndexPath(row: 0, section: Section.about.rawValue): "about", IndexPath(row: 0, section: Section.telemetry.rawValue): "telemetry" ] + /// Which sub‑rows collapse/expand under "Allow Callouts" private static let collapsibleCalloutIndexPaths: [IndexPath] = [ IndexPath(row: CalloutsRow.poi.rawValue, section: Section.callouts.rawValue), IndexPath(row: CalloutsRow.mobility.rawValue, section: Section.callouts.rawValue), + IndexPath(row: CalloutsRow.safety.rawValue, section: Section.callouts.rawValue), + IndexPath(row: CalloutsRow.intersection.rawValue, section: Section.callouts.rawValue), IndexPath(row: CalloutsRow.beacon.rawValue, section: Section.callouts.rawValue), IndexPath(row: CalloutsRow.shake.rawValue, section: Section.callouts.rawValue) ] @@ -61,7 +71,6 @@ class SettingsViewController: BaseTableViewController { // MARK: Properties @IBOutlet weak var largeBannerContainerView: UIView! - private var expandedSections: Set = [] // Section Descriptions @@ -81,11 +90,10 @@ class SettingsViewController: BaseTableViewController { super.viewWillAppear(animated) GDLogActionInfo("Opened 'Settings'") - GDATelemetry.trackScreenView("settings") self.title = GDLocalizedString("settings.screen_title") - expandedSections = [] // Initialize or reset expanded sections + expandedSections = [] // Reset expansions } override func numberOfSections(in tableView: UITableView) -> Int { @@ -96,10 +104,17 @@ class SettingsViewController: BaseTableViewController { guard let sectionType = Section(rawValue: section) else { return 0 } switch sectionType { - case .general: return expandedSections.contains(section) ? 6 : 0 - case .audio: return expandedSections.contains(section) ? 1 : 0 + case .general: + return expandedSections.contains(section) ? 6 : 0 + case .audio: + return expandedSections.contains(section) ? 1 : 0 case .callouts: - return SettingsContext.shared.automaticCalloutsEnabled && expandedSections.contains(section) ? 5 : 0 + guard expandedSections.contains(section), + SettingsContext.shared.automaticCalloutsEnabled else { + return 0 + } + // Now 7 callouts rows + return CalloutsRow.allCases.count case .streetPreview, .troubleshooting, .about, .telemetry: return expandedSections.contains(section) ? 1 : 0 } @@ -109,13 +124,15 @@ class SettingsViewController: BaseTableViewController { return expandedSections.contains(indexPath.section) ? UITableView.automaticDimension : 0 } - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + override func tableView(_ tableView: UITableView, + cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard expandedSections.contains(indexPath.section) else { - return UITableViewCell() // Return an empty cell if the section is not expanded + return UITableViewCell() } - let identifier = SettingsViewController.cellIdentifiers[indexPath] - let cell = tableView.dequeueReusableCell(withIdentifier: identifier ?? "default", for: indexPath) + let identifier = SettingsViewController.cellIdentifiers[indexPath] ?? "default" + let cell = tableView.dequeueReusableCell(withIdentifier: identifier, + for: indexPath) switch Section(rawValue: indexPath.section) { case .callouts: @@ -131,88 +148,99 @@ class SettingsViewController: BaseTableViewController { return cell } - private func configureCalloutCell(_ cell: CalloutSettingsCellView, at indexPath: IndexPath) { + private func configureCalloutCell(_ cell: CalloutSettingsCellView, + at indexPath: IndexPath) { cell.delegate = self - if let rowType = CalloutsRow(rawValue: indexPath.row) { - switch rowType { - case .all: - cell.type = .all // Ensure this matches with your CalloutSettingCellType - case .poi: - cell.type = .poi // Ensure this matches with your CalloutSettingCellType - case .mobility: - cell.type = .mobility // Ensure this matches with your CalloutSettingCellType - case .beacon: - cell.type = .beacon // Ensure this matches with your CalloutSettingCellType - case .shake: - cell.type = .shake // Ensure this matches with your CalloutSettingCellType - } + guard let rowType = CalloutsRow(rawValue: indexPath.row) else { + return + } + + switch rowType { + case .all: + cell.type = .all + case .poi: + cell.type = .poi + case .mobility: + // the "Mobility" toggle now maps to the transportation case + cell.type = .transportation + case .safety: + cell.type = .safety + case .intersection: + cell.type = .intersection + case .beacon: + cell.type = .beacon + case .shake: + cell.type = .shake } } + // MARK: Headers & Footers - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + override func tableView(_ tableView: UITableView, + titleForHeaderInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } - switch sectionType { - case .general: return GDLocalizedString("settings.section.general") - case .audio: return GDLocalizedString("settings.audio.media_controls") - case .callouts: return GDLocalizedString("menu.manage_callouts") - case .about: return GDLocalizedString("settings.section.about") - case .streetPreview: return GDLocalizedString("preview.title") - case .troubleshooting: return GDLocalizedString("settings.section.troubleshooting") - case .telemetry: return GDLocalizedString("settings.section.telemetry") + case .general: return GDLocalizedString("settings.section.general") + case .audio: return GDLocalizedString("settings.audio.media_controls") + case .callouts: return GDLocalizedString("menu.manage_callouts") + case .about: return GDLocalizedString("settings.section.about") + case .streetPreview:return GDLocalizedString("preview.title") + case .troubleshooting: + return GDLocalizedString("settings.section.troubleshooting") + case .telemetry: return GDLocalizedString("settings.section.telemetry") } } - override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { + override func tableView(_ tableView: UITableView, + titleForFooterInSection section: Int) -> String? { guard let sectionType = Section(rawValue: section) else { return nil } - - // Return description for expanded sections + if expandedSections.contains(section) { return SettingsViewController.sectionDescriptions[sectionType] } - + switch sectionType { - case .audio: return GDLocalizedString("settings.audio.mix_with_others.description") - case .streetPreview: return GDLocalizedString("preview.include_unnamed_roads.subtitle") - case .telemetry: return GDLocalizedString("settings.section.telemetry.footer") - default: return nil + case .audio: + return GDLocalizedString("settings.audio.mix_with_others.description") + case .streetPreview: + return GDLocalizedString("preview.include_unnamed_roads.subtitle") + case .telemetry: + return GDLocalizedString("settings.section.telemetry.footer") + default: + return nil } } - override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { + override func tableView(_ tableView: UITableView, + willDisplayHeaderView view: UIView, + forSection section: Int) { guard let header = view as? UITableViewHeaderFooterView else { return } - header.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleHeaderTap(_:)))) - header.tag = section // Set the tag to identify the section - - // Customize header title - header.textLabel?.textColor = .white // Change header text color to white for contrast - header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) // Make the text bold - - // Customize header appearance - header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") // Set a custom darker color - header.layer.borderColor = UIColor.clear.cgColor // Optional: set border color - header.layer.borderWidth = 0.0 // Optional: border width - header.layer.cornerRadius = 8.0 // Set rounded corners - header.layer.masksToBounds = true // Clip content to rounded corners + header.tag = section + header.addGestureRecognizer( + UITapGestureRecognizer(target: self, + action: #selector(handleHeaderTap(_:))) + ) - // Optional: Add some padding - header.contentView.layoutMargins = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15) + // Styling as before... + header.textLabel?.textColor = .white + header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18) + header.contentView.backgroundColor = UIColor(named: "HeaderBackgroundColor") + header.layer.cornerRadius = 8.0 + header.layer.masksToBounds = true + header.contentView.layoutMargins = UIEdgeInsets(top: 10, + left: 15, + bottom: 10, + right: 15) - // Add chevron icon - let chevronImageView = UIImageView(image: UIImage(systemName: "chevron.right")) // Use system image - chevronImageView.tintColor = .white // Set the color for the arrow - chevronImageView.translatesAutoresizingMaskIntoConstraints = false - - // Add chevron to header - header.contentView.addSubview(chevronImageView) - - // Set up constraints for chevron + let chevron = UIImageView(image: UIImage(systemName: "chevron.right")) + chevron.tintColor = .white + chevron.translatesAutoresizingMaskIntoConstraints = false + header.contentView.addSubview(chevron) NSLayoutConstraint.activate([ - chevronImageView.trailingAnchor.constraint(equalTo: header.contentView.trailingAnchor, constant: -15), - chevronImageView.centerYAnchor.constraint(equalTo: header.contentView.centerYAnchor), - chevronImageView.widthAnchor.constraint(equalToConstant: 20), - chevronImageView.heightAnchor.constraint(equalToConstant: 20) + chevron.trailingAnchor.constraint(equalTo: header.contentView.trailingAnchor, constant: -15), + chevron.centerYAnchor.constraint(equalTo: header.contentView.centerYAnchor), + chevron.widthAnchor.constraint(equalToConstant: 20), + chevron.heightAnchor.constraint(equalToConstant: 20) ]) } @@ -220,14 +248,12 @@ class SettingsViewController: BaseTableViewController { guard let header = gesture.view as? UITableViewHeaderFooterView else { return } let section = header.tag - // Toggle the section's expanded state if expandedSections.contains(section) { expandedSections.remove(section) - tableView.reloadSections(IndexSet(integer: section), with: .automatic) } else { expandedSections.insert(section) - tableView.reloadSections(IndexSet(integer: section), with: .automatic) } + tableView.reloadSections(IndexSet(integer: section), with: .automatic) } } @@ -237,34 +263,30 @@ extension SettingsViewController: MixAudioSettingCellDelegate { updateSetting(true) return } - let alert = UIAlertController(title: GDLocalizedString("general.alert.confirmation_title"), message: GDLocalizedString("setting.audio.mix_with_others.confirmation"), preferredStyle: .alert) - - let mixAction = UIAlertAction(title: GDLocalizedString("settings.audio.mix_with_others.title"), style: .default) { [weak self] (_) in + let mixAction = UIAlertAction(title: GDLocalizedString("settings.audio.mix_with_others.title"), + style: .default) { [weak self] _ in self?.updateSetting(false) self?.focusOnCell(cell) } alert.addAction(mixAction) alert.preferredAction = mixAction - - alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.cancel"), style: .cancel, handler: { [weak self] (_) in + alert.addAction(UIAlertAction(title: GDLocalizedString("general.alert.cancel"), + style: .cancel) { [weak self] _ in settingSwitch.isOn = false GDATelemetry.track("settings.mix_audio.cancel", with: ["context": "app_settings"]) self?.focusOnCell(cell) - })) - + }) present(alert, animated: true) } - + private func updateSetting(_ newValue: Bool) { SettingsContext.shared.audioSessionMixesWithOthers = newValue AppContext.shared.audioEngine.mixWithOthers = newValue - GDATelemetry.track("settings.mix_audio", - with: ["value": "\(SettingsContext.shared.audioSessionMixesWithOthers)", - "context": "app_settings"]) + with: ["value": "\(newValue)", "context": "app_settings"]) } private func focusOnCell(_ cell: MixAudioSettingCell) { @@ -276,22 +298,17 @@ extension SettingsViewController: MixAudioSettingCellDelegate { extension SettingsViewController: CalloutSettingsCellViewDelegate { func onCalloutSettingChanged(_ type: CalloutSettingCellType) { - guard type == .all else { - return - } - - let indexPaths = SettingsViewController.collapsibleCalloutIndexPaths - - if SettingsContext.shared.automaticCalloutsEnabled && !tableView.contains(indexPaths: indexPaths) { - tableView.insertRows(at: indexPaths, with: .automatic) - } else if !SettingsContext.shared.automaticCalloutsEnabled && tableView.contains(indexPaths: indexPaths) { - tableView.deleteRows(at: indexPaths, with: .automatic) + guard type == .all else { return } + let paths = SettingsViewController.collapsibleCalloutIndexPaths + if SettingsContext.shared.automaticCalloutsEnabled { + tableView.insertRows(at: paths, with: .automatic) + } else { + tableView.deleteRows(at: paths, with: .automatic) } } } extension SettingsViewController: LargeBannerContainerView { - func setLargeBannerHeight(_ height: CGFloat) { largeBannerContainerView.setHeight(height) tableView.reloadData() diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard index a6446a436..54d10bb1b 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard @@ -385,6 +385,78 @@ + + + + + + + + + + + + + + + + + + + + + + From eb96b826f8ae0ed7afc9d11b4fd0b2592236616d Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Mon, 28 Jul 2025 14:37:46 -0400 Subject: [PATCH 48/76] Completed the Mobility category separation updates --- .../Code/Visual UI/Views/Settings.storyboard | 228 +++++++----------- 1 file changed, 85 insertions(+), 143 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard index 54d10bb1b..f1a41f979 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard @@ -1,9 +1,8 @@ - + - - + @@ -284,8 +283,8 @@ - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + - - + + - + - - - + + + + + - + + + + + + - + - - + @@ -506,7 +483,7 @@ - + @@ -554,7 +531,7 @@ - + @@ -591,7 +568,7 @@ - + @@ -639,7 +616,7 @@ - + @@ -677,7 +654,7 @@ - + @@ -714,7 +691,7 @@ - + @@ -751,7 +728,7 @@ - + @@ -798,14 +775,14 @@ - + - From bbb36a7b066aa7bc8f51c57cb61bf431e61abbc3 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Mon, 15 Sep 2025 15:11:13 +0100 Subject: [PATCH 57/76] If an exact locale match isn't found, fall back to using only the language part to cover cases where Soundscape supports the language but not the region. fixes #112 (#208) --- .../Language/Localization/LocalizationContext.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/ios/GuideDogs/Code/Language/Localization/LocalizationContext.swift b/apps/ios/GuideDogs/Code/Language/Localization/LocalizationContext.swift index e0860259e..a1cac095e 100644 --- a/apps/ios/GuideDogs/Code/Language/Localization/LocalizationContext.swift +++ b/apps/ios/GuideDogs/Code/Language/Localization/LocalizationContext.swift @@ -160,6 +160,16 @@ class LocalizationContext { break } } + // Fallback: match only on language part if no exact match found + if _firstSupportedLocale == nil { + for preferredLocale in Locale.preferredLocales { + if let languageCode = preferredLocale.languageCode, + let locale = supportedLocales.first(where: { $0.languageCode == languageCode }) { + _firstSupportedLocale = locale + break + } + } + } return _firstSupportedLocale } From deee2e007a8e67baa7af8de2421fa135fd7c4ad2 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Fri, 12 Sep 2025 14:02:04 +0200 Subject: [PATCH 58/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.7% (1005 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.9% (1007 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 86.4% (1013 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 86.5% (1014 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 86.9% (1019 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/fa/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 72 +++++++++---------- .../en-US.lproj/Localizable.strings | 72 +++++++++---------- .../es-ES.lproj/Localizable.strings | 44 ++++++------ .../fa-IR.lproj/Localizable.strings | 5 ++ 4 files changed, 99 insertions(+), 94 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index ca0f6e6c9..cea41a2c6 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -247,11 +247,11 @@ /* */ -"general.error.location_services.authorize.instructions" = "1. Open the Settings app below\n2. Select \"Location\"\n3. Select \"Always\" or \"While Using the App\""; +"general.error.location_services.authorize.instructions" = "1. Open the Settings app below\n2. Select Location\n3. Select Always or While Using the App"; /* */ -"general.error.location_services.precise_location.instructions" = "1. Open the Settings app below\n2. Select \"Location\"\n3. Turn on \"Precise Location\""; +"general.error.location_services.precise_location.instructions" = "1. Open the Settings app below\n2. Select Location\n3. Turn on Precise Location"; /* */ @@ -299,7 +299,7 @@ /* */ -"general.error.network_connection_required.deleting_data" = "A network connection is required when deleting and reloading Soundscape's map data. Check that your phone is not in airplane mode."; +"general.error.network_connection_required.deleting_data" = "A network connection is required when deleting and reloading Soundscape's map data. Check that your phone is not in Airplane Mode."; /* */ @@ -561,7 +561,7 @@ /* */ -"voice.settings.enhanced_available" = "A higher quality version of this voice may be available. To download it and other voices, go to the Spoken Content section of the iOS accessibility settings."; +"voice.settings.enhanced_available" = "A higher quality version of this voice may be available. To download it and other voices, go to the Read & Speak section of the iOS accessibility settings."; /* */ @@ -1608,11 +1608,11 @@ /* */ -"routes.no_routes.hint.1" = "Create a route for yourself or for someone else by organising a set of markers as waypoints on a route."; +"routes.no_routes.hint.1" = "You can create a route for yourself or for someone else by organising a set of markers as waypoints on a route."; /* */ -"routes.no_routes.hint.2" = "While out on your route with Soundscape, you will be informed on arrival to each waypoint, and the Audio Beacon will automatically advance to the next waypoint."; +"routes.no_routes.hint.2" = "While out on your route with Soundscape, you will be informed on arrival to each waypoint, and the audio beacon will automatically advance to the next waypoint."; /* */ @@ -1628,7 +1628,7 @@ /* */ -"routes.tutorial.details" = "You will now return to the Soundscape home screen and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; +"routes.tutorial.details" = "You will now return to the Soundscape home screen and an audio beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; /* */ @@ -1881,7 +1881,7 @@ "filter.parks" = "Parks"; /* */ -"filter.things_to_do" = "Things to do"; +"filter.things_to_do" = "Things to Do"; /* */ @@ -2714,7 +2714,7 @@ /* */ -"location_callout_cell.nearest_road" = "Nearest road, %@."; +"location_callout_cell.nearest_road" = "Nearest road, %@"; /* */ @@ -3337,7 +3337,7 @@ /* */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Spoken Content > Voices and tapping on a voice. Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In IOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; /* */ @@ -3429,11 +3429,11 @@ /* */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to tick the \"accept the terms of use\" checkbox"; +"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to tick the \"Accept Terms of Use\" checkbox"; /* */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to untick the \"accept the terms of use\" checkbox"; +"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to untick the \"Accept Terms of Use\" checkbox"; /* */ @@ -3457,7 +3457,7 @@ /* */ -"first_launch.get_started_button.off.acc_hint" = "You must tick the \"accept the terms of use\" checkbox before you can press this button"; +"first_launch.get_started_button.off.acc_hint" = "You must tick the \"Accept Terms of Use\" checkbox before you can press this button"; /* */ @@ -3713,7 +3713,7 @@ /* */ -"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings Screen\" contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; +"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; /* */ @@ -3785,7 +3785,7 @@ /* */ -"help.text.markers.content.3" = "To experience marked places, Soundscape will automatically call out marked places as you walk by or approach them, or you can use the \"Nearby markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. You can even set an audio beacon on any marked place. When you do this, the Soundscape audio beacon you are familiar with, will be heard and you can operate it as usual."; +"help.text.markers.content.3" = "To experience marked places, Soundscape will automatically call out marked places as you walk by or approach them, or you can use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. You can even set an audio beacon on any marked place. When you do this, the Soundscape audio beacon you are familiar with, will be heard and you can operate it as usual."; /* */ @@ -3793,7 +3793,7 @@ /* */ -"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your Marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; /* */ @@ -3805,7 +3805,7 @@ /* */ -"help.text.routes.content.what" = "Routes are a series of waypoints. You will be informed on arrival to each waypoint, and the Audio Beacon will automatically advance to the next waypoint."; +"help.text.routes.content.what" = "Routes are a series of waypoints. You will be informed on arrival to each waypoint, and the audio beacon will automatically advance to the next waypoint."; /* */ @@ -3813,11 +3813,11 @@ /* */ -"help.text.routes.content.how.1" = "Creating a route:
First, go to \"Markers & Routes\", select the \"Routes\" tab, and then select the \"New Route\" button. Give the route a name and an optional description, then add waypoints as you go or pick them from your list of Markers. You can rearrange the order of the waypoints along a route at any time by editing the route."; +"help.text.routes.content.how.1" = "Creating a route:
First, go to \"Markers & Routes\", select the \"Routes\" tab, and then select the \"New Route\" button. Give the route a name and an optional description, then add waypoints as you go or pick them from your list of markers. You can rearrange the order of the waypoints along a route at any time by editing the route."; /* */ -"help.text.routes.content.how.1a" = "Following a route:
Select your route from the \"Markers & Routes\" page and then select Start Route. You will return to the home screen and Soundscape will set a beacon on the first waypoint. As you make your way through the route, the beacon advances to the next waypoint until the route is completed. If at any time you want to skip ahead or back a waypoint, press \"Next Waypoint\" or \"Previous Waypoint\"."; +"help.text.routes.content.how.1a" = "Following a route:
Select your route from the \"Markers & Routes\" page and then select \"Start Route\". You will return to the home screen and Soundscape will set a beacon on the first waypoint. As you make your way through the route, the beacon advances to the next waypoint until the route is completed. If at any time you want to skip ahead or back a waypoint, press \"Next Waypoint\" or \"Previous Waypoint\"."; /* */ @@ -3857,7 +3857,7 @@ /* */ -"osm.tag.townhall" = "Townhall"; +"osm.tag.townhall" = "Town Hall"; /* */ @@ -4153,7 +4153,7 @@ /* */ -"voice.apple.additional" = "Additional voices, including enhanced quality voices, can be downloaded in the Spoken Content section of the iOS accessibility settings."; +"voice.apple.additional" = "Additional voices, including enhanced quality voices, can be downloaded in the Read & Speak section of the iOS accessibility settings."; /* */ @@ -4221,7 +4221,7 @@ /* */ -"faq.beacon_on_address.answer" = "Yes you can. Addresses are not listed by default but can be found using the search field. To save this address so you don’t need to search for it again, you can add it as a marker from the home screen by selecting the \"add to markers\" button, or using VoiceOver actions on the beacon on the home screen."; +"faq.beacon_on_address.answer" = "Yes you can. Addresses are not listed by default but can be found using the search field. To save this address so you don’t need to search for it again, you can add it as a marker from the home screen by selecting the \"Add to Markers\" button, or using VoiceOver actions on the beacon on the home screen."; /* */ @@ -4245,7 +4245,7 @@ /* */ -"faq.turn_beacon_back_on.answer" = "Yes, you can turn the beacon back on once Soundscape turns it off by selecting the \"unmute beacon button\"; however, since Location Services is only accurate to about 10 metres, we cannot guarantee the behaviour of the beacon when you are within a few metres of your destination."; +"faq.turn_beacon_back_on.answer" = "Yes, you can turn the beacon back on once Soundscape turns it off by selecting the \"Unmute Beacon\" button; however, since Location Services is only accurate to about 10 metres, we cannot guarantee the behaviour of the beacon when you are within a few metres of your destination."; /* */ @@ -4305,15 +4305,15 @@ /* */ -"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximise your phone's battery life you should keep the screen locked whenever possible. To help minimise the impact on your iPhone battery, Soundscape has a Sleep Mode and a Snooze Mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; +"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximise your phone's battery life you should keep the screen locked whenever possible. To help minimise the impact on your iPhone battery, Soundscape has a Sleep mode and a Snooze mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; /* */ -"faq.sleep_mode_battery.question" = "How do I use Sleep Mode to minimise Soundscape’s impact on my phone battery?"; +"faq.sleep_mode_battery.question" = "How do I use Sleep mode to minimise Soundscape’s impact on my phone battery?"; /* */ -"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and mobile data until you wake it up."; +"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and mobile data until you wake it up."; /* */ @@ -4321,7 +4321,7 @@ /* */ -"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go into a low power state until you leave your current location."; +"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake Up When I Leave\" button and Soundscape will go into a low power state until you leave your current location."; /* */ @@ -4353,7 +4353,7 @@ /* */ -"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn by turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn by turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; +"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; /* */ @@ -4369,7 +4369,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not travelling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; +"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"Unmute Beacon\" button on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not travelling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"Mute Beacon\"/\"Unmute Beacon\" button on the home screen."; /* */ @@ -4385,7 +4385,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape allows you to customise three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or metres. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (metres).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behaviour:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the \"My Location\", \"Around Me\", and \"Ahead of Me\" buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; +"faq.personalize_experience.answer" = "Soundscape allows you to customise three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Voice\" to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Read & Speak (Spoken Content) > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or metres. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (metres).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behaviour:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the \"My Location\", \"Around Me\", and \"Ahead of Me\" buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; /* */ @@ -4405,7 +4405,7 @@ /* */ -"faq.tip.finding_bus_stops" = "You can find nearby bus stops by selecting the \"Public Transport\" filter in the Nearby Places list."; +"faq.tip.finding_bus_stops" = "You can find nearby bus stops by selecting the \"Public Transport\" filter in the Places Nearby list."; /* */ @@ -4421,7 +4421,7 @@ /* */ -"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as Markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; +"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; /* */ @@ -4452,10 +4452,10 @@ "osm.tag.fast_food" = "Fast Food"; "osm.tag.coffee_shop" = "Coffee Shop"; "whats_new.1_2_0.0.title" = "Shake to Repeat the Last Callout"; -"whats_new.1_2_0.0.description" = "You can now shake your device to repeat the last callout. To enable this feature, switch on the 'Repeat Callouts' toggle in settings."; +"whats_new.1_2_0.0.description" = "You can now shake your device to repeat the last callout. To enable this feature, switch on the \"Repeat Callouts\" toggle in settings."; "whats_new.1_2_0.1.title" = "Beacon Mute Distance Setting"; "whats_new.1_2_0.2.title" = "Categories in Places Nearby"; -"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as Public Transport, Food & Drink, etc."; +"whats_new.1_2_0.2.description" = "You can now filter the Places Nearby list by categories such as Public Transport, Food & Drink, etc."; "settings.about.title.copyright" = "Copyright Notices"; "first_launch.permissions.motion" = "Motion & Fitness"; "osm.tag.bar" = "Bar"; @@ -4482,11 +4482,11 @@ "whats_new.1_3_0.0.title" = "Bose Frames Support"; "whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; "whats_new.1_3_0.1.title" = "Testing in Texas"; -"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; +"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the main menu."; "beacon.action.navilens" = "Launch NaviLens"; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is"; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; "troubleshooting.tile_server_url" = "Tile Server URL"; "troubleshooting.user_data" = "User Data"; -"troubleshooting.user_data.button" = "Delete All markers and routes"; +"troubleshooting.user_data.button" = "Delete All Markers and Routes"; "troubleshooting.user_data.explanation" = "Delete all map data, including saved markers and routes. This action cannot be undone."; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index e5bb444e7..ab32d7782 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -197,10 +197,10 @@ "general.error.location_services.authorize.description" = "Soundscape uses your location to find and tell you about the places and things around you. The app needs your permission to use Location Services."; /* Error message to authorize location services. Quotes written as \" Keep newlines (\n) between sentences.. {NumberedPlaceholder="\n"} */ -"general.error.location_services.authorize.instructions" = "1. Open the Settings app below\n2. Select \"Location\"\n3. Select \"Always\" or \"While Using the App\""; +"general.error.location_services.authorize.instructions" = "1. Open the Settings app below\n2. Select Location\n3. Select Always or While Using the App"; /* Error message to turn on precise location. Ensure "Precise Location" is translated the same as in the iOS Settings app under Maps > Location > Precise Location (this refers to an Apple feature called "Precise Location" in US English). Quotes written as \". Keep newlines (\n) between sentences. {NumberedPlaceholder="\n"} */ -"general.error.location_services.precise_location.instructions" = "1. Open the Settings app below\n2. Select \"Location\"\n3. Turn on \"Precise Location\""; +"general.error.location_services.precise_location.instructions" = "1. Open the Settings app below\n2. Select Location\n3. Turn on Precise Location"; /* Error message to open Soundscape to resume setting location services. "Location Services" is an iOS term that can be found in the Privacy section in the iPhone Settings app. {NumberedPlaceholder="Soundscape"} */ "general.error.location_services_resume" = "Open Soundscape to resume Location Services"; @@ -240,7 +240,7 @@ "general.error.network_connection_required" = "Network Connection Required"; /* Error message that the internet is not connected. {NumberedPlaceholder="Soundscape"} */ -"general.error.network_connection_required.deleting_data" = "A network connection is required when deleting and reloading Soundscape's map data. Check that your phone is not in airplane mode."; +"general.error.network_connection_required.deleting_data" = "A network connection is required when deleting and reloading Soundscape's map data. Check that your phone is not in Airplane Mode."; //------------------------------------------------------------------------------ // MARK: Errors (BLE) @@ -496,7 +496,7 @@ "voice.settings.enhanced_available.title" = "Enhanced Voice Available!"; /* This is an alert presented to the user when they select a default version of a voice which has an enhanced version to inform them that they can download an enhanced version from the iOS Settings app, "Spoken Content" should be translated the same way it is in the iOS Settings app under Accessibility > Spoken Content, {NumberedPlaceholder="iOS"} */ -"voice.settings.enhanced_available" = "A higher quality version of this voice may be available. To download it and other voices, go to the Spoken Content section of the iOS accessibility settings."; +"voice.settings.enhanced_available" = "A higher quality version of this voice may be available. To download it and other voices, go to the Read & Speak section of the iOS accessibility settings."; /* This is one of the options available to the user when they are presented with the alert described by the key ""voice.settings.enhanced_available" */ "voice.settings.enhanced_available.button" = "Use Current Version"; @@ -587,7 +587,7 @@ "troubleshooting.user_data" = "User Data"; /* Label for the button that allows user to delete all map data, including saved markers and routes */ -"troubleshooting.user_data.button" = "Delete All markers and routes"; +"troubleshooting.user_data.button" = "Delete All Markers and Routes"; /* Explanation for the user data section in troubleshooting */ "troubleshooting.user_data.explanation" = "Delete all map data, including saved markers and routes. This action cannot be undone."; @@ -1377,10 +1377,10 @@ "routes.no_routes.title" = "Getting Started with Route Waypoints"; /* This text is displayed to the user when they navigate to the routes list but have not yet created any routes. It explains how a route is a set of ordered markers. */ -"routes.no_routes.hint.1" = "Create a route for yourself or for someone else by organizing a set of markers as waypoints on a route."; +"routes.no_routes.hint.1" = "You can create a route for yourself or for someone else by organizing a set of markers as waypoints on a route."; /* This text is displayed to the user when they navigate to the routes list but have not yet created any routes. It explains that the beacon will automatically shift between the route waypoints as they walk the route. */ -"routes.no_routes.hint.2" = "While out on your route with Soundscape, you will be informed on arrival to each waypoint, and the Audio Beacon will automatically advance to the next waypoint."; +"routes.no_routes.hint.2" = "While out on your route with Soundscape, you will be informed on arrival to each waypoint, and the audio beacon will automatically advance to the next waypoint."; /* Text for the first paragraph displayed when the waypoints list is empty for a route */ "route.no_waypoints.hint.1" = "Name your route and add an optional description. You can then add waypoints as you go or pick them from your list of markers."; @@ -1392,7 +1392,7 @@ "routes.tutorial.title" = "Hear Your Waypoints on Your Journey"; /* Explanation of the route guidance feature that is presented to the user the first time that they try to start route guidance {NumberedPlaceholder="Soundscape"} */ -"routes.tutorial.details" = "You will now return to the Soundscape home screen and an Audio Beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; +"routes.tutorial.details" = "You will now return to the Soundscape home screen and an audio beacon will be placed on your first waypoint. When you arrive at the waypoint, the beacon will advance to the next waypoint on your route."; /* Callout indicating a the user has arrived at the final waypoint in their route and the route experience is now complete. */ "routes.callout.complete" = "Route complete!"; @@ -1589,7 +1589,7 @@ "filter.parks" = "Parks"; /* Filter, Things To Do */ -"filter.things_to_do" = "Things to do"; +"filter.things_to_do" = "Things to Do"; /* Filters, Groceries & Convenience Stores */ "filter.groceries" = "Groceries & Convenience Stores"; @@ -2271,7 +2271,7 @@ "location_callout_cell.marked_location" = "Marked Location"; /* Location Callout Cell for the nearest road, %@ road name, "Nearest road, <27th Avenue West>" {NumberedPlaceholder="%@"} */ -"location_callout_cell.nearest_road" = "Nearest road, %@."; +"location_callout_cell.nearest_road" = "Nearest road, %@"; /* Location Callout Cell, Nearest road and beacon set on, %1$@ road name %2$@ location, "Nearest road, <27th Avenue West>. Beacon was set on ." {NumberedPlaceholder="%1$@", "%2$@"} */ "location_callout_cell.nearest_road.beacon_set_on" = "Nearest road, %1$@. Beacon was set on %2$@."; @@ -2798,7 +2798,7 @@ "settings.help.section.home_screen_buttons" = "\"Hear My Surroundings\" Buttons"; /* Help content describing how user can choose a voice and download additional voices */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Spoken Content > Voices and tapping on a voice. Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In IOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; /* Help Page Title, Offline */ "help.offline.page_title" = "Why is Soundscape working offline?"; @@ -2871,10 +2871,10 @@ "terms_of_use.accept_checkbox.acc_label" = "Accept Terms of Use"; /* Double tap to check the accept terms of use checkbox. Quotes written as \" */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to check the \"accept the terms of use\" checkbox"; +"terms_of_use.accept_checkbox.on.acc_hint" = "Double tap to check the \"Accept Terms of Use\" checkbox"; /* Double tap to uncheck the accept terms of use checkbox. Quotes written as \" */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to uncheck the \"accept the terms of use\" checkbox"; +"terms_of_use.accept_checkbox.off.acc_hint" = "Double tap to uncheck the \"Accept Terms of Use\" checkbox"; /* Terms of use accept checkbox has been checked */ "terms_of_use.accept_checkbox.on.acc_value" = "Checked"; @@ -2896,7 +2896,7 @@ //------------------------------------------------------------------------------ /* Button title accessibility hint. Quotes written as \" */ -"first_launch.get_started_button.off.acc_hint" = "You must check the \"accept the terms of use\" checkbox before you can press this button"; +"first_launch.get_started_button.off.acc_hint" = "You must check the \"Accept Terms of Use\" checkbox before you can press this button"; /* Notification, Welcome message */ "first_launch.welcome_text" = "Welcome! Before we get started, we need to go through some setup and ask for several permissions. Press the Next button to start."; @@ -3095,7 +3095,7 @@ "help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off by going to the \"Manage Callouts\" section of the \"Settings\" screen and then toggling the \"Allow Callouts\" button. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; /* Notification, Information how to turn on callouts continued. Ensure that "Manage Callouts" is translated the same as `menu.manage_callouts` and "Allow callouts" is translated the same as `callouts.allow_callouts`. Quotes written as \" {NumberedPlaceholder="","","
"} */ -"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings Screen\" contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; +"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; /* Notification, Information about what My Location does. Ensure that "My Location" is translated the same as `directions.my_location`. Quotes written as \" {NumberedPlaceholder="",""} */ "help.text.my_location.what" = "The \"My Location\" button quickly gives you information that helps you figure out where you currently are. \"My Location\" tells you about your current location including things like the direction you are facing, where nearby roads or intersections are, and where nearby points of interest are."; @@ -3149,13 +3149,13 @@ "help.text.markers.content.2" = "You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. You can mark any place or address, but you can also mark things that aren't usually on maps, for example, entrances to buildings or parks, push-to-walk buttons, pedestrian crossings or bridges, bus stops or even your dog’s favorite tree and use these as references along your walk."; /* Notification, Markers content continued {NumberedPlaceholder="Soundscape"} */ -"help.text.markers.content.3" = "To experience marked places, Soundscape will automatically call out marked places as you walk by or approach them, or you can use the \"Nearby markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. You can even set an audio beacon on any marked place. When you do this, the Soundscape audio beacon you are familiar with, will be heard and you can operate it as usual."; +"help.text.markers.content.3" = "To experience marked places, Soundscape will automatically call out marked places as you walk by or approach them, or you can use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. You can even set an audio beacon on any marked place. When you do this, the Soundscape audio beacon you are familiar with, will be heard and you can operate it as usual."; /* Notification, Creating Markers help content, Quotation marks are written as \" */ "help.text.creating_markers.content.1" = "You can create markers in three ways: searching for the place you would like to save using the search bar, finding somewhere using the \"Places Nearby\" button, or using the \"Current Location\" button, all of which can be found on the Soundscape home screen. Once you have found the place you would like, selecting it will take you to the \"Location Details\" page. On this page, select the button called \"Save as Marker\"."; /* Notification, Creating Markers help content continued, Quotation marks are written as \" */ -"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your Marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; /* Notification, Customizing Markers help content. "Markers & Routes" should be translated the same as the string with key 'search.view_markers'. Quotes written as \" */ "help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, select the marker from the \"Markers\" tab of the \"Markers & Routes\" page, and then select the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; @@ -3164,16 +3164,16 @@ "help.text.customizing_markers.content.2" = "From this Edit screen, you can also delete a marker if you no longer need it."; /* Help content explaining what the "routes" feature is */ -"help.text.routes.content.what" = "Routes are a series of waypoints. You will be informed on arrival to each waypoint, and the Audio Beacon will automatically advance to the next waypoint."; +"help.text.routes.content.what" = "Routes are a series of waypoints. You will be informed on arrival to each waypoint, and the audio beacon will automatically advance to the next waypoint."; /* Help content explaining when a user might choose to use the routes feature */ "help.text.routes.content.when" = "You may want to create and use a route somewhere you know to make sure you keep on track, or you may want to use it as a tool to help familiarize yourself along a new journey."; /* Help content explaining how a user can create a route. Quotes written as \" */ -"help.text.routes.content.how.1" = "Creating a route:
First, go to \"Markers & Routes\", select the \"Routes\" tab, and then select the \"New Route\" button. Give the route a name and an optional description, then add waypoints as you go or pick them from your list of Markers. You can rearrange the order of the waypoints along a route at any time by editing the route."; +"help.text.routes.content.how.1" = "Creating a route:
First, go to \"Markers & Routes\", select the \"Routes\" tab, and then select the \"New Route\" button. Give the route a name and an optional description, then add waypoints as you go or pick them from your list of markers. You can rearrange the order of the waypoints along a route at any time by editing the route."; /* Help content explaining how a user can follow a route. Quotes written as \" */ -"help.text.routes.content.how.1a" = "Following a route:
Select your route from the \"Markers & Routes\" page and then select Start Route. You will return to the home screen and Soundscape will set a beacon on the first waypoint. As you make your way through the route, the beacon advances to the next waypoint until the route is completed. If at any time you want to skip ahead or back a waypoint, press \"Next Waypoint\" or \"Previous Waypoint\"."; +"help.text.routes.content.how.1a" = "Following a route:
Select your route from the \"Markers & Routes\" page and then select \"Start Route\". You will return to the home screen and Soundscape will set a beacon on the first waypoint. As you make your way through the route, the beacon advances to the next waypoint until the route is completed. If at any time you want to skip ahead or back a waypoint, press \"Next Waypoint\" or \"Previous Waypoint\"."; /* Help content explaining how a user can edit a route. Quotes written as \" */ "help.text.routes.content.how.2" = "Editing a route:
Select your route on the \"Markers & Routes\" page and then select \"Edit Route\". From here you can add and remove waypoints, as well as edit the name and description of the route."; @@ -3225,7 +3225,7 @@ "osm.tag.dangerous_area" = "Dangerous Area"; /* Open Street Map term. This refers to a village, town or city townhall, which is often the seat of the mayor, or may be merely a community meeting place. */ -"osm.tag.townhall" = "Townhall"; +"osm.tag.townhall" = "Town Hall"; /* Open Street Map term. For flights of steps on footways and paths.. */ "osm.tag.steps" = "Steps"; @@ -3497,7 +3497,7 @@ "whats_new.1_2_0.0.title" = "Shake to Repeat the Last Callout"; /* Description of shake to repeat feature */ -"whats_new.1_2_0.0.description" = "You can now shake your device to repeat the last callout. To enable this feature, switch on the 'Repeat Callouts' toggle in settings."; +"whats_new.1_2_0.0.description" = "You can now shake your device to repeat the last callout. To enable this feature, switch on the \"Repeat Callouts\" toggle in settings."; /* Title of the beacon vicinity distance feature */ "whats_new.1_2_0.1.title" = "Beacon Mute Distance Setting"; @@ -3509,7 +3509,7 @@ "whats_new.1_2_0.2.title" = "Categories in Places Nearby"; /* Description of the categories in places nearby feature */ -"whats_new.1_2_0.2.description" = "You can now filter the places nearby list by categories such as Public Transit, Food & Drink, etc."; +"whats_new.1_2_0.2.description" = "You can now filter the Places Nearby list by categories such as Public Transit, Food & Drink, etc."; /* Title of the Bose Frames support feature */ "whats_new.1_3_0.0.title" = "Bose Frames Support"; @@ -3521,10 +3521,10 @@ "whats_new.1_3_0.1.title" = "Testing in Texas"; /* Description of the request for testing in Texas */ -"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the Send Feedback button from the main menu."; +"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the main menu."; /* Description of how users can download new voices. "Settings" and "Spoken Content" should be translated in the same way they are translated in the iOS Settin gs app. {NumberedPlaceholder="iOS"} */ -"voice.apple.additional" = "Additional voices, including enhanced quality voices, can be downloaded in the Spoken Content section of the iOS accessibility settings."; +"voice.apple.additional" = "Additional voices, including enhanced quality voices, can be downloaded in the Read & Speak section of the iOS accessibility settings."; // MARK: - FAQs @@ -3581,7 +3581,7 @@ "faq.beacon_on_address.question" = "Can I set a beacon on an address?"; /* Marker - A location that has been marked as important by the user or application. This can be an address, a business or a custom place such as an entrance, a bus stop or a bench., A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. 'Voiceover' is an iPhone feature to help people who are visually impaired use the iPhone. Quotes written as \" {NumberedPlaceholder="VoiceOver"} */ -"faq.beacon_on_address.answer" = "Yes you can. Addresses are not listed by default but can be found using the search field. To save this address so you don’t need to search for it again, you can add it as a marker from the home screen by selecting the \"add to markers\" button, or using VoiceOver actions on the beacon on the home screen."; +"faq.beacon_on_address.answer" = "Yes you can. Addresses are not listed by default but can be found using the search field. To save this address so you don’t need to search for it again, you can add it as a marker from the home screen by selecting the \"Add to Markers\" button, or using VoiceOver actions on the beacon on the home screen."; /* A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. */ "faq.beacon_on_home.question" = "How do I set a beacon on my home?"; @@ -3599,7 +3599,7 @@ "faq.turn_beacon_back_on.question" = "Can I turn the beacon back on when I am close to my destination?"; /* Preserve meter unit - Do not convert. A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. "Location Services" refers to the feature of the same name in iOS. It should be translated in the same manner that it is in the Settings app under Settings > Privacy > Location Services. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Quotes written as \" {NumberedPlaceholder="Soundscape","10"} */ -"faq.turn_beacon_back_on.answer" = "Yes, you can turn the beacon back on once Soundscape turns it off by selecting the \"unmute beacon button\"; however, since Location Services is only accurate to about 10 meters, we cannot guarantee the behavior of the beacon when you are within a few meters of your destination."; +"faq.turn_beacon_back_on.answer" = "Yes, you can turn the beacon back on once Soundscape turns it off by selecting the \"Unmute Beacon\" button; however, since Location Services is only accurate to about 10 meters, we cannot guarantee the behavior of the beacon when you are within a few meters of your destination."; /* Intersection - A junction where two or more roads meet or cross. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.road_names.question" = "Why does Soundscape call out road names twice when I approach an intersection?"; @@ -3646,19 +3646,19 @@ "faq.battery_impact.question" = "How does Soundscape impact my iPhone’s battery?"; /* Sleep - To put the app in an idle state for a period of time. Snooze - To put the app in an idle state that is interrupted by user movement. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape","iPhone"} */ -"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximize your phone's battery life you should keep the screen locked whenever possible. To help minimize the impact on your iPhone battery, Soundscape has a Sleep Mode and a Snooze Mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; +"faq.battery_impact.answer" = "Battery life varies significantly depending on the model and age of your iPhone. The biggest drain on your battery is having the screen on, so to maximize your phone's battery life you should keep the screen locked whenever possible. To help minimize the impact on your iPhone battery, Soundscape has a Sleep mode and a Snooze mode. To further reduce battery usage, when you aren’t using Soundscape, you should force close it via your iPhone’s App Switcher."; /* Sleep - To put the app in an idle state for a period of time. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.sleep_mode_battery.question" = "How do I use Sleep Mode to minimize Soundscape’s impact on my phone battery?"; +"faq.sleep_mode_battery.question" = "How do I use Sleep mode to minimize Soundscape’s impact on my phone battery?"; /* Sleep - To put the app in an idle state for a period of time. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. "Location Services" refers to the feature of the same name in iOS. It should be translated in the same manner that it is in the Settings app under Settings > Privacy > Location Services. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and cellular data until you wake it up."; +"faq.sleep_mode_battery.answer" = "To put Soundscape in Sleep mode, select the \"Sleep\" button in the top right-hand corner of the home screen. When you select this, Soundscape will stop using Location Services and cellular data until you wake it up."; /* Snooze - To put the app in an idle state that is interrupted by user movement. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.snooze_mode_battery.question" = "How do I use Snooze mode to minimize Soundscape’s impact on my phone battery?"; /* Snooze - To put the app in an idle state that is interrupted by user movement. Sleep - To put the app in an idle state for a period of time. Wake Up - To restore the app from a sleep (idle) state. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze Mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake up when I leave\" button and Soundscape will go into a low power state until you leave your current location."; +"faq.snooze_mode_battery.answer" = "To put Soundscape in Snooze mode, select the \"Sleep\" button in the top right-hand corner of the home screen. Once Soundscape’s in Sleep mode, select the \"Wake Up When I Leave\" button and Soundscape will go into a low power state until you leave your current location."; /* A question about how different headsets affect the phone's battery consumption */ "faq.headset_battery_impact.question" = "How does my choice of headphones affect my phone's battery life?"; @@ -3682,7 +3682,7 @@ "faq.difference_from_map_apps.question" = "How is Soundscape different from other map apps?"; /* Wayfinding - The process or activity of ascertaining one’s position and planning and following a route. 3D sound is where the audio through your headphones sounds as though it is coming from a given direction, as if it was actually coming from a speaker. Intersection - A junction where two or more roads meet or cross. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using spatial audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn by turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn by turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; +"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; /* Wayfinding - The process or activity of ascertaining one’s position and planning and following a route. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.use_with_wayfinding_apps.question" = "How do I use Soundscape with a wayfinding app?"; @@ -3694,7 +3694,7 @@ "faq.controlling_what_you_hear.question" = "How do I control what I hear and when I hear it in Soundscape?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. A 'beacon' or 'audio beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Intersection - A junction where two or more roads meet or cross. Point of interest - A specific location that someone may find useful or interesting. Snooze - To put the app in an idle state that is interrupted by user movement. Sleep - To put the app in an idle state for a period of time. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"unmute beacon button\" on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not traveling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"mute beacon\"/\"unmute beacon\" button on the home screen."; +"faq.controlling_what_you_hear.answer" = "Soundscape provides several ways to control what you hear and when:\n\n1. Immediately stop all audio: Double tap the screen with two fingers to immediately turn off all audio, including any callout that is currently playing and the beacon if it is on. Callouts will resume automatically when you approach the next intersection or point of interest, but the audible beacon will not. Select the \"Unmute Beacon\" button on the home screen to resume hearing the beacon.\n2. Stop automatic callouts: When you are not traveling or have reached a destination, you probably will not need Soundscape to continue to notify you of things around you. Instead of exiting the app, you can put Soundscape in Snooze mode and it will wake up when you leave, or you can put Soundscape in Sleep mode and it will stay off until you wake it up. Alternatively, you can select \"Settings\" from the menu and turn all callouts off in the \"Manage Callouts\" section.\n3. Stop the beacon: There are several scenarios for which you might set a destination, but not need the audible beacon on. For example, you may know exactly how to get to your destination, but you just want to get automatic updates about how far away you are. Or, you may know roughly how to get to your destination, and you only need the audio beacon when you're almost there. Whatever the case, you can choose when to hear the beacon by toggling the \"Mute Beacon\"/\"Unmute Beacon\" button on the home screen."; /* A frequently asked question about how the user should hold their phone */ "faq.holding_phone_flat.question" = "Do I need to hold the phone in my hand all the time?"; @@ -3706,7 +3706,7 @@ "faq.personalize_experience.question" = "In what ways can I personalize my Soundscape experience?"; /* All of the terms in the string "Settings > Accessibility > Spoken Content > Voices" should be translated such that they are consistant with those in the iOS Settings app. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. 'Nearby Markers' is the name of one of the buttons in the app. 'Voiceover' is an iPhone feature to help people who are visually impaired use the iPhone. 'Audio Ducking' is the name of an accessibility feature on the iPhone which reduces the volume of an app while 'Voiceover' is speaking. 'Touch ID' is the name of the iPhone feature for unlocking your phone using your finger print. 'Face ID' is the name of the iPhone feature for unlocking your phone using your face. 'Passcode' and 'iPhone Unlock' are all names of sections in the iPhone 'Settings' app. 'My Location', 'Around Me' and 'Ahead of Me' are buttons in the Soundscape app. {NumberedPlaceholder="Soundscape", "VoiceOver","Touch ID", "Face ID","iOS"} */ -"faq.personalize_experience.answer" = "Soundscape allows you to customize three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select Voice to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Spoken Content > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or meters. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (meters).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behavior:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the \"My Location\", \"Around Me\", and \"Ahead of Me\" buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; +"faq.personalize_experience.answer" = "Soundscape allows you to customize three key aspects of the callouts you hear as you are walking:\n\n1. Voice: You can choose which of the available voices on iOS you would like Soundscape to use, as well as the speed at which callouts are spoken. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Voice\" to adjust the Speaking Rate and Voice settings. Additional voices, including enhanced quality voices, can be downloaded in the iOS Settings app at Settings > Accessibility > Read & Speak (Spoken Content) > Voices.\n2. Measuring Distance: Soundscape allows you to hear all distances in either feet or meters. From the Menu, select \"Settings\" and then from \"General Settings\" select \"Language & Region\". The Units of Measure section allows you to toggle between two options: Imperial (feet) and Metric (meters).\n3. Markers: You can mark your world with anything you care about. You can mark things that are personal and relevant to you like your home, your office and your preferred grocery store. Then Soundscape will automatically call out marked places as you walk by or approach them, or you can also use the \"Nearby Markers\" button at the bottom of the home screen to hear a spatial callout of marked places around you. These markers will remain personal to you and will not be available to anyone else.\n\nIn addition to the above, the following settings can influence Soundscape's behavior:\n\n1. VoiceOver Tips: When VoiceOver tips are turned ON, you will hear more information about all the buttons on the main screen. You can turn on VoiceOver tips by navigating to the iOS Settings app and going to Accessibility > VoiceOver > Verbosity, and turning the Speak Hints setting on.\n2. Audio Ducking: Soundscape is designed to work with Audio Ducking turned OFF. When Audio Ducking is on, automatic callouts can be difficult to hear if VoiceOver is used simultaneously. We recommend turning Audio Ducking off to make it easier to hear all automatic callouts. Audio ducking can be turned off in VoiceOver settings or via the VoiceOver rotor.\n3. Touch ID or Face ID to Unlock: Setting your phone to unlock using Touch ID or Face ID will make unlocking the phone fast and easy, and in turn, allow you to access the \"My Location\", \"Around Me\", and \"Ahead of Me\" buttons as quickly as possible when you are on the go. Set up Touch ID or Face ID unlocking in the iOS Settings app."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape","Open Street Map"} */ "faq.what_is_osm.question" = "What is Open Street Map and why do we use it for Soundscape?"; @@ -3723,7 +3723,7 @@ "faq.tip.setting_beacon_on_address" = "You can set a beacon on any address. From the home screen, tap on the search bar and then type the address. After selecting the address in the search results, a \"Location Details\" screen will be shown containing the option to \"Start Audio Beacon\" on the address. In this way, you can set a beacon on businesses, places, points of interest, and residences that are not in Open Street Map."; /* 'Nearby Places' is a screen in the app that shows a list of places that are close to the user. Quotes written as \" */ -"faq.tip.finding_bus_stops" = "You can find nearby bus stops by selecting the \"Public Transit\" filter in the Nearby Places list."; +"faq.tip.finding_bus_stops" = "You can find nearby bus stops by selecting the \"Public Transit\" filter in the Places Nearby list."; /* Preserve meters unit - Do not convert. The 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. {NumberedPlaceholder="50"} */ "faq.tip.turning_beacon_off" = "You can turn on and off the rhythmic sound of the beacon using the mute button on the home screen. If the beacon is muted, you will still get updates about the distance to your destination every 50 meters or so."; @@ -3735,7 +3735,7 @@ "faq.tip.hold_phone_flat" = "Soundscape works best when you hold the phone flat with the screen facing the sky and the top of the phone pointing away from you."; /* Marker - A location that has been marked as important by the user or application. This can be an address, a business or a custom place such as an entrance, a bus stop or a bench. The 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. 'Manage Markers' is the name of one of the options in the Soundscape menu. Quotes written as \" */ -"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as Markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; +"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; /* Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. */ "faq.tip.two_finger_double_tap" = "Tapping the screen twice with two fingers will silence any active callouts."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 3a8c2255a..eaa133ac5 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -247,11 +247,11 @@ /* */ -"general.error.location_services.authorize.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona \"Ubicación\"\n3. Selecciona \"Siempre\" o \"Cuando se use la app\""; +"general.error.location_services.authorize.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona Ubicación\n3. Selecciona Siempre o Cuando se use la app"; /* */ -"general.error.location_services.precise_location.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona \"Ubicación\"\n3. Activa \"Ubicación exacta\""; +"general.error.location_services.precise_location.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona Ubicación\n3. Activa Ubicación exacta"; /* */ @@ -267,7 +267,7 @@ /* */ -"general.error.location_services_enable_instructions.2" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona el botón Atrás (en Ajustes)\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización \n4. Activa Localización"; +"general.error.location_services_enable_instructions.2" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona el botón Atrás (en Ajustes)\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización\n4. Activa Localización"; /* */ @@ -299,7 +299,7 @@ /* */ -"general.error.network_connection_required.deleting_data" = "Se requiere una conexión de red para eliminar y volver a cargar datos de mapas de Soundscape. Comprueba que el teléfono no se encuentra en el modo avión."; +"general.error.network_connection_required.deleting_data" = "Se requiere una conexión de red para eliminar y volver a cargar datos de mapas de Soundscape. Comprueba que el teléfono no se encuentra en el Modo Avión."; /* */ @@ -563,7 +563,7 @@ /* */ -"voice.settings.enhanced_available" = "Es posible que exista una versión de mayor calidad para esta voz. Para descargarla y descargar otras voces, ve a la sección Contenido leído de los ajustes de accesibilidad de iOS."; +"voice.settings.enhanced_available" = "Es posible que exista una versión de mayor calidad para esta voz. Para descargarla y descargar otras voces, ve a la sección Lectura y voz de los ajustes de accesibilidad de iOS."; /* */ @@ -1587,7 +1587,7 @@ /* */ -"routes.no_routes.hint.1" = "Crea una ruta para ti o para otra persona organizando un conjunto de marcadores como puntos de referencia en una ruta."; +"routes.no_routes.hint.1" = "Puedes crear una ruta para ti o para otra persona organizando un conjunto de marcadores como puntos de referencia en una ruta."; /* */ @@ -2678,7 +2678,7 @@ /* */ -"location_callout_cell.nearest_road" = "Carretera más cercana, %@."; +"location_callout_cell.nearest_road" = "Carretera más cercana, %@"; /* */ @@ -3294,11 +3294,11 @@ /* */ -"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación Ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación Ajustes de iOS, tienes que ir a Accesibilidad > Contenido leído > Voces y pulsar en una voz. En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: pulsa en \"Ajustes\" desde el menú principal y, a continuación, en \"Ajustes generales\", selecciona \"Voz\"."; +"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación Ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación Ajustes de iOS, tienes que ir a Accesibilidad > Lectura y voz > Voces y pulsar en una voz. (En las versiones de iOS anteriores a la 26, \"Lectura y voz\" se llama \"Contenido leído\".) En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: pulsa en \"Ajustes\" desde el menú principal y, a continuación, en \"Ajustes generales\", selecciona \"Voz\"."; /* */ -"help.offline.page_title" = "¿Por qué está Soundscape funcionando sin conexión?"; +"help.offline.page_title" = "¿Por qué Soundscape está funcionando sin conexión?"; /* */ @@ -3386,11 +3386,11 @@ /* */ -"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"aceptar los términos de uso\""; +"terms_of_use.accept_checkbox.on.acc_hint" = "Pulsa dos veces para activar la casilla \"Aceptar los términos de uso\""; /* */ -"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"aceptar los términos de uso\""; +"terms_of_use.accept_checkbox.off.acc_hint" = "Pulsa dos veces para desactivar la casilla \"Aceptar los términos de uso\""; /* */ @@ -3414,7 +3414,7 @@ /* */ -"first_launch.get_started_button.off.acc_hint" = "Debes marcar la casilla \"aceptar los términos de uso\" antes de poder pulsar este botón"; +"first_launch.get_started_button.off.acc_hint" = "Debes marcar la casilla \"Aceptar los términos de uso\" antes de poder pulsar este botón"; /* */ @@ -3734,7 +3734,7 @@ /* */ -"help.text.remote_control.how" = "

Puedes obtener acceso a las siguientes funciones de Soundscape con los botones de control multimedia de los auriculares:


⏯ Reproducir/Pausa: Silenciar los avisos actuales y, si la señal de audio está establecida, activar o desactivar el audio.

⏭ Siguiente: Aviso \"Mi ubicación\".

⏮ Anterior: Repetir el último aviso.

⏩ Saltar adelante: Activar y desactivar los avisos.

⏪ Saltar atrás: Aviso \"Alrededor de mí\".

"; +"help.text.remote_control.how" = "

Puedes obtener acceso a las siguientes funciones de Soundscape con los botones de control multimedia de los auriculares:


⏯ Reproducir/Pausa: Silenciar los avisos actuales y, si la señal de audio está establecida, activar o desactivar el audio.

⏭ Siguiente: Aviso \"Mi ubicación\".

⏮ Anterior: Repetir el último aviso.

⏩ Saltar adelante: Activar y desactivar los avisos.

⏪ Saltar atrás: Aviso \"Alrededor de mí\".

"; /* */ @@ -4110,7 +4110,7 @@ /* */ -"voice.apple.additional" = "Se pueden descargar voces adicionales, incluidas las de calidad mejorada, en la sección Contenido leído de los ajustes de accesibilidad de iOS."; +"voice.apple.additional" = "Se pueden descargar voces adicionales, incluidas las de calidad mejorada, en la sección Lectura y voz de los ajustes de accesibilidad de iOS."; /* */ @@ -4178,7 +4178,7 @@ /* */ -"faq.beacon_on_address.answer" = "Sí. Las direcciones no se muestran de manera predeterminada pero se pueden encontrar en el campo de búsqueda. Para guardar esta dirección y no tener que buscarla de nuevo, puedes agregarla como marcador desde la pantalla principal seleccionando el botón \"agregar a marcadores\" o mediante acciones de VoiceOver en la señal de la pantalla principal."; +"faq.beacon_on_address.answer" = "Sí. Las direcciones no se muestran de manera predeterminada pero se pueden encontrar en el campo de búsqueda. Para guardar esta dirección y no tener que buscarla de nuevo, puedes agregarla como marcador desde la pantalla principal seleccionando el botón \"Agregar a marcadores\" o mediante acciones de VoiceOver en la señal de la pantalla principal."; /* */ @@ -4202,7 +4202,7 @@ /* */ -"faq.turn_beacon_back_on.answer" = "Sí, puedes volver a activar la señal cuando Soundscape la haya desactivado. Para ello, selecciona el botón \"reactivar señal\". Sin embargo, dada la baja precisión de Localización a unos 10 metros, no podemos garantizar el comportamiento de la señal cuando te encuentres a pocos metros de tu destino."; +"faq.turn_beacon_back_on.answer" = "Sí, puedes volver a activar la señal cuando Soundscape la haya desactivado. Para ello, selecciona el botón \"Reactivar señal\". Sin embargo, dada la baja precisión de Localización a unos 10 metros, no podemos garantizar el comportamiento de la señal cuando te encuentres a pocos metros de tu destino."; /* */ @@ -4278,7 +4278,7 @@ /* */ -"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape esté en el modo de suspensión, selecciona el botón \"Reactivar cuando Salga\" y Soundscape entrará en un estado de bajo consumo hasta que te vayas de la ubicación actual."; +"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape esté en el modo de suspensión, selecciona el botón \"Reactivar cuando salga\" y Soundscape entrará en un estado de bajo consumo hasta que te vayas de la ubicación actual."; /* */ @@ -4342,7 +4342,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape , así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona Voz para ajustar la velocidad de habla y la configuración de voz . Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en la aplicación Ajustes de iOS en Ajustes > Accesibilidad > Contenido leído > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar todas las distancias en pies o metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre dos opciones: Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados al pasar o acercarte a ellos, o también puedes usar el botón \"Marcadores cercanos\" en la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Estos marcadores seguirán siendo personales para ti y no estarán disponibles para nadie más.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver están activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver navegando a la aplicación Ajustes de iOS y yendo a Accesibilidad > VoiceOver > Verbosidad, y activando la configuración Leer indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, los avisos automáticos pueden resultar difíciles de oír si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los avisos de VoiceOver o a través del rotor de VoiceOver.\n3. Desbloqueo con Touch ID o Face ID: configurar el teléfono para que se desbloquee con Touch ID o Face ID hará que desbloquear el teléfono sea rápido y fácil y, a su vez, te permitirá acceder a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" lo más rápido posible cuando estés en movimiento. Configura el desbloqueo con Touch ID o Face ID en la aplicación Ajustes de iOS ."; +"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape , así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Voz\" para ajustar la velocidad de habla y la configuración de voz . Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en la aplicación Ajustes de iOS en Ajustes > Accesibilidad > Lectura y voz (Contenido leído) > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar todas las distancias en pies o metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre dos opciones: Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados al pasar o acercarte a ellos, o también puedes usar el botón \"Marcadores cercanos\" en la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Estos marcadores seguirán siendo personales para ti y no estarán disponibles para nadie más.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver están activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver navegando a la aplicación Ajustes de iOS y yendo a Accesibilidad > VoiceOver > Verbosidad, y activando la configuración Leer indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, los avisos automáticos pueden resultar difíciles de oír si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los avisos de VoiceOver o a través del rotor de VoiceOver.\n3. Desbloqueo con Touch ID o Face ID: configurar el teléfono para que se desbloquee con Touch ID o Face ID hará que desbloquear el teléfono sea rápido y fácil y, a su vez, te permitirá acceder a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" lo más rápido posible cuando estés en movimiento. Configura el desbloqueo con Touch ID o Face ID en la aplicación Ajustes de iOS ."; /* */ @@ -4378,7 +4378,7 @@ /* */ -"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas regularmente, establece tus paradas de recogida y salida como Marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y obtendrás actualizaciones periódicas sobre lo cerca que estás a tu parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás recibiendo actualizaciones de la distancia por el camino."; +"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas regularmente, establece tus paradas de recogida y salida como marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y obtendrás actualizaciones periódicas sobre lo cerca que estás a tu parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás recibiendo actualizaciones de la distancia por el camino."; /* */ @@ -4422,7 +4422,7 @@ "osm.tag.bar" = "Bar"; "osm.tag.fast_food" = "Comida rápida"; "osm.tag.ice_cream" = "Heladería"; -"whats_new.1_2_0.0.description" = "Ahora puedes agitar tu dispositivo para repetir el último aviso. Para habilitar esta función, activa el botón 'Repetir Avisos' en los ajustes."; +"whats_new.1_2_0.0.description" = "Ahora puedes agitar tu dispositivo para repetir el último aviso. Para habilitar esta función, activa el botón \"Repetir avisos\" en los ajustes."; "whats_new.1_2_0.1.description" = "Ahora puedes ajustar la distancia a la que la señal se silencia automáticamente cuando te acercas. Simplemente ve a la configuración de la señal de audio y mueve el control deslizante \"Distancia de silenciar el audio\"."; "donation.body" = "Por favor, apoya el desarrollo continuo de la aplicación Soundscape Community donando en nuestra página de recaudación de fondos. Cada donación nos acerca un paso más a nuestra visión de ayudar a crear un mundo donde TODOS tengan el mismo acceso a la información sobre su entorno a través de nuestra tecnología que mejora la vida."; "menu.donate" = "Donar"; @@ -4441,7 +4441,7 @@ "help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien."; "whats_new.1_3_0.0.title" = "Compatibilidad con Bose Frames"; "whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; -"whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón Enviar comentarios del menú principal."; +"whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón \"Enviar comentarios\" del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "beacon.action.navilens" = "Iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; @@ -4453,7 +4453,7 @@ "routes.reverse_name_format" = "%@ de regreso"; "route_detail.action.start_reversed_route" = "Iniciar ruta de regreso"; "faq.tip.reverse_route" = "Cuando seleccionas \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden de regreso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; -"help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y rutas\" y, a continuación, \"Iniciar ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vayas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior."; +"help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y rutas\" y, a continuación, \"Iniciar ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vayas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior\"."; "location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una señal de audio según qué tan cerca esté esta ubicación"; "beacon.suggest_navilens" = "Usa el botón NaviLens para llegar a tu destino."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; diff --git a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings index 06853a8a1..af100e81f 100644 --- a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings @@ -2470,3 +2470,8 @@ "donation.link" = "رفتن به صفحه جمع‌آوری کمک‌های مالی"; + + + + + From 8663dd8b1dc30c84bbcd633f849e3a08aaa7248a Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Sat, 1 Nov 2025 21:51:34 +0100 Subject: [PATCH 59/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.4% (1001 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.5% (1003 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.6% (1004 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/fa/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 18 +++++++++--------- .../en-US.lproj/Localizable.strings | 18 +++++++++--------- .../es-ES.lproj/Localizable.strings | 16 ++++++++-------- .../fa-IR.lproj/Localizable.strings | 3 +++ 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index cea41a2c6..f78b8f019 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -3793,7 +3793,7 @@ /* */ -"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customise this marker. You can change its name and also add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; /* */ @@ -3825,11 +3825,11 @@ /* */ -"help.text.routes.content.how.3" = "Sharing a route:
Select your route on the \"Markers & Routes\" page and then select the option to \"Share\" using all of the usual share options available to you."; +"help.text.routes.content.how.3" = "Sharing a route:
Select your route on the \"Markers & Routes\" page and then select \"Share\". You can now use any of the usual share options available to you."; /* */ -"help.using_headsets.airpods.what" = "Soundscape supports spatial audio with dynamic head tracking when using compatible AirPods. Once they're connected, sensors in the AirPods tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with AirPods connected, you do not need to hold your phone for Soundscape to work correctly."; +"help.using_headsets.airpods.what" = "Soundscape supports spatial audio with dynamic head tracking when using compatible AirPods. Once they're connected, sensors in the AirPods tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with AirPods connected, you do not need to hold your phone for the app to work correctly."; /* */ @@ -4253,7 +4253,7 @@ /* */ -"faq.road_names.answer" = "To accommodate a variety of intersection layouts, Soundscape describes intersections as segments of roadways that depart from a common point. Soundscape uses spatial audio to indicate the name of the road that goes to the left, the name of the road that continues straight ahead, and the name of the road that goes to the right, in that order. If the description of the intersection begins with the road you are on rather than one to the left, then the intersection is a T with the road you are on continuing ahead and a road intersecting from the right. Similarly, if the description only includes a road to the left and to the right, you will know that the road you are on ends at a T ahead of you. This method of describing intersections also supports the case when a road changes name at an intersection."; +"faq.road_names.answer" = "To accommodate a variety of intersection layouts, Soundscape describes intersections as segments of roadways that depart from a common point. Soundscape uses spatial audio to indicate the names of the roads that go to the left, straight ahead, and to the right, in that order. If the description of the intersection begins with the road you are on rather than one to the left, then the intersection forms a sideways T with the road you are on continuing ahead and a road intersecting from the right. Similarly, if the description only includes a road to the left and to the right, you will know that the road you are on ends at a T ahead of you. This method of describing intersections also supports the case when a road changes name at an intersection."; /* */ @@ -4277,7 +4277,7 @@ /* */ -"faq.miss_a_callout.answer" = "Soundscape has a list of your recent callouts so that you can revisit callouts that you might have missed. To find this, tap on the search bar on the Soundscape home screen. At the bottom of this page, there is a section for \"Recent Callouts\" where the callout you missed will be listed. Alternatively, you can shake your phone to repeat the last callout. From the \"Manage Callouts\" section of the \"Settings\" screen, turn on \"Repeat Callouts\"."; +"faq.miss_a_callout.answer" = "Soundscape has a list of your recent callouts so that you can revisit callouts you might have missed. To find this, tap the search bar on the home screen. At the bottom of this page, there is a section for \"Recent Callouts\" where the callout you missed will be listed. Alternatively, you can shake your phone to repeat the last callout. To enable this, go to the \"Manage Callouts\" section of the \"Settings\" screen and then turn on \"Repeat Callouts\"."; /* */ @@ -4345,7 +4345,7 @@ /* */ -"faq.mobile_data_use.answer" = "The amount of mobile data used depends on how you use Soundscape. We have designed Soundscape to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to download them again every time you go back to somewhere you’ve already been. To reduce the amount of mobile data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; +"faq.mobile_data_use.answer" = "The amount of mobile data used depends on how you use Soundscape. We have designed the app to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to redownload them every time you go back to somewhere you’ve been before. To reduce the amount of mobile data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; /* */ @@ -4477,10 +4477,10 @@ "help.using_headsets.bose_frames.title" = "Using Bose Frames"; "help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; -"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
Support for the Bose Frames is new and we would love to hear your feedback. You can contact us by choosing the \"Send Feedback\" option in the menu."; -"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly."; +"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; +"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; "whats_new.1_3_0.0.title" = "Bose Frames Support"; -"whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; +"whats_new.1_3_0.0.description" = "Soundscape now supports head tracking with the Alto or Rondo versions of the Bose Frames. Once they're connected, your Bose Frames will tell Soundscape where you are facing, helping Soundscape to improve your audio experience. To connect your Bose Frames to Soundscape, go to the \"Head Tracking Headphones\" item in the Soundscape menu."; "whats_new.1_3_0.1.title" = "Testing in Texas"; "whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the main menu."; "beacon.action.navilens" = "Launch NaviLens"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index ab32d7782..8d2fba89b 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -3155,7 +3155,7 @@ "help.text.creating_markers.content.1" = "You can create markers in three ways: searching for the place you would like to save using the search bar, finding somewhere using the \"Places Nearby\" button, or using the \"Current Location\" button, all of which can be found on the Soundscape home screen. Once you have found the place you would like, selecting it will take you to the \"Location Details\" page. On this page, select the button called \"Save as Marker\"."; /* Notification, Creating Markers help content continued, Quotation marks are written as \" */ -"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. You can change its name, as well as add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; +"help.text.creating_markers.content.2" = "You will now have the option to customize this marker. You can change its name and also add an annotation that will be called out along with the marker to provide extra information. Then select the \"Done\" button to save your marker."; /* Notification, Customizing Markers help content. "Markers & Routes" should be translated the same as the string with key 'search.view_markers'. Quotes written as \" */ "help.text.customizing_markers.content.1" = "If you want to rename a marker you previously created, or add an annotation to it, select the marker from the \"Markers\" tab of the \"Markers & Routes\" page, and then select the \"Edit Marker\" button. You can use this to give markers descriptive or useful nicknames, as well as give them a longer description using the annotation field."; @@ -3179,10 +3179,10 @@ "help.text.routes.content.how.2" = "Editing a route:
Select your route on the \"Markers & Routes\" page and then select \"Edit Route\". From here you can add and remove waypoints, as well as edit the name and description of the route."; /* Help content explaining how a user can share a route. "Share" should be translated in the same way as it is for the key `share.title`. Quotes written as \" */ -"help.text.routes.content.how.3" = "Sharing a route:
Select your route on the \"Markers & Routes\" page and then select the option to \"Share\" using all of the usual share options available to you."; +"help.text.routes.content.how.3" = "Sharing a route:
Select your route on the \"Markers & Routes\" page and then select \"Share\". You can now use any of the usual share options available to you."; /* Help content describing how Apple AirPods work with Soundscape and which versions are supported {NumberedPlaceholder="Soundscape","AirPods"} */ -"help.using_headsets.airpods.what" = "Soundscape supports spatial audio with dynamic head tracking when using compatible AirPods. Once they're connected, sensors in the AirPods tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with AirPods connected, you do not need to hold your phone for Soundscape to work correctly."; +"help.using_headsets.airpods.what" = "Soundscape supports spatial audio with dynamic head tracking when using compatible AirPods. Once they're connected, sensors in the AirPods tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with AirPods connected, you do not need to hold your phone for the app to work correctly."; /* Information on when users can use Apple AirPods headphones with Soundscape, {NumberedPlaceholder="Soundscape","AirPods"} */ "help.using_headsets.airpods.when" = "You can use AirPods with Soundscape anytime you would normally use Soundscape. Using AirPods provides you with high quality audio and allows you to have a more hands-free experience."; @@ -3194,7 +3194,7 @@ "help.using_headsets.airpods.how.2" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your AirPods to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; /* Help content describing how Bose Frames work with Soundscape and which versions are supported {NumberedPlaceholder="Soundscape","Bose Frames"} */ -"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly."; +"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; /* Information on when users can use Bose Frames headphones with Soundscape, {NumberedPlaceholder="Soundscape","Bose Frames"} */ "help.using_headsets.bose_frames.when" = "You can use Bose Frames with Soundscape anytime you would normally use Soundscape. Using Bose Frames provides you with high quality audio that does not occlude environmental audio and allows you to have a more hands-free experience."; @@ -3209,7 +3209,7 @@ "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; /* Trouble shooting information for Bose Frames */ -"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
Support for the Bose Frames is new and we would love to hear your feedback. You can contact us by choosing the \"Send Feedback\" option in the menu."; +"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; //------------------------------------------------------------------------------ // MARK: - OSM Tags @@ -3515,7 +3515,7 @@ "whats_new.1_3_0.0.title" = "Bose Frames Support"; /* Description of the Bose Frames support feature */ -"whats_new.1_3_0.0.description" = "Soundscape now supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for Soundscape to work correctly. To get started, go to the \"Head Tracking Headphones\" item in the Soundscape menu to connect your Bose Frames and follow the instructions on screen. Note that you will need to pair your Bose Frames to your phone in the Bluetooth settings before connecting them in Soundscape."; +"whats_new.1_3_0.0.description" = "Soundscape now supports head tracking with the Alto or Rondo versions of the Bose Frames. Once they're connected, your Bose Frames will tell Soundscape where you are facing, helping Soundscape to improve your audio experience. To connect your Bose Frames to Soundscape, go to the \"Head Tracking Headphones\" item in the Soundscape menu."; /* Title of the request for testing in Texas */ "whats_new.1_3_0.1.title" = "Testing in Texas"; @@ -3605,7 +3605,7 @@ "faq.road_names.question" = "Why does Soundscape call out road names twice when I approach an intersection?"; /* Intersection - A junction where two or more roads meet or cross. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. 'Spatial audio' is where the audio through your headphones sounds as though it is coming from a given direction, as if it was actually coming from a speaker. 'T' here refers to the shape of the intersection, it's a three way intersection that resembles the shape of the letter 'T'. {NumberedPlaceholder="Soundscape"} */ -"faq.road_names.answer" = "To accommodate a variety of intersection layouts, Soundscape describes intersections as segments of roadways that depart from a common point. Soundscape uses spatial audio to indicate the name of the road that goes to the left, the name of the road that continues straight ahead, and the name of the road that goes to the right, in that order. If the description of the intersection begins with the road you are on rather than one to the left, then the intersection is a T with the road you are on continuing ahead and a road intersecting from the right. Similarly, if the description only includes a road to the left and to the right, you will know that the road you are on ends at a T ahead of you. This method of describing intersections also supports the case when a road changes name at an intersection."; +"faq.road_names.answer" = "To accommodate a variety of intersection layouts, Soundscape describes intersections as segments of roadways that depart from a common point. Soundscape uses spatial audio to indicate the names of the roads that go to the left, straight ahead, and to the right, in that order. If the description of the intersection begins with the road you are on rather than one to the left, then the intersection forms a sideways T with the road you are on continuing ahead and a road intersecting from the right. Similarly, if the description only includes a road to the left and to the right, you will know that the road you are on ends at a T ahead of you. This method of describing intersections also supports the case when a road changes name at an intersection."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.why_not_every_business.question" = "Why doesn’t Soundscape announce every business that I pass?"; @@ -3623,7 +3623,7 @@ "faq.miss_a_callout.question" = "What if I don't understand a callout or miss it because of ambient noise?"; /* Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Quotes written as \". {NumberedPlaceholder="Soundscape"} */ -"faq.miss_a_callout.answer" = "Soundscape has a list of your recent callouts so that you can revisit callouts that you might have missed. To find this, tap on the search bar on the Soundscape home screen. At the bottom of this page, there is a section for \"Recent Callouts\" where the callout you missed will be listed. Alternatively, you can shake your phone to repeat the last callout. From the \"Manage Callouts\" section of the \"Settings\" screen, turn on \"Repeat Callouts\"."; +"faq.miss_a_callout.answer" = "Soundscape has a list of your recent callouts so that you can revisit callouts you might have missed. To find this, tap the search bar on the home screen. At the bottom of this page, there is a section for \"Recent Callouts\" where the callout you missed will be listed. Alternatively, you can shake your phone to repeat the last callout. To enable this, go to the \"Manage Callouts\" section of the \"Settings\" screen and then turn on \"Repeat Callouts\"."; // MARK: How Soundscape Works @@ -3676,7 +3676,7 @@ "faq.mobile_data_use.question" = "How much cellular data does Soundscape use?"; /* Wi-Fi - The set of standards for delivering digital information over high-frequency, wireless local area networks, defined by IEEE 802.11. 'Force close' is referring to the way to completely close an iPhone app rather than just putting it in to the background. "Sleep" should be translated the in the same way as the string for key "sleep.sleep". Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.mobile_data_use.answer" = "The amount of cellular data used depends on how you use Soundscape. We have designed Soundscape to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to download them again every time you go back to somewhere you’ve already been. To reduce the amount of cellular data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; +"faq.mobile_data_use.answer" = "The amount of cellular data used depends on how you use Soundscape. We have designed the app to use only a small amount of data when you’re out and about by doing things like saving points as you walk around so you don’t need to redownload them every time you go back to somewhere you’ve been before. To reduce the amount of cellular data you use, make sure you are connected to Wi-Fi whenever possible, particularly to download the app. When you are not using Soundscape, you should use the \"Sleep\" button to put Soundscape to sleep or force close the app."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.difference_from_map_apps.question" = "How is Soundscape different from other map apps?"; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index eaa133ac5..f29ca2c14 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -3782,11 +3782,11 @@ /* */ -"help.text.routes.content.how.3" = "Uso compartido de una ruta:
selecciona tu ruta en la página \"Marcadores y rutas\" y, a continuación, la opción \"Compartir ruta\" utilizando todas las opciones de uso compartido habituales disponibles para ti."; +"help.text.routes.content.how.3" = "Uso compartido de una ruta:
selecciona tu ruta en la página \"Marcadores y rutas\" y, a continuación, \"Compartir\". Ahora puedes utilizar cualquiera de las opciones de uso compartido habituales disponibles para ti."; /* */ -"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que Soundscape funcione bien."; +"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que la aplicación funcione bien."; /* */ @@ -4210,7 +4210,7 @@ /* */ -"faq.road_names.answer" = "Para adaptarse a una variedad de formas de intersecciones, Soundscape describe los cruces como segmentos de carreteras que parten de un punto común. Soundscape usa audio espacial para indicar el nombre de la carretera que va a la izquierda, el nombre de la carretera que continúa de frente y el nombre de la carretera que va a la derecha, en ese orden. Si la descripción del cruce comienza con la carretera en la que te encuentras en lugar de una a la izquierda, la intersección es una T con la carretera en la que te encuentras continuando adelante y una carretera que cruza desde la derecha. De manera similar, si la descripción solo incluye una carretera a la izquierda y a la derecha, sabrás que la carretera en la que te encuentras termina en una T delante de ti. Este método de describir cruces también admite la situación de una carretera que cambia de nombre en un cruce."; +"faq.road_names.answer" = "Para adaptarse a una variedad de formas de intersecciones, Soundscape describe los cruces como segmentos de carreteras que parten de un punto común. Soundscape usa audio espacial para indicar los nombres de las carreteras que van hacia la izquierda, hacia adelante y hacia la derecha, en ese orden. Si la descripción del cruce comienza con la carretera en la que te encuentras en lugar de una a la izquierda, la intersección forma una T lateral con la carretera en la que te encuentras continuando adelante y una carretera que cruza desde la derecha. De manera similar, si la descripción solo incluye una carretera a la izquierda y a la derecha, sabrás que la carretera en la que te encuentras termina en una T delante de ti. Este método de describir cruces también admite la situación de una carretera que cambia de nombre en un cruce."; /* */ @@ -4234,7 +4234,7 @@ /* */ -"faq.miss_a_callout.answer" = "Soundscape tiene una lista de tus avisoss recientes para que puedas volver a visitar los avisos que te hayas perdido. Para ello, pulsa en la barra de búsqueda de la pantalla principal de Soundscape. En la parte inferior de esta página, hay una sección de \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar el teléfono para repetir el último aviso. En la sección \"Administrar avisos\" de la pantalla \"Ajustes\", activa la opción \"Repetir avisos\"."; +"faq.miss_a_callout.answer" = "Soundscape tiene una lista de tus avisoss recientes para que puedas volver a visitar los avisos que te hayas perdido. Para ello, pulsa en la barra de búsqueda de la pantalla principal. En la parte inferior de esta página, hay una sección de \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar tu teléfono para repetir el último aviso. Para habilitar esta función, ve a la sección \"Administrar avisos\" de la pantalla \"Ajustes\" y activa \"Repetir avisos\"."; /* */ @@ -4302,7 +4302,7 @@ /* */ -"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado Soundscape para que consuma solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, guardando puntos mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que regreses a un sitio donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a una red Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para suspender Soundscape, o bien cierra totalmente la aplicación."; +"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado la aplicación para que consuma solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, guardando puntos mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que regreses a un sitio donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a una red Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para poner Soundscape en suspensión, o bien cierra totalmente la aplicación."; /* */ @@ -4436,11 +4436,11 @@ "help.using_headsets.bose_frames.when" = "Puedes usar Bose Frames en cualquier momento con Soundscape. El uso de Bose Frames te proporciona un audio de alta calidad que no dificulta la audición ambiental y te permite tener una experiencia mayor de manos libres."; "help.using_headsets.bose_frames.how.3" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén habilitados en la configuración de Soundscape, podrás usarlos en las Bose Frames para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; "help.using_headsets.bose_frames.how.1" = "Conexión de un dispositivo:
ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; -"help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
Si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación de Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
La compatibilidad con las Bose Frames es nueva y nos encantaría escuchar tus comentarios. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; +"help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
Si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación de Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
Nos encantaría escuchar tus comentarios sobre la compatibilidad con las Bose Frames. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; "help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión hacia dónde estás mirando. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. Puedes repetir esta calibración, en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; -"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien."; +"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que la aplicación funcione bien."; "whats_new.1_3_0.0.title" = "Compatibilidad con Bose Frames"; -"whats_new.1_3_0.0.description" = "Ahora Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los Bose Frames conectadas, no es necesario sostener el teléfono para que Soundscape funcione bien. Para empezar, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; +"whats_new.1_3_0.0.description" = "Ahora Soundscape admite seguimiento de cabeza con las versiones Alto o Rondo de Bose Frames. Cuando se conecten, tus Bose Frames indicarán a Soundscape hacia dónde estás mirando, lo que ayudará a Soundscape a mejorar tu experiencia de audio. Para conectar tus Bose Frames a Soundscape, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón \"Enviar comentarios\" del menú principal."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "beacon.action.navilens" = "Iniciar NaviLens"; diff --git a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings index af100e81f..5ae8edaf4 100644 --- a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings @@ -2475,3 +2475,6 @@ + + + From dce7f1af0931594e892d4df9965d58eb771e1b5f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:28:33 +0000 Subject: [PATCH 60/76] Fix VoiceOver reading lowercase text in What's New page (#221) * Remove accessibilityString() function and all accessibility label overrides Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --- .../String Extensions/String+Extension.swift | 4 ---- .../New Feature Announcement/FeaturePageViewController.swift | 4 ---- .../New Feature Announcement/NewFeaturesViewController.swift | 2 +- .../Settings/VersionHistoryTableViewController.swift | 3 --- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/apps/ios/GuideDogs/Code/App/Framework Extensions/String Extensions/String+Extension.swift b/apps/ios/GuideDogs/Code/App/Framework Extensions/String Extensions/String+Extension.swift index 74100798f..c96de692f 100644 --- a/apps/ios/GuideDogs/Code/App/Framework Extensions/String Extensions/String+Extension.swift +++ b/apps/ios/GuideDogs/Code/App/Framework Extensions/String Extensions/String+Extension.swift @@ -131,10 +131,6 @@ extension String { return output } - - func accessibilityString() -> String { - return self.lowercased().replacingOccurrences(of: "callout", with: "call out") - } public func urlEncoded(plusForSpace: Bool = true) -> String? { let allowed = NSMutableCharacterSet.alphanumeric() diff --git a/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/FeaturePageViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/FeaturePageViewController.swift index 021bce253..7c84b1471 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/FeaturePageViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/FeaturePageViewController.swift @@ -19,7 +19,6 @@ class FeaturePageViewController: UIViewController { var image: UIImage? var header: String! var attributedBody: NSMutableAttributedString! - var bodyAccessibilityLabel: String! var contentView: UIView! var buttonLabel: String? var buttonAccessibilityHint: String? @@ -29,7 +28,6 @@ class FeaturePageViewController: UIViewController { vc.image = feature.localizedImage vc.header = feature.localizedTitle - vc.bodyAccessibilityLabel = feature.localizedAccessibilityDescription.accessibilityString() let description = feature.localizedDescription vc.attributedBody = NSMutableAttributedString(string: description) @@ -53,9 +51,7 @@ class FeaturePageViewController: UIViewController { // Do any additional setup after loading the view. featureImageView.image = image headerLabel.text = header - headerLabel.accessibilityLabel = header.accessibilityString() bodyTextView.attributedText = attributedBody - bodyTextView.attributedText.accessibilityLabel = bodyAccessibilityLabel bodyTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) bodyTextView.textContainer.lineFragmentPadding = 0 diff --git a/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/NewFeaturesViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/NewFeaturesViewController.swift index ef7f9506a..48e1f7a17 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/NewFeaturesViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Controls/New Feature Announcement/NewFeaturesViewController.swift @@ -113,7 +113,7 @@ class NewFeaturesViewController: UIViewController { UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: vc.headerLabel) } else { let total = self?.featurePages.count ?? index + 1 - UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: "\(index + 1) of \(total). \(vc.header.accessibilityString()). \(vc.bodyAccessibilityLabel ?? "")") + UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: "\(index + 1) of \(total). \(vc.header ?? "")") } self?.refreshControls() diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/VersionHistoryTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/VersionHistoryTableViewController.swift index 19dd53d2c..7c4dae60b 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/VersionHistoryTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Settings/VersionHistoryTableViewController.swift @@ -56,10 +56,7 @@ class VersionHistoryTableViewController: BaseTableViewController { let feature = features(for: indexPath.section)[indexPath.row] cell.textLabel?.text = feature.localizedTitle - cell.textLabel?.accessibilityLabel = feature.localizedTitle.accessibilityString() - cell.detailTextLabel?.text = feature.localizedDescription - cell.detailTextLabel?.accessibilityLabel = feature.localizedAccessibilityDescription.accessibilityString() return cell } From 4ed29db5352b4eab2d44b1dc1dba603dc003a7ba Mon Sep 17 00:00:00 2001 From: RDMurray Date: Tue, 18 Nov 2025 16:18:32 +0000 Subject: [PATCH 61/76] Refine search region parameters and manage MKLocalSearch instance in SearchResultsUpdater, fixes #215 (#222) The MKLocalSearch instance was not stored, resulting in the search being canceled, resulting in very few if any search results. fixes Search Functionality Is Too Strict and Does Not Return Expected Results Fixes #215 --- .../Helpers/Search/SearchResultsUpdater.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Search/SearchResultsUpdater.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Search/SearchResultsUpdater.swift index d7c08aeea..18c879582 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Search/SearchResultsUpdater.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Search/SearchResultsUpdater.swift @@ -38,6 +38,7 @@ class SearchResultsUpdater: NSObject { private(set) var searchBarButtonClicked = false private var location: CLLocation? var context: Context = .partialSearchText + private var localSearch: MKLocalSearch? // MARK: Initialization @@ -125,9 +126,9 @@ extension SearchResultsUpdater: UISearchResultsUpdating { let request = MKLocalSearch.Request() request.naturalLanguageQuery = searchText let coordinate = self.location!.coordinate - request.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 75000, longitudinalMeters: 75000) - let search = MKLocalSearch(request: request) - search.start(completionHandler: searchWithTextCallback) + request.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000) + localSearch = MKLocalSearch(request: request) + localSearch!.start(completionHandler: searchWithTextCallback) } } @@ -170,12 +171,13 @@ extension SearchResultsUpdater: UISearchBarDelegate { let request = MKLocalSearch.Request() request.naturalLanguageQuery = searchText let coordinate = self.location!.coordinate - request.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 75000, longitudinalMeters: 75000) - let search = MKLocalSearch(request: request) - search.start(completionHandler: searchWithTextCallback) + request.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 5000, longitudinalMeters: 5000) + localSearch = MKLocalSearch(request: request) + localSearch!.start(completionHandler: searchWithTextCallback) } private func searchWithTextCallback(using response: MKLocalSearch.Response?, error: Error?) -> Void { + localSearch = nil // finished with the MKLocalSearch instance guard error == nil else { return } From ac5acc48c3b38c60334605feec0678d070eac45d Mon Sep 17 00:00:00 2001 From: RDMurray Date: Wed, 26 Nov 2025 16:00:16 +0000 Subject: [PATCH 62/76] Remove GDAStateMachine implementation and references (#219) The primary purpose is to fix the bug that crashed when soundscape was in the background and there was a call on the device. Still needs a lot of cleanup but it works and the crash is gone. * Remove GDAStateMachine implementation and delegate files * Remove GDAStateMachine references from project files * bump version and remove macos support which is of no use to anyone. * Refactor DiscreteAudioPlayer to serialize state access and mutations on the player's queue * Fix initialization of audioEngine in testInit method * Update apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift, hush() calls eventHush() Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * remove extra space Update apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor CalloutStateMachine state management and remove unused states --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 37 +- .../xcschemes/Soundscape.xcscheme | 8 + .../Code/App/Soundscape-Bridging-Header.h | 2 +- .../GuideDogs/Code/Audio/AudioEngine.swift | 32 +- .../Code/Audio/DiscreteAudioPlayer.swift | 53 +- .../Helpers/CalloutStateMachine.swift | 562 +++++++----------- .../Helpers/GDAStateMachine/GDAStateMachine.h | 91 --- .../Helpers/GDAStateMachine/GDAStateMachine.m | 481 --------------- .../GDAStateMachine/GDAStateMachineDelegate.h | 29 - apps/ios/UnitTests.xctestplan | 3 +- .../ios/UnitTests/Audio/AudioEngineTest.swift | 18 +- 11 files changed, 291 insertions(+), 1025 deletions(-) delete mode 100644 apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.h delete mode 100644 apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.m delete mode 100644 apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachineDelegate.h diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 7585d8045..7e129b3ee 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -568,7 +568,6 @@ B9533FF924B4DB2400605B07 /* IntersectionFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9533FF824B4DB2400605B07 /* IntersectionFinder.swift */; }; B9533FFB24B4DCC100605B07 /* IntersectionSearchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9533FFA24B4DCC100605B07 /* IntersectionSearchResult.swift */; }; B954678A24EB2B02006866EF /* SecondaryRoadsContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B954678924EB2B02006866EF /* SecondaryRoadsContext.swift */; }; - B962DD792914E39A00CED854 /* GDAStateMachine.m in Sources */ = {isa = PBXBuildFile; fileRef = B962DD772914E39900CED854 /* GDAStateMachine.m */; }; B96755A3251D21AF00B366F6 /* TintedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B96755A2251D21AF00B366F6 /* TintedImageView.swift */; }; B97140DA204835BC00B15BD0 /* Roundabout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B97140D9204835BB00B15BD0 /* Roundabout.swift */; }; B97140DE2048896800B15BD0 /* RoadDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B97140DD2048896800B15BD0 /* RoadDirection.swift */; }; @@ -1365,9 +1364,6 @@ B954678924EB2B02006866EF /* SecondaryRoadsContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SecondaryRoadsContext.swift; path = "Code/Data/Spatial Data/SecondaryRoadsContext.swift"; sourceTree = ""; }; B9546B211E54AB36002776D4 /* Soundscape.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Soundscape.entitlements; path = Assets/PropertyLists/Soundscape.entitlements; sourceTree = ""; }; B958961125536F01005B1AE8 /* MixAudioSettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MixAudioSettingCell.swift; path = "Code/Visual UI/Controls/Settings/MixAudioSettingCell.swift"; sourceTree = ""; }; - B962DD732914E39900CED854 /* GDAStateMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDAStateMachine.h; sourceTree = ""; }; - B962DD762914E39900CED854 /* GDAStateMachineDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDAStateMachineDelegate.h; sourceTree = ""; }; - B962DD772914E39900CED854 /* GDAStateMachine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDAStateMachine.m; sourceTree = ""; }; B96755A2251D21AF00B366F6 /* TintedImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TintedImageView.swift; path = "Code/Visual UI/Controls/TintedImageView.swift"; sourceTree = ""; }; B97140D9204835BB00B15BD0 /* Roundabout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Roundabout.swift; path = Code/Data/Models/Helpers/Roundabout.swift; sourceTree = ""; }; B97140DD2048896800B15BD0 /* RoadDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RoadDirection.swift; path = Code/Data/Models/Helpers/RoadDirection.swift; sourceTree = ""; }; @@ -2028,7 +2024,6 @@ 286DC6AC21E6B5F9001CD88A /* Helpers */ = { isa = PBXGroup; children = ( - B962DD722914E39900CED854 /* GDAStateMachine */, 28F94F5D2485AE0A0010D2B3 /* BehaviorBase.swift */, 286DC6AA21E6857D001CD88A /* Events.swift */, 286DC6AD21E6B61B001CD88A /* Verbosity.swift */, @@ -3629,16 +3624,6 @@ path = "Code/Sensors/Geolocation/GPX Simulator"; sourceTree = ""; }; - B962DD722914E39900CED854 /* GDAStateMachine */ = { - isa = PBXGroup; - children = ( - B962DD732914E39900CED854 /* GDAStateMachine.h */, - B962DD772914E39900CED854 /* GDAStateMachine.m */, - B962DD762914E39900CED854 /* GDAStateMachineDelegate.h */, - ); - path = GDAStateMachine; - sourceTree = ""; - }; B998914920305A34000E2220 /* Motion */ = { isa = PBXGroup; children = ( @@ -5281,7 +5266,6 @@ 6A4891BB2A5E66DE0002D146 /* ExternalNavigationApps.swift in Sources */, 623E0104244767BB0081CA5B /* LocationParameters.swift in Sources */, 622AB2F6263767A8006BB729 /* MKMapViewDelegate+Extensions.swift in Sources */, - B962DD792914E39A00CED854 /* GDAStateMachine.m in Sources */, 6258B38A2469DB220051F60B /* UniversalLinkVersion.swift in Sources */, 628855462656F98B00EFFB91 /* Route+Realm.swift in Sources */, 62B3FE3225A8D5D300FCCA4B /* FeatureFlag.swift in Sources */, @@ -5529,7 +5513,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5560,7 +5544,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.2; + MARKETING_VERSION = 1.7.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5568,6 +5552,9 @@ PROVISIONING_PROFILE_SPECIFIER = ""; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "GuideDogs/Code/App/Soundscape-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -5818,7 +5805,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5850,7 +5837,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.2; + MARKETING_VERSION = 1.7.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5858,6 +5845,9 @@ PROVISIONING_PROFILE_SPECIFIER = ""; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "GuideDogs/Code/App/Soundscape-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -5878,7 +5868,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5908,7 +5898,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.2; + MARKETING_VERSION = 1.7.3; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; @@ -5916,6 +5906,9 @@ PROVISIONING_PROFILE_SPECIFIER = ""; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "GuideDogs/Code/App/Soundscape-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; diff --git a/apps/ios/GuideDogs.xcodeproj/xcshareddata/xcschemes/Soundscape.xcscheme b/apps/ios/GuideDogs.xcodeproj/xcshareddata/xcschemes/Soundscape.xcscheme index fa407322a..de0120c14 100644 --- a/apps/ios/GuideDogs.xcodeproj/xcshareddata/xcschemes/Soundscape.xcscheme +++ b/apps/ios/GuideDogs.xcodeproj/xcshareddata/xcschemes/Soundscape.xcscheme @@ -79,6 +79,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + enableThreadSanitizer = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" @@ -102,6 +103,13 @@ isEnabled = "YES"> + + + + diff --git a/apps/ios/GuideDogs/Code/App/Soundscape-Bridging-Header.h b/apps/ios/GuideDogs/Code/App/Soundscape-Bridging-Header.h index 29ef59b75..bcac9a000 100644 --- a/apps/ios/GuideDogs/Code/App/Soundscape-Bridging-Header.h +++ b/apps/ios/GuideDogs/Code/App/Soundscape-Bridging-Header.h @@ -12,4 +12,4 @@ // Helpers #import "GDAJSONObject.h" #import "ObjCExceptionHandling.h" -#import "GDAStateMachine.h" + diff --git a/apps/ios/GuideDogs/Code/Audio/AudioEngine.swift b/apps/ios/GuideDogs/Code/Audio/AudioEngine.swift index ec4cd795e..e20f7a1a8 100644 --- a/apps/ios/GuideDogs/Code/Audio/AudioEngine.swift +++ b/apps/ios/GuideDogs/Code/Audio/AudioEngine.swift @@ -550,6 +550,11 @@ class AudioEngine: AudioEngineProtocol { return } + // Check if we should start before activating the session + guard shouldStart() else { + return + } + if activateAudioSession { // We try to forcibly activate the audio session, even if we believe it's not needed (`needsActivation == false`). // This is because of the following issue: @@ -565,19 +570,6 @@ class AudioEngine: AudioEngineProtocol { isSessionInterrupted = false } - guard shouldStart() else { - // If the audio engine has started, make sure all the paused players are resumed if needed. - if state == .started { - if !resume() { - // If resuming wasn't successful because one of the players could not be resumed, - // that player will be marked as done. If this was the case, try to play the - // next sound, which will either play or report finished. - playNextSound() - } - } - return - } - if isConfigChangePending { connectNodes() isConfigChangePending = false @@ -964,7 +956,7 @@ class AudioEngine: AudioEngineProtocol { guard self.state != .stopped else { GDLogAudioError("Unable to play sounds. Audio engine is stopped.") - callback?(false) + Task { @MainActor in callback?(false) } return } @@ -1099,7 +1091,9 @@ class AudioEngine: AudioEngineProtocol { self.play(nextSounds, completion: completion) } - callback?(success) + Task { @MainActor in + callback?(success) + } } // MARK: 3D Audio Environment @@ -1253,6 +1247,14 @@ extension AudioEngine: AudioSessionManagerDelegate { // Make sure the interruption flag is cleared if the audio session is re-activated. isSessionInterrupted = false + // Don't try to start the engine if there's a call in progress and we're not active. + // The session might be activated by the system or remain active during interruptions, + // but we shouldn't start audio playback until the app is actually ready. + guard shouldStart() else { + GDLogAudioVerbose("Audio session activated but engine should not start yet") + return + } + start(activateAudioSession: false) } diff --git a/apps/ios/GuideDogs/Code/Audio/DiscreteAudioPlayer.swift b/apps/ios/GuideDogs/Code/Audio/DiscreteAudioPlayer.swift index aeba9e942..f5fb2b32d 100644 --- a/apps/ios/GuideDogs/Code/Audio/DiscreteAudioPlayer.swift +++ b/apps/ios/GuideDogs/Code/Audio/DiscreteAudioPlayer.swift @@ -251,43 +251,48 @@ class DiscreteAudioPlayer: BaseAudioPlayer { guard let `self` = self else { return } - - guard self.layerStates[layer].bufferQueue.isEmpty else { - self.wasPaused = true - return - } + // Serialize all state access on the player's queue to avoid races + self.queue.async { + if !self.layerStates[layer].bufferQueue.isEmpty { + self.wasPaused = true + return + } - guard self.layerStates[layer].playbackDispatchGroupWasEntered else { - GDLogAudioVerbose("Silent buffer played back, but dispatch group was never entered!") - return - } - - guard !self.layerStates[layer].playbackDispatchGroupWasLeft else { - GDLogAudioVerbose("Silent buffer played back, but dispatch group was already left!") - return + guard self.layerStates[layer].playbackDispatchGroupWasEntered else { + GDLogAudioVerbose("Silent buffer played back, but dispatch group was never entered!") + return + } + + guard !self.layerStates[layer].playbackDispatchGroupWasLeft else { + GDLogAudioVerbose("Silent buffer played back, but dispatch group was already left!") + return + } + + self.layerStates[layer].playbackDispatchGroupWasLeft = true + self.channelPlayedBackDispatchGroup.leave() } - - self.layerStates[layer].playbackDispatchGroupWasLeft = true - self.channelPlayedBackDispatchGroup.leave() } return } // Schedule this buffer (and use the dispatch group to know when it is done playing) - layerStates[layer].bufferQueue.enqueue(buffer) - layerStates[layer].bufferCount += 1 + // Serialize mutations to layer state on the queue + queue.async { [weak self] in + guard let self = self else { return } + self.layerStates[layer].bufferQueue.enqueue(buffer) + self.layerStates[layer].bufferCount += 1 + } layers[layer].player.scheduleBuffer(buffer, completionCallbackType: .dataRendered) { [weak self] (_) in guard let `self` = self else { return } - - // Only log completion and remove from the buffer queue if the audio actually played back - guard !self.wasPaused else { - return - } - + // Ensure reads/writes occur on the queue to avoid races self.queue.async { + // Only log completion and remove from the buffer queue if the audio actually played back + if self.wasPaused { + return + } _ = self.layerStates[layer].bufferQueue.dequeue() } } diff --git a/apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift b/apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift index 95925c9ac..d77954e6b 100644 --- a/apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift +++ b/apps/ios/GuideDogs/Code/Behaviors/Helpers/CalloutStateMachine.swift @@ -11,39 +11,24 @@ import CoreLocation -private enum State: String { - case unknown = "[Unknown]" - case wildcard = "*" - case off = "[Off]" - case start = "[Start]" - case starting = "[Starting]" - case stop = "[Stop]" - case stopping = "[Stopping]" - case announceCallout = "[AnnounceCallout]" - case announcingCallout = "[AnnouncingCallout]" - case delayingCalloutAnnounced = "[DelayingCalloutAnnounced]" - case complete = "[Complete]" - case failed = "[Failed]" -} - -private enum StateMachineEvent: String { - case start = "(Start)" - case started = "(Started)" - case stop = "(Stop)" - case stopped = "(Stopped)" - case hush = "(Hush)" - case delayCalloutAnnounced = "(CalloutDelay)" - case calloutAnnounced = "(CalloutAnnounced)" - case complete = "(Complete)" - case completed = "(Completed)" - case failed = "(Failed)" -} - protocol CalloutStateMachineDelegate: AnyObject { func calloutsDidFinish(id: UUID) } class CalloutStateMachine { + + // MARK: State Machine + + private enum State { + case off + case start + case playingPrefixSounds + case stop + case stopping + case announcingCallout + case delayingCalloutAnnounced + case complete + } // MARK: Properties @@ -54,20 +39,20 @@ class CalloutStateMachine { private weak var motionActivityContext: MotionActivityProtocol! private weak var audioEngine: AudioEngineProtocol! + private var state: State = .off private var hushed = false private var playHushedSound = false - private var stateMachine: GDAStateMachine! private var calloutGroup: CalloutGroup? private var calloutIterator: IndexingIterator<[CalloutProtocol]>? private var lastGroupID: UUID? var currentState: String { - return stateMachine?.currentState?.name ?? State.unknown.rawValue + return String(describing: state) } var isPlaying: Bool { - return stateMachine.currentState.name != State.off.rawValue + return state != .off } // MARK: Initialization @@ -81,387 +66,248 @@ class CalloutStateMachine { motionActivityContext = motion self.geo = geo - stateMachine = buildStateMachine() + state = .off } // MARK: Methods func start(_ callouts: CalloutGroup) { - // The state machine must be stopped before you can call start(...) guard !isPlaying else { - GDLogVerbose(.stateMachine, "Unable to start callout group. State machine is currently in state: \(stateMachine.currentState.name ?? State.unknown.rawValue)") + GDLogVerbose(.stateMachine, "Unable to start callout group. State machine is currently in state: \(String(describing: state))") return } - calloutGroup = callouts hushed = false playHushedSound = false callouts.onStart?() - stateMachine.fireEvent(.start) - } - - func hush(playSound: Bool = false) { - hushed = true - if playSound { - playHushedSound = true + GDLogVerbose(.stateMachine, "Entering state: \(State.start)") + state = .start + // Stop current sounds if needed + if callouts.stopSoundsBeforePlaying { + self.audioEngine.stopDiscrete() } - stateMachine.fireEvent(.hush) - } - - func stop() { - if isPlaying { - stateMachine.fireEvent(.stop) - } - } - - private func buildStateMachine() -> GDAStateMachine { - let states: [GDAStateMachineState] = [ - stateOff(), - stateStart(), - stateStarting(), - stateStop(), - stateStopping(), - stateAnnounceCallout(), - stateAnnouncingCallout(), - stateDelayingCalloutAnnounced(), - stateComplete(), - stateFailed() - ] + callouts.delegate?.calloutsStarted(for: callouts) - let events: [GDAStateMachineEvent] = [ - // START - GDAStateMachine.event(name: .start, - transitions: [.off: .start]), - - // STARTING - GDAStateMachine.event(name: .started, transitions: [.starting: .announceCallout]), - - // HUSH - GDAStateMachine.event(name: .hush, - transitions: [.wildcard: .stop]), - - // DELAY CALLOUT ANNOUNCED - GDAStateMachine.event(name: .delayCalloutAnnounced, - transitions: [.announcingCallout: .delayingCalloutAnnounced, - .complete: .complete, - .off: .off - ]), - - // EXPLORE QUADRANT RESULT ANNOUNCED - GDAStateMachine.event(name: .calloutAnnounced, - transitions: [.announcingCallout: .announceCallout, - .delayingCalloutAnnounced: .announceCallout, - .complete: .complete, - .off: .off]), - - // STOP - GDAStateMachine.event(name: .stop, transitions: [ - .starting: .stop, - .announcingCallout: .stop, - .complete: .off, - .off: .off, - .wildcard: .complete - ]), - - // STOPPING - GDAStateMachine.event(name: .stopped, transitions: [.stopping: .complete]), - - // COMPLETE - GDAStateMachine.event(name: .complete, transitions: [.wildcard: .complete]), - - // COMPLETED - GDAStateMachine.event(name: .completed, transitions: [.complete: .off]), - - // FAILED - GDAStateMachine.event(name: .failed, transitions: [.wildcard: .failed]) - ] + // Prepare the iterator for the callouts + self.calloutIterator = callouts.callouts.makeIterator() - return GDAStateMachine(name: "CalloutMachine", states: states, events: events) - } -} - -extension CalloutStateMachine { - - private func stateOff() -> GDAStateMachineState { - return GDAStateMachine.state(name: .off, enter: { [weak self] (_, _, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.off)") - - guard let strongSelf = self else { - return - } - - if let lastGroupID = strongSelf.lastGroupID { - strongSelf.lastGroupID = nil - DispatchQueue.main.async { - strongSelf.delegate?.calloutsDidFinish(id: lastGroupID) - } - } - }) - } - - private func stateStart() -> GDAStateMachineState { - return GDAStateMachine.state(name: .start, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.start)") - - guard let strongSelf = self else { - return - } - - guard let calloutGroup = strongSelf.calloutGroup else { - nextStateName?.pointee = State.failed.rawValue as NSString - return - } - - // Stop current sounds if needed - if calloutGroup.stopSoundsBeforePlaying { - strongSelf.audioEngine.stopDiscrete() - } - - calloutGroup.delegate?.calloutsStarted(for: calloutGroup) - - // Prepare the iterator for the callouts - strongSelf.calloutIterator = calloutGroup.callouts.makeIterator() - - // Play the sounds indicating that the mode has started - var sounds: [Sound] = calloutGroup.playModeSounds ? [GlyphSound(.enterMode)] : [] - - if let prefixSounds = calloutGroup.prefixCallout?.sounds(for: strongSelf.geo?.location) { - sounds.append(contentsOf: prefixSounds.soundArray) - } - - if sounds.count > 0 { - strongSelf.audioEngine.play(Sounds(sounds)) { (success) in - guard strongSelf.currentState != State.stopping.rawValue else { - GDLogVerbose(.stateMachine, "Callout interrupted. Stopping...") - strongSelf.stateMachine.fireEvent(.stopped) - calloutGroup.onComplete?(false) - return - } - - guard strongSelf.currentState != State.off.rawValue else { - GDLogVerbose(.stateMachine, "Callouts immediately interrupted. Cleaning up...") - calloutGroup.onComplete?(false) - return - } - - guard success else { - GDLogVerbose(.stateMachine, "Callout did not finish playing successfully. Terminating state machine...") - strongSelf.stateMachine.fireEvent(.failed) - return - } - - GDLogVerbose(.stateMachine, "Enter mode sound played") - strongSelf.stateMachine.fireEvent(.started) - } - - // Transition to the state to allow mode sounds and prefix sounds to play - nextStateName?.pointee = State.starting.rawValue as NSString - } else { - // Transition to the state to announce callouts - nextStateName?.pointee = State.announceCallout.rawValue as NSString - } - }) - } - - private func stateStarting() -> GDAStateMachineState { - return GDAStateMachine.state(name: .starting, enter: { (_, _, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.starting)") - }) - } - - private func stateStop() -> GDAStateMachineState { - return GDAStateMachine.state(name: .stop, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.stop)") - - guard let strongSelf = self else { - return - } - - if strongSelf.audioEngine.isDiscreteAudioPlaying { - // The audio engine is currently playing a discrete sound. Stop it and then move to the .stopping state and wait - // until the sound is actually stopped (see the completion handlers passed to audioEngine.play() in the .start - // and .announceCallout states). - strongSelf.audioEngine.stopDiscrete(with: strongSelf.hushed && strongSelf.playHushedSound ? GlyphSound(.hush) : nil) - nextStateName?.pointee = State.stopping.rawValue as NSString - } else { - // In this case, discrete audio isn't currently playing, but we might be between sounds, so still call stopDiscrete in - // order to clear the sounds queue in the audio engine before moving to the complete state - strongSelf.audioEngine.stopDiscrete(with: strongSelf.hushed && strongSelf.playHushedSound ? GlyphSound(.hush) : nil) - nextStateName?.pointee = State.complete.rawValue as NSString - } - }) - } - - private func stateStopping() -> GDAStateMachineState { - return GDAStateMachine.state(name: .stopping, enter: { (_, _, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.stopping)") - }) - } - - private func stateAnnounceCallout() -> GDAStateMachineState { - return GDAStateMachine.state(name: .announceCallout, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.announceCallout)") - - guard let strongSelf = self else { - return - } - - guard let calloutGroup = strongSelf.calloutGroup else { - nextStateName?.pointee = State.failed.rawValue as NSString - return - } - - guard let callout = strongSelf.calloutIterator?.next() else { - calloutGroup.onComplete?(true) - nextStateName?.pointee = State.complete.rawValue as NSString - return - } - - // If this callout is not within the region to live, skip to the next callout - if let delegate = calloutGroup.delegate, !delegate.isCalloutWithinRegionToLive(callout) { - calloutGroup.delegate?.calloutSkipped(callout) - nextStateName?.pointee = State.announceCallout.rawValue as NSString - return - } - - calloutGroup.delegate?.calloutStarting(callout) - strongSelf.history?.insert(callout) - - let sounds: Sounds - if let repeatLocation = calloutGroup.repeatingFromLocation { - sounds = callout.sounds(for: repeatLocation, isRepeat: true) - } else { - sounds = callout.sounds(for: strongSelf.geo?.location, automotive: strongSelf.motionActivityContext.isInVehicle) - } - - strongSelf.audioEngine.play(sounds) { (success) in - calloutGroup.delegate?.calloutFinished(callout, completed: success) - - guard strongSelf.currentState != State.stopping.rawValue else { + // Play the sounds indicating that the mode has started + var sounds: [Sound] = callouts.playModeSounds ? [GlyphSound(.enterMode)] : [] + + if let prefixSounds = callouts.prefixCallout?.sounds(for: self.geo?.location) { + sounds.append(contentsOf: prefixSounds.soundArray) + } + + if sounds.count > 0 { + self.audioEngine.play(Sounds(sounds)) { (success) in + if self.state == .stopping { GDLogVerbose(.stateMachine, "Callout interrupted. Stopping...") - strongSelf.stateMachine.fireEvent(.stopped) - calloutGroup.onComplete?(false) + self.complete() + callouts.onComplete?(false) return } - - guard strongSelf.currentState != State.off.rawValue else { + + if self.state == .off { GDLogVerbose(.stateMachine, "Callouts immediately interrupted. Cleaning up...") - calloutGroup.onComplete?(false) + callouts.onComplete?(false) return } guard success else { GDLogVerbose(.stateMachine, "Callout did not finish playing successfully. Terminating state machine...") - calloutGroup.onComplete?(false) - strongSelf.stateMachine.fireEvent(.failed) + self.complete(failed: true) return } - strongSelf.stateMachine.fireEvent(.delayCalloutAnnounced) + GDLogVerbose(.stateMachine, "Enter mode sound played") + self.announceCallout() } - CalloutStateMachineLogger.log(callout: callout, context: strongSelf.calloutGroup?.logContext) - - nextStateName?.pointee = State.announcingCallout.rawValue as NSString - }) + // Transition to the state to allow mode sounds and prefix sounds to play + self.state = .playingPrefixSounds + } else { + announceCallout() + } } - private func stateAnnouncingCallout() -> GDAStateMachineState { - return GDAStateMachine.state(name: .announcingCallout, enter: { (_, _, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.announcingCallout)") - }) + func hush(playSound: Bool = false) { + hushed = true + + if playSound { + playHushedSound = true + } + stateStop() + } + + func stop() { + switch state { + case .playingPrefixSounds, .announcingCallout: + stateStop() + case .complete, .off: + calloutsDidFinish() + case .start, .stop, .stopping, .delayingCalloutAnnounced: + complete() + } } - private func stateDelayingCalloutAnnounced() -> GDAStateMachineState { - return GDAStateMachine.state(name: .delayingCalloutAnnounced, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.delayingCalloutAnnounced)") - - guard let strongSelf = self else { - return - } - - if let delay = strongSelf.calloutGroup?.calloutDelay, delay >= 0.0 { - DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in - guard let strongSelf = self, strongSelf.currentState == State.delayingCalloutAnnounced.rawValue else { - return - } - - strongSelf.stateMachine.fireEvent(.calloutAnnounced) - } - } else { - nextStateName?.pointee = State.announceCallout.rawValue as NSString + private func eventDelayCalloutAnnounced() { + switch state { + case .announcingCallout: + stateDelayingCalloutAnnounced() + case .complete: + complete() + case .off: + calloutsDidFinish() + case .delayingCalloutAnnounced, .start, .playingPrefixSounds, .stop, .stopping: + GDLogError(.stateMachine, "Invalid state transition: eventDelayCalloutAnnounced() called from state .\(state)") + } + } + + private func eventCalloutAnnounced() { + switch state{ + case .announcingCallout: + announceCallout() + case .delayingCalloutAnnounced: + announceCallout() + case .complete: + complete() + case .off: + calloutsDidFinish() + case .start, .playingPrefixSounds, .stop, .stopping: + GDLogError(.stateMachine, "Invalid state transition: eventCalloutAnnounced() called from state .\(state)") + } + } + + private func calloutsDidFinish() { + GDLogVerbose(.stateMachine, "Entering state: \(State.off)") + state = .off + if let lastGroupID = self.lastGroupID { + self.lastGroupID = nil + Task { @MainActor in + self.delegate?.calloutsDidFinish(id: lastGroupID) } - }) + } + } + + private func stateStop() { + GDLogVerbose(.stateMachine, "Entering state: \(State.stop)") + state = .stop + + if self.audioEngine.isDiscreteAudioPlaying { + // The audio engine is currently playing a discrete sound. Stop it and then move to the .stopping state and wait + // until the sound is actually stopped (see the completion handlers passed to audioEngine.play() in the .start + // and .announceCallout states). + self.audioEngine.stopDiscrete(with: self.hushed && self.playHushedSound ? GlyphSound(.hush) : nil) + state = .stopping + } else { + // In this case, discrete audio isn't currently playing, but we might be between sounds, so still call stopDiscrete in + // order to clear the sounds queue in the audio engine before moving to the complete state + self.audioEngine.stopDiscrete(with: self.hushed && self.playHushedSound ? GlyphSound(.hush) : nil) + complete() + } } - private func stateComplete() -> GDAStateMachineState { - return GDAStateMachine.state(name: .complete, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.complete)") + private func announceCallout() { + guard let calloutGroup = self.calloutGroup else { + complete(failed: true) + return + } + + guard let callout = self.calloutIterator?.next() else { + calloutGroup.onComplete?(true) + complete() + return + } + + // If this callout is not within the region to live, skip to the next callout + if let delegate = calloutGroup.delegate, !delegate.isCalloutWithinRegionToLive(callout) { + calloutGroup.delegate?.calloutSkipped(callout) + announceCallout() + return + } + + calloutGroup.delegate?.calloutStarting(callout) + self.history?.insert(callout) + + let sounds: Sounds + if let repeatLocation = calloutGroup.repeatingFromLocation { + sounds = callout.sounds(for: repeatLocation, isRepeat: true) + } else { + sounds = callout.sounds(for: self.geo?.location, automotive: self.motionActivityContext.isInVehicle) + } + + self.audioEngine.play(sounds) { (success) in + calloutGroup.delegate?.calloutFinished(callout, completed: success) - guard let strongSelf = self else { + if self.state == .stopping { + GDLogVerbose(.stateMachine, "Callout interrupted. Stopping...") + self.complete() + calloutGroup.onComplete?(false) return } - if !strongSelf.hushed && strongSelf.calloutGroup?.playModeSounds ?? false { - strongSelf.audioEngine.play(GlyphSound(.exitMode)) { (_) in - GDLogVerbose(.stateMachine, "Exit mode sound played") - - strongSelf.lastGroupID = strongSelf.calloutGroup?.id - strongSelf.calloutIterator = nil - strongSelf.calloutGroup = nil - strongSelf.stateMachine.fireEvent(.completed) - } - } else { - strongSelf.lastGroupID = strongSelf.calloutGroup?.id - strongSelf.calloutIterator = nil - strongSelf.calloutGroup = nil - nextStateName?.pointee = State.off.rawValue as NSString + if self.state == .off { + GDLogVerbose(.stateMachine, "Callouts immediately interrupted. Cleaning up...") + calloutGroup.onComplete?(false) + return } - }) - } - - /// This is the same as COMPLETE except no additional sounds may be played - private func stateFailed() -> GDAStateMachineState { - return GDAStateMachine.state(name: .failed, enter: { [weak self] (_, nextStateName, _) in - GDLogVerbose(.stateMachine, "Entering state: \(State.failed)") - guard let strongSelf = self else { + guard success else { + GDLogVerbose(.stateMachine, "Callout did not finish playing successfully. Terminating state machine...") + calloutGroup.onComplete?(false) + self.complete(failed: true) return } - strongSelf.lastGroupID = strongSelf.calloutGroup?.id - strongSelf.calloutIterator = nil - strongSelf.calloutGroup = nil - nextStateName?.pointee = State.off.rawValue as NSString - }) - } - -} - -extension GDAStateMachine { - fileprivate func fireEvent(_ event: StateMachineEvent) { - self.fireEvent(withName: event.rawValue) + self.eventDelayCalloutAnnounced() + } + + CalloutStateMachine.log(callout: callout, context: self.calloutGroup?.logContext) + + state = .announcingCallout } - fileprivate class func state(name: State, timeout: TimeInterval = 0.0, enter: GDAStateEnterAction? = nil, exit: GDAStateExitAction? = nil) -> GDAStateMachineState { - return GDAStateMachineState(name: name.rawValue, timeout: timeout, enterAction: enter, exitAction: exit) + private func stateDelayingCalloutAnnounced() { + GDLogVerbose(.stateMachine, "Entering state: \(State.delayingCalloutAnnounced)") + state = .delayingCalloutAnnounced + + if let delay = self.calloutGroup?.calloutDelay, delay >= 0.0 { + DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in + guard let strongSelf = self, strongSelf.state == .delayingCalloutAnnounced else { + return + } + + strongSelf.eventCalloutAnnounced() + } + } else { + announceCallout() + } } - fileprivate class func event(name: StateMachineEvent, transitions stateTransitions: [State: State]) -> GDAStateMachineEvent { - var transitions: [String: String] = [:] + private func complete(failed: Bool = false) { + GDLogVerbose(.stateMachine, "Entering state: \(State.complete)") + state = .complete - for (start, end) in stateTransitions { - transitions[start.rawValue] = end.rawValue + if !failed && !self.hushed && self.calloutGroup?.playModeSounds == true { + self.audioEngine.play(GlyphSound(.exitMode)) { (_) in + GDLogVerbose(.stateMachine, "Exit mode sound played") + + self.lastGroupID = self.calloutGroup?.id + self.calloutIterator = nil + self.calloutGroup = nil + self.calloutsDidFinish() + } + } else { + self.lastGroupID = self.calloutGroup?.id + self.calloutIterator = nil + self.calloutGroup = nil + calloutsDidFinish() } - - return GDAStateMachineEvent(name: name.rawValue, transitions: transitions) } -} - -private class CalloutStateMachineLogger { + class func log(callout: CalloutProtocol, context: String?) { var properties = ["type": callout.logCategory, "activity": AppContext.shared.motionActivityContext.currentActivity.rawValue, @@ -473,4 +319,4 @@ private class CalloutStateMachineLogger { GDATelemetry.track("callout", with: properties) } -} +} \ No newline at end of file diff --git a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.h b/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.h deleted file mode 100644 index 19097c13d..000000000 --- a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.h +++ /dev/null @@ -1,91 +0,0 @@ -// -// GDAStateMachine.h -// Soundscape -// -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// -// Description: -// -// This class represents a state machine. A state machine is constructed with states and events and -// begins in an initial state. As events occur, the state machine takes transitions from input states -// to output states, as specified in the event declarations. -// - -@import Foundation; -#import "GDAStateMachineDelegate.h" - -// State enter action. -typedef void (^GDAStateEnterAction)(id object, NSString ** nextStateName, id * nextStateObject); - -// State exit action. -typedef void (^GDAStateExitAction)(void); - -// GDAStateMachineState interface. -@interface GDAStateMachineState : NSObject - -// Properties. -@property (nonatomic, readonly) NSString * name; -@property (nonatomic, readonly) NSTimeInterval timeout; -@property (nonatomic, readonly) GDAStateEnterAction enterAction; -@property (nonatomic, readonly) GDAStateExitAction exitAction; - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - timeout:(NSTimeInterval)timeout - enterAction:(GDAStateEnterAction)enterAction - exitAction:(GDAStateExitAction)exitAction; - -@end - -// GDAStateMachineEvent interface. -@interface GDAStateMachineEvent : NSObject - -// Properties. -@property (nonatomic, readonly) NSString * name; -@property (nonatomic, readonly) NSDictionary * transitions; - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - transitions:(NSDictionary *)transitions; - -@end - -// GDAStateMachine interface. -@interface GDAStateMachine : NSObject - -// Properties. -@property (nonatomic, weak) id delegate; -@property (nonatomic, readonly) NSString * name; -@property (nonatomic, readonly) NSString * previousStateName; -@property (nonatomic, readonly) GDAStateMachineState * currentState; - -// Returns a new state machine. -+ (instancetype)stateMachineWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events; - -// Returns a new state machine. -+ (instancetype)stateMachineWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events - defaultStateName:(NSString *)defaultStateName; - -// Returns a new state machine state. -+ (id)stateWithName:(NSString *)name - timeout:(NSTimeInterval)timeout - enterAction:(GDAStateEnterAction)enterAction - exitAction:(GDAStateExitAction)exitAction; - -// Returns a new state machine event. -+ (id)eventWithName:(NSString *)name - transitions:(NSDictionary *)transitions; - -// Fires an event by name. -- (BOOL)fireEventWithName:(NSString *)eventName; - -// Fires an event by name. -- (BOOL)fireEventWithName:(NSString *)eventName - object:(id)object; - -@end diff --git a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.m b/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.m deleted file mode 100644 index 31bd2ddde..000000000 --- a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachine.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GDAStateMachine.m -// Soundscape -// -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// -// Description: -// -// This class represents a state machine. A state machine is constructed with states and events and -// begins in an initial state. As events occur, the state machine takes transitions from input states -// to output states, as specified in the event declarations. -// - -#import "GDAStateMachine.h" -#import - -// Logging. -static inline void Log(NSString * format, ...) -{ - // Removed logs for now. - return; - -// // Format the log entry. -// va_list args; -// va_start(args, format); -// NSString * formattedString = [[NSString alloc] initWithFormat:format arguments:args]; -// va_end(args); -// -// // Log the log entry. -// NSLog(@"%@", [NSString stringWithFormat:@" StateMachine: %@", formattedString]); -} - -// GDAStateMachineState implementation. -@implementation GDAStateMachineState - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - timeout:(NSTimeInterval)timeout - enterAction:(GDAStateEnterAction)enterAction - exitAction:(GDAStateExitAction)exitAction -{ - // Initialize superclass. - self = [super init]; - - // Handle errors. - if (!self) - { - return nil; - } - - // Initialize. - _name = name; - _timeout = timeout; - _enterAction = enterAction; - _exitAction = exitAction; - - // Done. - return self; -} - -@end - -// GDAStateMachineEvent implementation. -@implementation GDAStateMachineEvent - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - transitions:(NSDictionary *)transitions -{ - // Initialize superclass. - self = [super init]; - - // Handle errors. - if (!self) - { - return nil; - } - - // Initialize. - _name = name; - _transitions = transitions; - - // Done. - return self; -} - -@end - -// GDAStateMachine (Internal) interface. -@interface GDAStateMachine (Internal) - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events - defaultStateName:(NSString *)defaultStateName; - -// Transitions to the specified state. -- (void)transitionToState:(GDAStateMachineState *)state - object:(id)object; - -@end - -// GDAStateMachine implementation. -@implementation GDAStateMachine -{ -@private - // The mutex. - pthread_mutex_t _mutex; - - // The default state. - GDAStateMachineState * _defaultState; - - // The timeout state. - GDAStateMachineState * _timeoutState; - - // The states dictionary. The key is the state name. The entry is a GDAStateMachineState object. - NSDictionary * _states; - - // The events dictionary. Each key is an event name. The entry is a dictionary of transitions. - NSDictionary * _events; - - // The state number. Used for timeout processing. - uint64_t _stateNumber; -} - -// Class initializer. -- (instancetype)init -{ - // Initialize superclass. - self = [super init]; - - // Handle errors. - if (!self) - { - return nil; - } - - // Done. - return self; -} - -// Returns a new state machine. -+ (instancetype)stateMachineWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events -{ - return [[GDAStateMachine alloc] initWithName:name - states:states - events:events - defaultStateName:@""]; -} - -// Returns a new state machine. -+ (instancetype)stateMachineWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events - defaultStateName:(NSString *)defaultStateName -{ - return [[GDAStateMachine alloc] initWithName:name - states:states - events:events - defaultStateName:defaultStateName]; -} - -// Returns a new state machine state. -+ (id)stateWithName:(NSString *)name - timeout:(NSTimeInterval)timeout - enterAction:(GDAStateEnterAction)enterAction - exitAction:(GDAStateExitAction)exitAction -{ - return [[GDAStateMachineState alloc] initWithName:name - timeout:timeout - enterAction:enterAction - exitAction:exitAction]; -} - -// Returns a new state machine event. -+ (id)eventWithName:(NSString *)name - transitions:(NSDictionary *)transitions -{ - return [[GDAStateMachineEvent alloc] initWithName:name - transitions:transitions]; -} - -// Fires an event by name. -- (BOOL)fireEventWithName:(NSString *)eventName -{ - return [self fireEventWithName:eventName - object:nil]; -} - -// Fires an event by name. -- (BOOL)fireEventWithName:(NSString *)eventName - object:(id)object -{ - // Find the event. If it can't be found, raise an exception. - NSDictionary * transitions = _events[eventName]; - if (!transitions) - { - [NSException raise:@"Undefined Event" - format:@"State machine '%@' does not contain an event named '%@'.", _name, eventName]; - } - - // Lock. - pthread_mutex_lock(&_mutex); - - // Look for an explicit transition from the current state. - GDAStateMachineState * toState = transitions[[_currentState name]]; - - // If we found an explicit transition from the current state, great. - BOOL result; - if (toState) - { - // Explicit transition found. - result = YES; - - // Log. - Log(@"%@: Event '%@' fired. Explicit transition from state '%@' to state '%@'.", _name, eventName, [_currentState name], [toState name]); - } - else - { - // An explicit transition from the current state wasn't found. Look for a wildcard transition. - toState = transitions[@"*"]; - - // If a wildcard transition was found, great. - if (toState) - { - // Wildcard transition found. - result = YES; - - // Log. - Log(@"%@: Event '%@' fired. Wildcard transition from state '%@' to state '%@'.", _name, eventName, [_currentState name], [toState name]); - } - else - { - // State machine error. Do not make a state transition. - toState = nil; - result = NO; - } - } - - // If we have a new state to transition to, do it. - if (toState && _currentState != toState) - { - [self transitionToState:toState - object:object]; - } - - // Unlock. - pthread_mutex_unlock(&_mutex); - - // If there was a state machine error, notify the delegate. - if (!result) - { - // Log. - Log(@"%@: Event '%@' fired. State machine error. Not transition from state '%@' was found.", _name, eventName, [_currentState name]); - - // Notify the delegate. - if ([[self delegate] respondsToSelector:@selector(stateMachineError:)]) - { - [[self delegate] stateMachineError:self]; - } - } - - // Retun the result. - return result; -} - -@end - -// GDAStateMachine (Internal) implementation. -@implementation GDAStateMachine (Internal) - -// Class initializer. -- (instancetype)initWithName:(NSString *)name - states:(NSArray *)states - events:(NSArray *)events - defaultStateName:(NSString *)defaultStateName -{ - // Initialize superclass. - self = [super init]; - - // Handle errors. - if (!self) - { - return nil; - } - - // Initialize. - pthread_mutex_init(&_mutex, NULL); - _name = name; - - // The default state is the first state. - if(defaultStateName != nil && ![defaultStateName isEqualToString:@""]){ - NSUInteger index = [states indexOfObjectPassingTest:^BOOL(GDAStateMachineState * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - BOOL result = NO; - - if([[obj name] isEqualToString: defaultStateName]){ - result = YES; - } - - return result; - }]; - - _defaultState = states[index]; - }else{ - _defaultState = states[0]; - } - - // Set-up states. - NSMutableDictionary * mutableStates = [[NSMutableDictionary alloc] initWithCapacity:[states count]]; - for (GDAStateMachineState * state in states) - { - // Check for duplicate state definitions. - if (mutableStates[[state name]]) - { - [NSException raise:@"Duplicate State" - format:@"State machine '%@' defines state '%@' more than once.", _name, [state name]]; - } - - // Note the timeout statem. - if ([[state name] isEqualToString:@"[Timeout]"]) - { - _timeoutState = state; - } - - // Add the state. - mutableStates[[state name]] = state; - } - _states = mutableStates; - - // If a timeout state wasn't explicitly defined, use the detault state. - if (!_timeoutState) - { - _timeoutState = _defaultState; - } - - // Set-up events. - NSMutableDictionary *> * mutableEvents = [[NSMutableDictionary *> alloc] initWithCapacity:[events count]]; - for (GDAStateMachineEvent * event in events) - { - // Check for duplicate event definitions. - if (mutableEvents[[event name]]) - { - [NSException raise:@"Duplicate Event" - format:@"State machine '%@' defines event '%@' more than once.", _name, [event name]]; - } - - // Process the transitions. - NSMutableDictionary * mutableTransitions = [[NSMutableDictionary alloc] init]; - [[event transitions] enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL * stop) { - // Get the from state name and to state name. - NSString * fromStateName = (NSString *)key; - NSString * toStateName = (NSString *)obj; - -// // Verify the from state. -// if (![fromStateName isEqualToString:@"*"] && !_states[fromStateName]) -// { -// [NSException raise:@"Event Definition Error" -// format:@"State machine '%@' event '%@' from state '%@' not defined.", _name, [event name], fromStateName]; -// } - - // Verify the to state. - GDAStateMachineState * toState = _states[toStateName]; -// if (!toState) -// { -// [NSException raise:@"Event Definition Error" -// format:@"State machine '%@' event '%@' to state '%@' not defined.", _name, [event name], toStateName]; -// } - - // Add the transition. - mutableTransitions[fromStateName] = toState; - }]; - - // Add the event and its transitions. - mutableEvents[[event name]] = (NSDictionary *)mutableTransitions; - } - _events = mutableEvents; - -#if defined(Logging) - // Log. - Log(@"%@: Initialized (States: %u Events: %u)", _name, [_states count], [_events count]); -#endif - - // Transition to the default state. - [self transitionToState:_defaultState - object:nil]; - - // Done. - return self; -} - -// Transitions to the specified state. -- (void)transitionToState:(GDAStateMachineState *)state - object:(id)object -{ - // Log. - Log(@"%@: Transition from state '%@' to state '%@'.", _name, [_currentState name], [state name]); - - // If the current state has an exit action, call it. - if ([_currentState exitAction]) - { - [_currentState exitAction]; - } - - // Increment the state number. - _stateNumber++; - - //set the previous state - _previousStateName = [_currentState name]; - - // Set the current state. - _currentState = state; - - // If the current state specifies a timeout, set-up timeout processing before calling the enter action. - NSTimeInterval timeout = [state timeout]; - if (timeout) - { - // Capture the state number for timeout processing. - uint64_t stateNumber = _stateNumber; - - // Log. - Log(@"%@: State '%@' will time out after %.0f seconds.", _name, [state name], timeout); - - // Schedule timeout processing. - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - // Lock. - pthread_mutex_lock(&self->_mutex); - - // If the operation timed out, change to the default state. - BOOL timedout = self->_stateNumber == stateNumber; - if (timedout) - { - // Log. - Log(@"%@: State '%@' timed out after %.0f seconds. Transition to state '%@'", self->_name, [state name], timeout, [self->_timeoutState name]); - - // Transition to the timeout state. - [self transitionToState:self->_timeoutState - object:[state name]]; - } - - // Unlock. - pthread_mutex_unlock(&self->_mutex); - - // If the operation timed out, notify the delegate. - if (timedout && [[self delegate] respondsToSelector:@selector(stateMachine:timedOutWithState:)]) - { - [[self delegate] stateMachine:self timedOutWithState:[state name]]; - } - }); - } - - // If the current state has an enter action, call it. - if ([state enterAction]) - { - // Call the enter action. - NSString * nextStateName = nil; - id nextStateObject = nil; - [state enterAction](object, &nextStateName, &nextStateObject); - - // If the enter action specifies a next state, immediately transition to that state. - if (nextStateName) - { - // Find the next state. - GDAStateMachineState * nextState = _states[nextStateName]; - if (!nextState) - { - [NSException raise:@"Undefined State" - format:@"State machine '%@' state '%@' enter action transitions to next state '%@' which is not defined.", _name, [state name], nextStateName]; - } - - // Transition. - [self transitionToState:nextState - object:nextStateObject]; - } - } -} - -@end diff --git a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachineDelegate.h b/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachineDelegate.h deleted file mode 100644 index 41079b08d..000000000 --- a/apps/ios/GuideDogs/Code/Behaviors/Helpers/GDAStateMachine/GDAStateMachineDelegate.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// GDAStateMachineDelegate.h -// Soundscape -// -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// -// Description: -// -// This protocol defines the events that emitted by the GDAStateMachine class. -// - -// Forward declarations. -@class GDAStateMachine; -@class GDAStateMachineState; -@class GDAStateMachineEvent; - -// GDAStateMachineDelegate protocol. -@protocol GDAStateMachineDelegate -@required - -// Notifies the delegate of a state machine error. -- (void)stateMachineError:(GDAStateMachine *)stateMachine; - -// Notifies the delegate of a state machine timeout. -- (void)stateMachine:(GDAStateMachine *)stateMachine - timedOutWithState:(NSString *)state; - -@end diff --git a/apps/ios/UnitTests.xctestplan b/apps/ios/UnitTests.xctestplan index c4e2fa5b6..1033579b7 100644 --- a/apps/ios/UnitTests.xctestplan +++ b/apps/ios/UnitTests.xctestplan @@ -28,7 +28,8 @@ "identifier" : "D3D7CFC71B3D96460020B5E9", "name" : "Soundscape" }, - "testExecutionOrdering" : "random" + "testExecutionOrdering" : "random", + "threadSanitizerEnabled" : true }, "testTargets" : [ { diff --git a/apps/ios/UnitTests/Audio/AudioEngineTest.swift b/apps/ios/UnitTests/Audio/AudioEngineTest.swift index 4cca7ee25..2a42e2413 100644 --- a/apps/ios/UnitTests/Audio/AudioEngineTest.swift +++ b/apps/ios/UnitTests/Audio/AudioEngineTest.swift @@ -33,9 +33,19 @@ final class AudioEngineTest: XCTestCase { var finish_count = 0 } + var audioEngine: AudioEngine? + + override func tearDown() { + super.tearDown() + // Stop and clean up the audio engine to prevent multiple engines running simultaneously + audioEngine?.stop() + audioEngine = nil + } + /// Ensures the initial state is correct func testInit() throws { - let eng = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + audioEngine = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + let eng = audioEngine! XCTAssertNil(eng.delegate) XCTAssertFalse(eng.isInMonoMode) // currently always true as it is not implemented XCTAssertFalse(eng.isDiscreteAudioPlaying) @@ -49,7 +59,8 @@ final class AudioEngineTest: XCTestCase { /// Just playing a single `Sound` func testDiscreteAudio2DSimple() throws { - let eng = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + audioEngine = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + let eng = audioEngine! let delegate = TestAudioEngineDelegate() eng.delegate = delegate let expectation = XCTestExpectation() @@ -68,7 +79,8 @@ final class AudioEngineTest: XCTestCase { /// Play a series of queued sounds in sequence func testDiscreteAudio2DSeveral() throws { - let eng = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + audioEngine = AudioEngine(envSettings: TestAudioEnvironmentSettings(), mixWithOthers: false) + let eng = audioEngine! let delegate = TestAudioEngineDelegate() eng.delegate = delegate let expectations = [XCTestExpectation(description: "one"), From 550c0982c49d55a1536bff6f72d356478e834b89 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 02:37:22 +0000 Subject: [PATCH 63/76] Update copyright year to 2025 in About page (#224) Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --- apps/ios/GuideDogs/Assets/Licenses/licenses.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Assets/Licenses/licenses.html b/apps/ios/GuideDogs/Assets/Licenses/licenses.html index 56b97d7d9..527a6696d 100644 --- a/apps/ios/GuideDogs/Assets/Licenses/licenses.html +++ b/apps/ios/GuideDogs/Assets/Licenses/licenses.html @@ -21,7 +21,7 @@

MIT License

- Copyright © 2024 Soundscape Community Contributors + Copyright © 2025 Soundscape Community Contributors
Copyright © Microsoft Corporation.

From b496bedeaae7148b343e00c612c1daa0299d219d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Dec 2025 21:26:33 +0000 Subject: [PATCH 64/76] Add Russian language support (#229) --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 5 +++++ .../Assets/Localization/ru.lproj/InfoPlist.strings | 7 +++++++ .../Assets/Localization/ru.lproj/Localizable.strings | 0 3 files changed, 12 insertions(+) create mode 100644 apps/ios/GuideDogs/Assets/Localization/ru.lproj/InfoPlist.strings create mode 100644 apps/ios/GuideDogs/Assets/Localization/ru.lproj/Localizable.strings diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 7e129b3ee..2252d303f 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -1572,6 +1572,8 @@ DCAAD87E2BC1E95F0018D135 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Assets/PropertyLists/PrivacyInfo.xcprivacy; sourceTree = ""; }; DCE09DD62E54AC9500B66BDF /* fa-IR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fa-IR"; path = "fa-IR.lproj/Localizable.strings"; sourceTree = ""; }; DCE09DD72E54AE7400B66BDF /* fa-IR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fa-IR"; path = "fa-IR.lproj/InfoPlist.strings"; sourceTree = ""; }; + 4BB00625C9264FD5ACF0ED5F /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/Localizable.strings"; sourceTree = ""; }; + 3247AF49E74F47A3BC0C066E /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/InfoPlist.strings"; sourceTree = ""; }; DCE4D2AC2D7CE40F00B5DA4B /* NewFeatures.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = NewFeatures.json; path = Assets/NewFeatures.json; sourceTree = ""; }; /* End PBXFileReference section */ @@ -4562,6 +4564,7 @@ "nl-NL", "pt-PT", "fa-IR", + "ru", ); mainGroup = D3D7CFBF1B3D96460020B5E9; packageReferences = ( @@ -5408,6 +5411,7 @@ 62CFAC6628E3A7B300BE504D /* nl-NL */, 62CFAC6728E3A7BE00BE504D /* pt-PT */, DCE09DD72E54AE7400B66BDF /* fa-IR */, + 3247AF49E74F47A3BC0C066E /* ru */, ); name = InfoPlist.strings; sourceTree = ""; @@ -5432,6 +5436,7 @@ 62CFAC6128E3A75200BE504D /* nl-NL */, 62CFAC6228E3A76D00BE504D /* pt-PT */, DCE09DD62E54AC9500B66BDF /* fa-IR */, + 4BB00625C9264FD5ACF0ED5F /* ru */, ); name = Localizable.strings; sourceTree = ""; diff --git a/apps/ios/GuideDogs/Assets/Localization/ru.lproj/InfoPlist.strings b/apps/ios/GuideDogs/Assets/Localization/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..2e1a1e4a5 --- /dev/null +++ b/apps/ios/GuideDogs/Assets/Localization/ru.lproj/InfoPlist.strings @@ -0,0 +1,7 @@ +/* + InfoPlist.strings + Soundscape + + Copyright (c) Soundscape Community contributors. + Licensed under the MIT License. +*/ diff --git a/apps/ios/GuideDogs/Assets/Localization/ru.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/ru.lproj/Localizable.strings new file mode 100644 index 000000000..e69de29bb From 5d7958a827d77531150ccb3bc93ec950dccbe554 Mon Sep 17 00:00:00 2001 From: RDMurray Date: Fri, 9 Jan 2026 04:28:06 +0000 Subject: [PATCH 65/76] fix scrolling in markers list and move search back to top for iOS 26+ (#230) * Remove DeleteModifier implementation and update list views to use swipe actions for deletion * Fix swipe to delete in marker and route list --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 17 ++- .../Visual UI/Modifiers/DeleteModifier.swift | 111 ----------------- .../Home/HomeViewController.swift | 5 + .../Views/Markers & Routes/MarkerCell.swift | 1 + .../MarkersAndRoutesList.swift | 11 +- .../Views/Markers & Routes/MarkersList.swift | 111 +++++++++-------- .../Views/Markers & Routes/RouteCell.swift | 1 + .../Views/Markers & Routes/RoutesList.swift | 117 ++++++++++-------- 8 files changed, 146 insertions(+), 228 deletions(-) delete mode 100644 apps/ios/GuideDogs/Code/Visual UI/Modifiers/DeleteModifier.swift diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 2252d303f..53a042653 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -289,7 +289,6 @@ 28E60D461FE490D900EAB5C0 /* POICallout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E60D451FE490D900EAB5C0 /* POICallout.swift */; }; 28E60D551FE9816500EAB5C0 /* POI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E60D541FE9816500EAB5C0 /* POI.swift */; }; 28E60D5A1FE99BBE00EAB5C0 /* RealmMigrationTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28E60D591FE99BBE00EAB5C0 /* RealmMigrationTools.swift */; }; - 28EB441426B4A16700D5BBE4 /* DeleteModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EB441326B4A16700D5BBE4 /* DeleteModifier.swift */; }; 28EB9C75237CBA3A0064E7EF /* ExperimentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EB9C74237CBA3A0064E7EF /* ExperimentConfiguration.swift */; }; 28EB9C79237CC7D90064E7EF /* ExperimentServiceModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EB9C78237CC7D90064E7EF /* ExperimentServiceModel.swift */; }; 28F0F9251F85A39D00B6A64F /* DestinationTutorialIntroViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F0F9241F85A39C00B6A64F /* DestinationTutorialIntroViewController.swift */; }; @@ -1060,7 +1059,6 @@ 28E60D451FE490D900EAB5C0 /* POICallout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POICallout.swift; sourceTree = ""; }; 28E60D541FE9816500EAB5C0 /* POI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = POI.swift; path = Code/Data/Models/Protocols/POI.swift; sourceTree = ""; }; 28E60D591FE99BBE00EAB5C0 /* RealmMigrationTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RealmMigrationTools.swift; path = Code/Data/Models/Helpers/RealmMigrationTools.swift; sourceTree = ""; }; - 28EB441326B4A16700D5BBE4 /* DeleteModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteModifier.swift; sourceTree = ""; }; 28EB9C74237CBA3A0064E7EF /* ExperimentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ExperimentConfiguration.swift; path = "Code/App/Feature Flags/Experiment Flighting/ExperimentConfiguration.swift"; sourceTree = ""; }; 28EB9C78237CC7D90064E7EF /* ExperimentServiceModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ExperimentServiceModel.swift; path = "Code/App/Feature Flags/Experiment Flighting/ExperimentServiceModel.swift"; sourceTree = ""; }; 28F0F9241F85A39C00B6A64F /* DestinationTutorialIntroViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DestinationTutorialIntroViewController.swift; path = "Code/Visual UI/View Controllers/Tutorials/Destination/DestinationTutorialIntroViewController.swift"; sourceTree = ""; }; @@ -1133,6 +1131,8 @@ 31F12C4122569E9100BDA072 /* StreetSuffixAbbreviations_fr.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = StreetSuffixAbbreviations_fr.plist; path = Assets/PropertyLists/StreetSuffixAbbreviations_fr.plist; sourceTree = ""; }; 31F1370322B867B800FC1860 /* GeolocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GeolocationManager.swift; path = "Code/Sensors/Geolocation/Geolocation Manager/GeolocationManager.swift"; sourceTree = ""; }; 31FE6C77233A7B760098D8C5 /* TelemetryHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TelemetryHelper.swift; path = Code/App/Logging/TelemetryHelper.swift; sourceTree = ""; }; + 3247AF49E74F47A3BC0C066E /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 4BB00625C9264FD5ACF0ED5F /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 5684808F1CBC975E004B4227 /* Soundscape-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = "Soundscape-Bridging-Header.h"; path = "Code/App/Soundscape-Bridging-Header.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 568480901CBC9C94004B4227 /* HomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = HomeViewController.swift; path = "Code/Visual UI/View Controllers/Home/HomeViewController.swift"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 568480921CBC9CEE004B4227 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = SettingsViewController.swift; path = "Code/Visual UI/View Controllers/Settings/SettingsViewController.swift"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; @@ -1572,8 +1572,6 @@ DCAAD87E2BC1E95F0018D135 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Assets/PropertyLists/PrivacyInfo.xcprivacy; sourceTree = ""; }; DCE09DD62E54AC9500B66BDF /* fa-IR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fa-IR"; path = "fa-IR.lproj/Localizable.strings"; sourceTree = ""; }; DCE09DD72E54AE7400B66BDF /* fa-IR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fa-IR"; path = "fa-IR.lproj/InfoPlist.strings"; sourceTree = ""; }; - 4BB00625C9264FD5ACF0ED5F /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/Localizable.strings"; sourceTree = ""; }; - 3247AF49E74F47A3BC0C066E /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/InfoPlist.strings"; sourceTree = ""; }; DCE4D2AC2D7CE40F00B5DA4B /* NewFeatures.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = NewFeatures.json; path = Assets/NewFeatures.json; sourceTree = ""; }; /* End PBXFileReference section */ @@ -3210,7 +3208,7 @@ 629F53E326CB28F400796B23 /* List */, 629F53BE26BDEDA200796B23 /* Text */, 624C96B62852983C001F84F8 /* Navigation */, - 28EB441326B4A16700D5BBE4 /* DeleteModifier.swift */, + 288E5FE1269FA78400F7D4CD /* GeometryPreferenceReader.swift */, 288E5FDF269504D500F7D4CD /* ConditionalAccessibilityAction.swift */, ); @@ -4564,7 +4562,7 @@ "nl-NL", "pt-PT", "fa-IR", - "ru", + ru, ); mainGroup = D3D7CFBF1B3D96460020B5E9; packageReferences = ( @@ -5119,7 +5117,6 @@ C34333B0221E2C1800D9CECD /* TableViewHeaderFooterViewConfigurator.swift in Sources */, C30EF62320894AD400BEA785 /* VoiceTableViewCell.swift in Sources */, 626789B026F540CF0007E566 /* RouteDetailLocalizedLabel.swift in Sources */, - 28EB441426B4A16700D5BBE4 /* DeleteModifier.swift in Sources */, 622CAFA226AB815300F804D6 /* BeaconTitleContentView.swift in Sources */, B97791511E8ED1B100498320 /* UINavigationBar+Extentions.swift in Sources */, 623E0103244767BB0081CA5B /* MarkerParameters.swift in Sources */, @@ -5540,7 +5537,7 @@ INFOPLIST_FILE = GuideDogs/Assets/PropertyLists/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Soundscape; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation"; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5833,7 +5830,7 @@ INFOPLIST_FILE = GuideDogs/Assets/PropertyLists/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Soundscape; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation"; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5894,7 +5891,7 @@ INFOPLIST_FILE = GuideDogs/Assets/PropertyLists/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Soundscape; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.navigation"; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/apps/ios/GuideDogs/Code/Visual UI/Modifiers/DeleteModifier.swift b/apps/ios/GuideDogs/Code/Visual UI/Modifiers/DeleteModifier.swift deleted file mode 100644 index d5eebafcc..000000000 --- a/apps/ios/GuideDogs/Code/Visual UI/Modifiers/DeleteModifier.swift +++ /dev/null @@ -1,111 +0,0 @@ -// -// DeleteModifier.swift -// Soundscape -// -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -// - -import SwiftUI - -struct Delete: ViewModifier { - @ScaledMetric(relativeTo: .title) var iconSize: CGFloat = 24.0 - - let action: () -> Void - - @State var offset: CGSize = .zero - @State var initialOffset: CGSize = .zero - @State var contentWidth: CGFloat = 0.0 - @State var deletionDistance: CGFloat = 80.0 - @State var waitingForMinGesture = true - @State var willDeleteIfReleased = false - - // MARK: Constants - - let minGetureWidth: CGFloat = -40.0 - let tappableDeletionWidth: CGFloat = -80.0 - let deletionSkipLength: CGFloat = 60.0 - - func body(content: Content) -> some View { - content - .background( - GeometryReader { geometry in - ZStack(alignment: .trailing) { - Rectangle() - .foregroundColor(.red) - - Image(systemName: "trash") - .frame(height: iconSize) - .font(.title) - .foregroundColor(.white) - .padding() - } - .accessibilityHidden(true) - .frame(width: -offset.width) - .offset(x: geometry.size.width) - .onAppear { - contentWidth = geometry.size.width - deletionDistance -= contentWidth - } - .gesture(TapGesture().onEnded { delete() }) - } - ) - .offset(x: offset.width, y: 0) - .gesture( - DragGesture() - .onChanged { gesture in - if waitingForMinGesture && gesture.translation.width > minGetureWidth { - return - } else if waitingForMinGesture && gesture.translation.width < minGetureWidth { - waitingForMinGesture = false - offset.width = gesture.translation.width + initialOffset.width + minGetureWidth - } else if gesture.translation.width + initialOffset.width <= 0 { - offset.width = gesture.translation.width + initialOffset.width - } - - if self.offset.width < deletionDistance && !willDeleteIfReleased { - // Trigger haptic feedback and jump the offset further along - // to the left - hapticFeedback() - willDeleteIfReleased = true - initialOffset.width -= deletionSkipLength - offset.width -= deletionSkipLength - } else if offset.width > deletionDistance && willDeleteIfReleased { - hapticFeedback() - willDeleteIfReleased = false - } - } - .onEnded { _ in - if offset.width < deletionDistance { - delete() - } else if offset.width < tappableDeletionWidth { - offset.width = tappableDeletionWidth - initialOffset.width = tappableDeletionWidth - } else { - offset = .zero - initialOffset = .zero - } - waitingForMinGesture = true - } - ) - .animation(.interactiveSpring()) - } - - private func delete() { - offset.width = -contentWidth - action() - } - - private func hapticFeedback() { - let generator = UIImpactFeedbackGenerator(style: .medium) - generator.impactOccurred() - } -} - -extension View { - - func onDelete(perform action: @escaping () -> Void) -> some View { - self.modifier(Delete(action: action)) - } - -} diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift index e4fb6dd19..e2da08cd2 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Home/HomeViewController.swift @@ -124,6 +124,11 @@ class HomeViewController: UIViewController { // Add search controller to navigation bar configureSearchAndBrowseView() self.navigationItem.hidesSearchBarWhenScrolling = false + + // Don't allow ios 26 to move the search to the bottom. + if #available(iOS 26.0, *) { + self.navigationItem.searchBarPlacementAllowsToolbarIntegration = false + } // Search results will be displayed modally // Use this view controller to define presentation context diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkerCell.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkerCell.swift index 99265c753..bf20c320e 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkerCell.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkerCell.swift @@ -137,6 +137,7 @@ struct MarkerCell: View { .padding([.trailing]) .accessibilityHidden(true) } + .contentShape(Rectangle()) .background(Color.primaryBackground) .accessibilityElement(children: .combine) } diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesList.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesList.swift index bc694822b..0a4d68112 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesList.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersAndRoutesList.swift @@ -107,14 +107,11 @@ struct MarkersAndRoutesList: View { .ignoresSafeArea() VStack(spacing: 0) { - ScrollView { - if selectedList == .markers { - MarkersList(sort: $sort) - } else { - RoutesList(sort: $sort) - } + if selectedList == .markers { + MarkersList(sort: $sort) + } else { + RoutesList(sort: $sort) } - .padding([.top], 1) HStack { MarkerRouteTabButton(name: GDLocalizedString("markers.title"), diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersList.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersList.swift index 30cfe7ad0..77df220ab 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersList.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/MarkersList.swift @@ -54,57 +54,25 @@ struct MarkersList: View { GDATelemetry.trackScreenView("markers_list.empty") } } else { - VStack(spacing: 0) { + List { SortStyleCell(listName: GDLocalizedString("markers.title"), sort: _sort) - + .plainListRowBackground(Color.quaternaryBackground) + ForEach(loader.markerIDs, id: \.self) { id in - MarkerCell(model: MarkerModel(id: id)) - .accessibilityAddTraits(.isButton) - .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.beacon.text)) { - if let poi = entity(for: id) { - navHelper.didSelectLocationAction(.beacon, entity: poi) - } - } - .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.edit.text)) { - selectedDetail = LocationDetail(markerId: id, telemetryContext: "markers_list") - goToNavDestination = true - } - .conditionalAccessibilityAction(routeIsActive == false, named: GDLocalizedTextView("general.alert.delete")) { - alert = confirmationAlert(for: id) - showAlert = true - } - .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.preview.text)) { - if let poi = entity(for: id) { - navHelper.didSelectLocationAction(.preview, entity: poi) - } - } - .accessibilityAction(named: Text(LocationAction.share(isEnabled: true).text), { - if let poi = entity(for: id) { - navHelper.didSelectLocationAction(.share(isEnabled: true), entity: poi) - } - }) - .if(routeIsActive == false, transform: { - $0.onDelete { - delete(id) - } - }) - .onTapGesture { - selectedDetail = LocationDetail(markerId: id, telemetryContext: "markers_list") - - let storyboard = UIStoryboard(name: "POITable", bundle: Bundle.main) - - guard let viewController = storyboard.instantiateViewController(identifier: "LocationDetailView") as? LocationDetailViewController else { - return - } - - viewController.locationDetail = selectedDetail - viewController.deleteAction = .popToViewController(type: MarkersAndRoutesListHostViewController.self) - viewController.onDismissPreviewHandler = navHelper.onDismissPreviewHandler - - navHelper.pushViewController(viewController, animated: true) - } + markerRow(id) + .deleteDisabled(routeIsActive) + } + .onDelete { offsets in + guard let index = offsets.first else { + return + } + + let id = loader.markerIDs[index] + alert = confirmationAlert(for: id) + showAlert = true } } + .listStyle(PlainListStyle()) .background(Color.quaternaryBackground) .alert(isPresented: $showAlert, content: { alert ?? errorAlert() }) @@ -124,8 +92,10 @@ struct MarkersList: View { private func confirmationAlert(for markerID: String) -> Alert { return Alert.deleteMarkerAlert(markerId: markerID, - deleteAction: { delete(markerID) }, - cancelAction: { selectedDetail = nil }) + deleteAction: { + delete(markerID) + }, + cancelAction: { }) } private func errorAlert() -> Alert { @@ -142,6 +112,49 @@ struct MarkersList: View { showAlert = true } } + + @ViewBuilder + private func markerRow(_ id: String) -> some View { + Button { + selectedDetail = LocationDetail(markerId: id, telemetryContext: "markers_list") + + let storyboard = UIStoryboard(name: "POITable", bundle: Bundle.main) + + guard let viewController = storyboard.instantiateViewController(identifier: "LocationDetailView") as? LocationDetailViewController else { + return + } + + viewController.locationDetail = selectedDetail + viewController.deleteAction = .popToViewController(type: MarkersAndRoutesListHostViewController.self) + viewController.onDismissPreviewHandler = navHelper.onDismissPreviewHandler + + navHelper.pushViewController(viewController, animated: true) + } label: { + MarkerCell(model: MarkerModel(id: id)) + } + .buttonStyle(.plain) + .accessibilityAddTraits(.isButton) + .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.beacon.text)) { + if let poi = entity(for: id) { + navHelper.didSelectLocationAction(.beacon, entity: poi) + } + } + .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.edit.text)) { + selectedDetail = LocationDetail(markerId: id, telemetryContext: "markers_list") + goToNavDestination = true + } + .conditionalAccessibilityAction(routeIsActive == false, named: Text(LocationAction.preview.text)) { + if let poi = entity(for: id) { + navHelper.didSelectLocationAction(.preview, entity: poi) + } + } + .accessibilityAction(named: Text(LocationAction.share(isEnabled: true).text), { + if let poi = entity(for: id) { + navHelper.didSelectLocationAction(.share(isEnabled: true), entity: poi) + } + }) + .plainListRowBackground(Color.quaternaryBackground) + } } struct MarkersList_Previews: PreviewProvider { diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RouteCell.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RouteCell.swift index 600b32c8b..3d81b5b4e 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RouteCell.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RouteCell.swift @@ -100,6 +100,7 @@ struct RouteCell: View { .padding([.trailing]) .accessibilityHidden(true) } + .contentShape(Rectangle()) .background(Color.primaryBackground) .accessibilityElement(children: .combine) } diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RoutesList.swift b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RoutesList.swift index 4d2eda90d..912cab6d9 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RoutesList.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Markers & Routes/RoutesList.swift @@ -80,60 +80,28 @@ struct RoutesList: View { GDATelemetry.trackScreenView("routes_list.empty") } } else { - VStack(spacing: 0) { + List { SortStyleCell(listName: GDLocalizedString("routes.title"), sort: _sort) - + .plainListRowBackground(Color.quaternaryBackground) + ForEach(loader.routeIDs, id: \.self) { id in - RouteCell(model: RouteModel(id: id)) - .accessibilityAddTraits(.isButton) - .conditionalAccessibilityAction(AppContext.shared.eventProcessor.activeBehavior is SoundscapeBehavior && activeRouteID == nil, named: Text(RouteActionState(.startRoute).text)) { - GDATelemetry.track("routes.start", with: ["source": "accessibility_action"]) - - let routeGuidance = RouteGuidance(.init(source: .database(id: id)), - spatialData: AppContext.shared.spatialDataContext, - motion: AppContext.shared.motionActivityContext) - AppContext.shared.eventProcessor.activateCustom(behavior: routeGuidance) - navHelper.popToRootViewController(animated: true) - } - .conditionalAccessibilityAction(id == activeRouteID, named: Text(RouteActionState(.stopRoute).text)) { - GDATelemetry.track("routes.stop", with: ["source": "accessibility_action"]) - - AppContext.shared.eventProcessor.deactivateCustom() - } - .conditionalAccessibilityAction(id != activeRouteID, named: Text(RouteActionState(.edit).text)) { - GDATelemetry.track("routes.edit", with: ["source": "accessibility_action"]) - - selectedDetail = RouteDetail(source: .database(id: id)) - showEditView = true - goToNavDestination = true - } - .conditionalAccessibilityAction(id != activeRouteID, named: GDLocalizedTextView("general.alert.delete")) { - GDATelemetry.track("routes.delete", with: ["source": "accessibility_action"]) - - alert = confirmationAlert(for: id) - showAlert = true - } - .accessibilityAction(named: Text(RouteActionState(.share).text), { - GDATelemetry.track("routes.share", with: ["source": "accessibility_action"]) - - isPresentingForRouteId = id - - if FirstUseExperience.didComplete(.share) { - presentShareActivityViewController() - } else { - isPresentingFirstUseShareAlert = true - } - }) - .onDelete { - delete(id) - } - .onTapGesture { - selectedDetail = RouteDetail(source: .database(id: id)) - showEditView = false - goToNavDestination = true - } + routeRow(id) + } + .onDelete { offsets in + guard let index = offsets.first else { + return + } + + let id = loader.routeIDs[index] + guard id != activeRouteID else { + return + } + + alert = confirmationAlert(for: id) + showAlert = true } } + .listStyle(PlainListStyle()) .background(Color.quaternaryBackground) .alert(isPresented: $showAlert, content: { alert ?? errorAlert() }) @@ -160,7 +128,7 @@ struct RoutesList: View { } let cancel: Alert.Button = .cancel(GDLocalizedTextView("general.alert.cancel")) { - selectedDetail = nil + // No-op } return Alert(title: GDLocalizedTextView("route_detail.edit.delete.title"), @@ -183,6 +151,53 @@ struct RoutesList: View { showAlert = true } } + + @ViewBuilder + private func routeRow(_ id: String) -> some View { + Button { + selectedDetail = RouteDetail(source: .database(id: id)) + showEditView = false + goToNavDestination = true + } label: { + RouteCell(model: RouteModel(id: id)) + } + .buttonStyle(.plain) + .accessibilityAddTraits(.isButton) + .conditionalAccessibilityAction(AppContext.shared.eventProcessor.activeBehavior is SoundscapeBehavior && activeRouteID == nil, named: Text(RouteActionState(.startRoute).text)) { + GDATelemetry.track("routes.start", with: ["source": "accessibility_action"]) + + let routeGuidance = RouteGuidance(.init(source: .database(id: id)), + spatialData: AppContext.shared.spatialDataContext, + motion: AppContext.shared.motionActivityContext) + AppContext.shared.eventProcessor.activateCustom(behavior: routeGuidance) + navHelper.popToRootViewController(animated: true) + } + .conditionalAccessibilityAction(id == activeRouteID, named: Text(RouteActionState(.stopRoute).text)) { + GDATelemetry.track("routes.stop", with: ["source": "accessibility_action"]) + + AppContext.shared.eventProcessor.deactivateCustom() + } + .conditionalAccessibilityAction(id != activeRouteID, named: Text(RouteActionState(.edit).text)) { + GDATelemetry.track("routes.edit", with: ["source": "accessibility_action"]) + + selectedDetail = RouteDetail(source: .database(id: id)) + showEditView = true + goToNavDestination = true + } + .accessibilityAction(named: Text(RouteActionState(.share).text), { + GDATelemetry.track("routes.share", with: ["source": "accessibility_action"]) + + isPresentingForRouteId = id + + if FirstUseExperience.didComplete(.share) { + presentShareActivityViewController() + } else { + isPresentingFirstUseShareAlert = true + } + }) + .deleteDisabled(id == activeRouteID) + .plainListRowBackground(Color.quaternaryBackground) + } } struct RoutesList_Previews: PreviewProvider { From 4996b3b9b7077c5df94fd09732548d731f0a07b7 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Fri, 9 Jan 2026 04:43:44 +0000 Subject: [PATCH 66/76] Update project build to 5 and copyright year to 2026 in licenses --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 7 +++---- apps/ios/GuideDogs/Assets/Licenses/licenses.html | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 53a042653..40e311f08 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -3208,7 +3208,6 @@ 629F53E326CB28F400796B23 /* List */, 629F53BE26BDEDA200796B23 /* Text */, 624C96B62852983C001F84F8 /* Navigation */, - 288E5FE1269FA78400F7D4CD /* GeometryPreferenceReader.swift */, 288E5FDF269504D500F7D4CD /* ConditionalAccessibilityAction.swift */, ); @@ -5515,7 +5514,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5807,7 +5806,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 5; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5870,7 +5869,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; diff --git a/apps/ios/GuideDogs/Assets/Licenses/licenses.html b/apps/ios/GuideDogs/Assets/Licenses/licenses.html index 527a6696d..84a726205 100644 --- a/apps/ios/GuideDogs/Assets/Licenses/licenses.html +++ b/apps/ios/GuideDogs/Assets/Licenses/licenses.html @@ -21,7 +21,7 @@

MIT License

- Copyright © 2025 Soundscape Community Contributors + Copyright © 2026 Soundscape Community Contributors
Copyright © Microsoft Corporation.

From 0b4e5fd2502f3b7325e298fe099017474c30ed27 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 20:03:22 +0000 Subject: [PATCH 67/76] Update privacy policy URL to vially.io (#232) * Update privacy policy URL to https://vially.io/privacy-policy Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --- apps/ios/GuideDogs/Code/App/AppContext.swift | 2 +- apps/ios/fastlane/metadata/en-GB/privacy_url.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/ios/GuideDogs/Code/App/AppContext.swift b/apps/ios/GuideDogs/Code/App/AppContext.swift index c95dcd7c6..e65c0592b 100644 --- a/apps/ios/GuideDogs/Code/App/AppContext.swift +++ b/apps/ios/GuideDogs/Code/App/AppContext.swift @@ -376,7 +376,7 @@ extension AppContext { struct Links { static func privacyPolicyURL(for locale: Locale) -> URL { - return URL(string: "https://ialabs.ie/privacy-policy")! + return URL(string: "https://vially.io/privacy-policy")! } static func servicesAgreementURL(for locale: Locale) -> URL { diff --git a/apps/ios/fastlane/metadata/en-GB/privacy_url.txt b/apps/ios/fastlane/metadata/en-GB/privacy_url.txt index 79a61f09a..5e3826cf0 100644 --- a/apps/ios/fastlane/metadata/en-GB/privacy_url.txt +++ b/apps/ios/fastlane/metadata/en-GB/privacy_url.txt @@ -1 +1 @@ -https://ialabs.ie/privacy-policy/ +https://vially.io/privacy-policy From 72bd15ee2e1c90f51f07f3936bdae6c30c13ba43 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 00:15:40 +0000 Subject: [PATCH 68/76] Keep search bars pinned to top across search flows (#235) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --- .../POI Table/SearchResultsTableViewController.swift | 5 +++++ .../POI Table/SearchTableViewController.swift | 5 +++++ .../POI Table/SearchWaypointViewController.swift | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchResultsTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchResultsTableViewController.swift index b3a0f1867..4daacd022 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchResultsTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchResultsTableViewController.swift @@ -88,6 +88,11 @@ class SearchResultsTableViewController: UITableViewController { searchVC.navigationItem.searchController = searchController searchVC.navigationItem.hidesSearchBarWhenScrolling = false + + // Don't allow iOS 26 to move the search to the bottom. + if #available(iOS 26.0, *) { + searchVC.navigationItem.searchBarPlacementAllowsToolbarIntegration = false + } let navigationVC = NavigationController(rootViewController: searchVC) return navigationVC diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift index cf4f8ecd1..d50e4d08a 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchTableViewController.swift @@ -104,6 +104,11 @@ class SearchTableViewController: BaseTableViewController { // Add search controller to navigation bar self.navigationItem.searchController = self.searchController self.navigationItem.hidesSearchBarWhenScrolling = false + + // Don't allow iOS 26 to move the search to the bottom. + if #available(iOS 26.0, *) { + self.navigationItem.searchBarPlacementAllowsToolbarIntegration = false + } // Search results will be displayed modally // Use this view controller to define presentation context diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchWaypointViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchWaypointViewController.swift index 7e1412cfa..64680ed09 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchWaypointViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/SearchWaypointViewController.swift @@ -44,6 +44,11 @@ class SearchWaypointViewController: UIViewController { // Add search controller to navigation bar self.navigationItem.searchController = self.searchController self.navigationItem.hidesSearchBarWhenScrolling = false + + // Don't allow iOS 26 to move the search to the bottom. + if #available(iOS 26.0, *) { + self.navigationItem.searchBarPlacementAllowsToolbarIntegration = false + } // Search results will be displayed modally // Use this view controller to define presentation context From 5f3723f0f087d02016c19786204d5d1230354b5b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 31 Jan 2026 14:34:53 +0000 Subject: [PATCH 69/76] Remove callout-specific accessibility overrides in Help & Tutorials (#236) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RDMurray <23378611+RDMurray@users.noreply.github.com> --- .../Behaviors/Default/Callouts/POICallout.swift | 4 ++-- .../Callouts/Protocols/CalloutOrigin.swift | 3 --- .../BaseTableViewController.swift | 12 ------------ .../Help/HelpPageFAQViewController.swift | 2 -- .../Help/HelpPageGenericViewController.swift | 13 ------------- .../Help/HelpPageViewController.swift | 17 ----------------- 6 files changed, 2 insertions(+), 49 deletions(-) diff --git a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift index 4596b9032..4469c1f15 100644 --- a/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift +++ b/apps/ios/GuideDogs/Code/Behaviors/Default/Callouts/POICallout.swift @@ -186,9 +186,9 @@ struct POICallout: POICalloutProtocol { func moreInfoDescription(for location: CLLocation?) -> String { guard let locationDescription = distanceDescription(for: location, tts: true) else { - return GDLocalizedString("announced_name.named", origin.localizedStringForAccessibility, timeDescription) + return GDLocalizedString("announced_name.named", origin.localizedString, timeDescription) } - return GDLocalizedString("announced_name_distance_away.named", origin.localizedStringForAccessibility, timeDescription, locationDescription) + return GDLocalizedString("announced_name_distance_away.named", origin.localizedString, timeDescription, locationDescription) } } diff --git a/apps/ios/GuideDogs/Code/Generators/Callouts/Protocols/CalloutOrigin.swift b/apps/ios/GuideDogs/Code/Generators/Callouts/Protocols/CalloutOrigin.swift index 5fae3e552..590cdb4b6 100644 --- a/apps/ios/GuideDogs/Code/Generators/Callouts/Protocols/CalloutOrigin.swift +++ b/apps/ios/GuideDogs/Code/Generators/Callouts/Protocols/CalloutOrigin.swift @@ -16,9 +16,6 @@ struct CalloutOrigin: RawRepresentable, Equatable, Hashable { var localizedString: String - var localizedStringForAccessibility: String { - return localizedString.lowercasedWithAppLocale().replacingOccurrences(of: "callout", with: "call out") - } init?(rawValue: String) { self.rawValue = rawValue diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/BaseTableViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/BaseTableViewController.swift index fc8489f6f..24897612d 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/BaseTableViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/BaseTableViewController.swift @@ -28,12 +28,6 @@ class BaseTableViewController: UITableViewController { view.textLabel?.textColor = Colors.Foreground.primary view.backgroundView?.backgroundColor = Colors.Background.quaternary - - if let text = view.textLabel?.text, text.lowercased().contains("callout") { - view.accessibilityLabel = text.lowercased().replacingOccurrences(of: "callout", with: "call out") - } else { - view.accessibilityLabel = view.textLabel?.text - } } override func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { @@ -41,12 +35,6 @@ class BaseTableViewController: UITableViewController { view.textLabel?.textColor = Colors.Foreground.primary view.backgroundView?.backgroundColor = Colors.Background.quaternary - - if let text = view.textLabel?.text, text.lowercased().contains("callout") { - view.accessibilityLabel = text.lowercased().replacingOccurrences(of: "callout", with: "call out") - } else { - view.accessibilityLabel = view.textLabel?.text - } } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageFAQViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageFAQViewController.swift index bdc479986..b98c1432b 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageFAQViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageFAQViewController.swift @@ -33,7 +33,6 @@ class HelpPageFAQViewController: UIViewController { func showParagraphs(stackView: UIStackView, stub: UILabel, paragraphs: [String]) { stub.attributedText = paragraphs.first?.getFormattedString() ?? NSAttributedString(string: GDLocalizedString("text.coming_soon")) - stub.accessibilityLabel = paragraphs.first?.getVoiceOverLabel() guard paragraphs.count > 1 else { return @@ -42,7 +41,6 @@ class HelpPageFAQViewController: UIViewController { for paragraph in paragraphs.suffix(from: 1) { let label = UILabel(frame: CGRect.zero) label.attributedText = paragraph.getFormattedString() - label.accessibilityLabel = paragraph.getVoiceOverLabel() label.numberOfLines = 0 stackView.addArrangedSubview(label) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageGenericViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageGenericViewController.swift index 8816ae566..ae2c651bc 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageGenericViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageGenericViewController.swift @@ -28,23 +28,11 @@ class HelpPageGenericViewController: UIViewController { func loadContent(_ content: TextHelpPage) { title = content.title - if content.title.lowercased().contains("callout") { - let titleLabel = UILabel(frame: CGRect.zero) - titleLabel.text = content.title - titleLabel.accessibilityLabel = content.title.lowercased().replacingOccurrences(of: "callout", with: "call out") - titleLabel.textColor = UIColor.white - titleLabel.textAlignment = .natural - titleLabel.font = UIFont.systemFont(ofSize: 17.0, weight: .semibold) - - navigationItem.titleView = titleLabel - } - self.content = content } func showParagraphs(stackView: UIStackView, stub: UILabel, paragraphs: [String]) { stub.attributedText = paragraphs.first?.getFormattedString() ?? NSAttributedString(string: GDLocalizedString("text.coming_soon")) - stub.accessibilityLabel = paragraphs.first?.getVoiceOverLabel() guard paragraphs.count > 1 else { return @@ -53,7 +41,6 @@ class HelpPageGenericViewController: UIViewController { for paragraph in paragraphs.suffix(from: 1) { let label = UILabel(frame: CGRect.zero) label.attributedText = paragraph.getFormattedString() - label.accessibilityLabel = paragraph.getVoiceOverLabel() label.numberOfLines = 0 stackView.addArrangedSubview(label) diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageViewController.swift index 99c9b9fdd..b59456caf 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/Help/HelpPageViewController.swift @@ -51,17 +51,6 @@ class HelpPageViewController: UIViewController { func loadContent(_ content: SectionedHelpPage) { title = content.title - if content.title.lowercased().contains("callout") { - let titleLabel = UILabel(frame: CGRect.zero) - titleLabel.text = content.title - titleLabel.accessibilityLabel = content.title.lowercased().replacingOccurrences(of: "callout", with: "call out") - titleLabel.textColor = UIColor.white - titleLabel.textAlignment = .natural - titleLabel.font = UIFont.systemFont(ofSize: 17.0, weight: .semibold) - - navigationItem.titleView = titleLabel - } - what = content.what when = content.when how = content.how @@ -70,7 +59,6 @@ class HelpPageViewController: UIViewController { func showParagraphs(stackView: UIStackView, stub: UILabel, paragraphs: [String]) { stub.attributedText = paragraphs.first?.getFormattedString() ?? NSAttributedString(string: GDLocalizedString("text.coming_soon")) - stub.accessibilityLabel = paragraphs.first?.getVoiceOverLabel() guard paragraphs.count > 1 else { return @@ -79,7 +67,6 @@ class HelpPageViewController: UIViewController { for paragraph in paragraphs.suffix(from: 1) { let label = UILabel(frame: CGRect.zero) label.attributedText = paragraph.getFormattedString() - label.accessibilityLabel = paragraph.getVoiceOverLabel() label.numberOfLines = 0 stackView.addArrangedSubview(label) @@ -120,10 +107,6 @@ extension String { return try? NSAttributedString(data: html.data, options: options, documentAttributes: nil) } - func getVoiceOverLabel() -> String? { - let lowercase = self.getFormattedString()?.string.replacingOccurrences(of: "callout", with: "call out") - return lowercase?.replacingOccurrences(of: "Callout", with: "Call out") - } } extension HelpPageViewController: LargeBannerContainerView { From 9eb6109960a676cdcb94559b821927b4daeda271 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Sat, 31 Jan 2026 14:01:58 +0100 Subject: [PATCH 70/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translation: Soundscape/iOS app --- .../Assets/Localization/en-GB.lproj/Localizable.strings | 4 ++-- .../Assets/Localization/en-US.lproj/Localizable.strings | 4 ++-- .../Assets/Localization/es-ES.lproj/Localizable.strings | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index f78b8f019..62f7bb640 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -3337,7 +3337,7 @@ /* */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In IOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; /* */ @@ -4353,7 +4353,7 @@ /* */ -"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; +"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and wayfinding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; /* */ diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 8d2fba89b..8ee3e8e75 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -2798,7 +2798,7 @@ "settings.help.section.home_screen_buttons" = "\"Hear My Surroundings\" Buttons"; /* Help content describing how user can choose a voice and download additional voices */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In IOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; /* Help Page Title, Offline */ "help.offline.page_title" = "Why is Soundscape working offline?"; @@ -3682,7 +3682,7 @@ "faq.difference_from_map_apps.question" = "How is Soundscape different from other map apps?"; /* Wayfinding - The process or activity of ascertaining one’s position and planning and following a route. 3D sound is where the audio through your headphones sounds as though it is coming from a given direction, as if it was actually coming from a speaker. Intersection - A junction where two or more roads meet or cross. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using spatial audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ -"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and way-finding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; +"faq.difference_from_map_apps.answer" = "Soundscape provides an ambient description of your surroundings in aid of exploration and wayfinding. Using spatial audio, Soundscape will call out points of interest, parks, roads, and intersections from the direction they physically are in your immediate environment as you walk. For example, if you pass a shop on your right, you will hear the name of the shop sounding from your right. As you approach an intersection, you will hear each road name sounding from the direction it goes in, beginning to your left, ahead and to the right.\n\nInstead of turn-by-turn directions as often provided by other map applications, Soundscape will play an audible beacon in the direction of your destination, empowering you to make your way there on your terms using your increased awareness of your surroundings and the location of your destination. Soundscape is designed to run in the background, enabling you to use a turn-by-turn directions app, all the while continuing to provide environmental awareness as you make your way to your destination."; /* Wayfinding - The process or activity of ascertaining one’s position and planning and following a route. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.use_with_wayfinding_apps.question" = "How do I use Soundscape with a wayfinding app?"; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index f29ca2c14..9d849faff 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -1979,11 +1979,11 @@ /* */ -"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Esto usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa el botón siguiente para reactivar ahora."; +"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa el botón siguiente para reactivar ahora."; /* */ -"sleep.sleeping.message" = "Soundscape se encuentra actualmente en modo de suspensión. Esto evita que Soundscape use Localización o descargue datos y ahorra batería cuando no se usa Soundscape. Pulsa el botón siguiente para reactivar Soundscape."; +"sleep.sleeping.message" = "Soundscape se encuentra actualmente en el modo de suspensión. Evita que Soundscape use Localización o descargue datos y ahorra batería cuando no se usa Soundscape. Pulsa el botón siguiente para reactivar Soundscape."; /* */ @@ -4310,7 +4310,7 @@ /* */ -"faq.difference_from_map_apps.answer" = "Soundscape ofrece una descripción de tu entorno mediante la exploración y la orientación. Usando el sonido espacial, Soundscape avisará de puntos de interés, parques, carreteras y cruces desde la dirección en la que se encuentran físicamente en tu entorno inmediato mientras caminas. Por ejemplo, si pasas por una tienda que se encuentre a tu derecha, oirás el nombre de la tienda sonando a tu derecha. Cuando te acerques a un cruce, oirás el sonido del nombre de cada carretera proveniente de la dirección a la que se dirige, comenzando por la izquierda, adelante y a la derecha.\n\nEn lugar de indicaciones paso a paso, a menudo proporcionadas por aplicaciones de mapas o GPS tradicionales, Soundscape reproducirá una señal de audio en la dirección de tu destino, lo que te permitirá llegar allí en tus condiciones con el mejor conocimiento posible de tu entorno y de la ubicación de tu destino. Soundscape se ha diseñado para ejecutarse en segundo plano, lo que te permite usar una aplicación de indicaciones paso a paso, y seguirá proporcionando todo el tiempo información del entorno mientras llegas a tu destino."; +"faq.difference_from_map_apps.answer" = "Soundscape ofrece una descripción de tu entorno mediante la exploración y la orientación. Usando el sonido espacial, Soundscape avisará de puntos de interés, parques, carreteras y cruces desde la dirección en la que se encuentran físicamente en tu entorno inmediato mientras caminas. Por ejemplo, si pasas por una tienda que se encuentre a tu derecha, oirás el nombre de la tienda sonando a tu derecha. Cuando te acerques a un cruce, oirás el sonido del nombre de cada carretera proveniente de la dirección a la que se dirige, comenzando por la izquierda, adelante y a la derecha.\n\nEn lugar de indicaciones paso a paso, a menudo proporcionadas por otras aplicaciones de mapas, Soundscape reproducirá una señal de audio en la dirección de tu destino, lo que te permitirá llegar allí en tus condiciones con el mejor conocimiento posible de tu entorno y de la ubicación de tu destino. Soundscape se ha diseñado para ejecutarse en segundo plano, lo que te permite usar una aplicación de indicaciones paso a paso, y seguirá proporcionando todo el tiempo información del entorno mientras llegas a tu destino."; /* */ From 850dd051b95d4b6e8acec78951610682ab2ea5d7 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Sat, 31 Jan 2026 14:53:08 +0000 Subject: [PATCH 71/76] Bump iOS app version to 1.7.4 --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index 40e311f08..eaa13f350 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5514,7 +5514,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/SoundscapeDF.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = ""; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5545,7 +5545,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.3; + MARKETING_VERSION = 1.7.4; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5806,7 +5806,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; @@ -5838,7 +5838,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.3; + MARKETING_VERSION = 1.7.4; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5869,7 +5869,7 @@ CODE_SIGN_ENTITLEMENTS = GuideDogs/Assets/PropertyLists/Soundscape.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = X4H33NKGKY; EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = YES; ENABLE_BITCODE = NO; @@ -5899,7 +5899,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.3; + MARKETING_VERSION = 1.7.4; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; From fb09e11f8d490b9a701b68ac778739514853bfa0 Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Sat, 31 Jan 2026 16:03:39 +0000 Subject: [PATCH 72/76] Bump iOS app version to 1.8.1 --- apps/ios/GuideDogs.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/ios/GuideDogs.xcodeproj/project.pbxproj b/apps/ios/GuideDogs.xcodeproj/project.pbxproj index eaa13f350..d58972411 100644 --- a/apps/ios/GuideDogs.xcodeproj/project.pbxproj +++ b/apps/ios/GuideDogs.xcodeproj/project.pbxproj @@ -5545,7 +5545,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.4; + MARKETING_VERSION = 1.8.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DADHOC"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-adhoc"; @@ -5838,7 +5838,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.4; + MARKETING_VERSION = 1.8.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "services.soundscape-debug"; @@ -5899,7 +5899,7 @@ "$(inherited)", "$(PROJECT_DIR)/GuideDogs", ); - MARKETING_VERSION = 1.7.4; + MARKETING_VERSION = 1.8.1; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) -DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = services.soundscape; From 3a932ad7f36e94c4869e24c6d664cb8f49b9d200 Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Mon, 23 Feb 2026 00:09:57 +0100 Subject: [PATCH 73/76] Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.8% (994 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.8% (995 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.1% (998 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.2% (999 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 85.3% (1000 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/fa/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 26 +-- .../en-US.lproj/Localizable.strings | 26 +-- .../es-ES.lproj/Localizable.strings | 174 +++++++++--------- .../fa-IR.lproj/Localizable.strings | 5 + 4 files changed, 118 insertions(+), 113 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 62f7bb640..2b4d24d39 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -267,11 +267,11 @@ /* */ -"general.error.location_services_enable_instructions.2" = "Turn Location Services On in the Settings app to continue.\n\n1. Press the back button (titled Settings)\n2. Select Privacy & Security\n3. Select Location Services\n4. Turn On Location Services"; +"general.error.location_services_enable_instructions.2" = "Turn Location Services On in the Settings app to continue.\n\n1. Press the back button until you get to the main settings\n2. Select Privacy & Security\n3. Select Location Services\n4. Turn On Location Services"; /* */ -"general.error.location_services_enable_instructions.3" = "Turn Location Services On in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button (titled Settings)\n3. Select Privacy & Security\n4. Select Location Services\n5. Turn On Location Services"; +"general.error.location_services_enable_instructions.3" = "Turn Location Services On in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button until you get to the main settings\n3. Select Privacy & Security\n4. Select Location Services\n5. Turn On Location Services"; /* */ @@ -335,7 +335,7 @@ /* */ -"device_motion.enable.instructions" = "Turn On Fitness Tracking in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the Back button (titled Settings)\n3. Select Privacy & Security\n4. Select Motion & Fitness\n5. Turn on Fitness Tracking\n6. Restart Soundscape"; +"device_motion.enable.instructions" = "Turn On Fitness Tracking in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button until you get to the main settings\n3. Select Privacy & Security\n4. Select Motion & Fitness\n5. Turn on Fitness Tracking\n6. Restart Soundscape"; /* */ @@ -1897,7 +1897,7 @@ /* */ -"filter.not_available" = "Some category filters are not available. You can still browse nearby places by selecting \"%@\"."; +"filter.not_available" = "Some category filters are not available. You can still browse nearby places by selecting \"%@\""; /* */ @@ -3337,7 +3337,7 @@ /* */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by going to \"Settings\" from the menu and then from \"General Settings\" selecting \"Voice\"."; /* */ @@ -3573,7 +3573,7 @@ /* */ -"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk"; +"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of Soundscape's automatic callouts"; /* */ @@ -3713,7 +3713,7 @@ /* */ -"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; +"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen from the menu on the home screen. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; /* */ @@ -3769,11 +3769,11 @@ /* */ -"help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while Soundscape is in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; +"help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while the app runs in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; /* */ -"help.text.remote_control.how" = "

You can access the following features in Soundscape using the media control buttons on your headphones:


⏯ Play/Pause: Mute any current callouts and if the audio beacon is set, toggle the beacon audio.

⏭ Next: Callout \"My Location\".

⏮ Previous: Repeat last callout.

⏩ Skip Forward: Toggle callouts On and Off.

⏪ Skip Backward: Callout \"Around Me\".

"; +"help.text.remote_control.how" = "

You can access the following features in Soundscape using the media control buttons on your headphones:


⏯ Play/Pause: Mute any current callouts and if the audio beacon is set, toggle the beacon audio.

⏭ Next: Callout \"My Location\".

⏮ Previous: Repeat last callout.

⏩ Skip Forward: Toggle callouts On and Off.

⏪ Skip Backward: Callout \"Around Me\".

"; /* */ @@ -4237,7 +4237,7 @@ /* */ -"faq.how_close_to_destination.answer" = "Soundscape can determine the location of your destination to within several metres, but not less. When Soundscape determines that you are close to your destination, you will hear a final callout that your destination is nearby, and the beacon will turn off. You can adjust when the beacon goes silent by going to \"Audio Beacon\" from the \"Settings\" screen and then moving the \"Audio Mute Distance\" slider up or down."; +"faq.how_close_to_destination.answer" = "Soundscape can determine the location of your destination to within several metres, but not less. When Soundscape determines that you are close to your destination, you will hear a final callout that your destination is nearby, and the beacon will turn off. You can adjust the distance at which the beacon goes silent by going to \"Audio Beacon\" from the \"Settings\" screen and then moving the \"Audio Mute Distance\" slider up or down."; /* */ @@ -4413,7 +4413,7 @@ /* */ -"faq.tip.turning_off_auto_callouts" = "If you still want to interact with Soundscape but don’t want to hear automatic callouts, you can turn them off by going to the \"Manage Callouts\" section of the \"Settings\" screen from the menu and then turn off \"Allow Callouts\". Or, if you aren’t going to be using Soundscape, you can put it in either Sleep or Snooze mode using the \"Sleep\" button on the home screen."; +"faq.tip.turning_off_auto_callouts" = "If you still want to interact with Soundscape but don’t want to hear automatic callouts, you can turn callouts off by going to the \"Manage Callouts\" section of the \"Settings\" screen from the menu. Or, if you aren’t going to be using Soundscape, you can put it in either Sleep or Snooze mode using the \"Sleep\" button on the home screen."; /* */ @@ -4468,7 +4468,7 @@ "mail.gmail" = "Gmail"; "mail.spark" = "Spark"; "mail.airmail" = "Airmail"; -"donation.body" = "Please support the ongoing development of the Soundscape Community app by donating on our fundraising page. Every donation brings us a step closer to our vision of helping bring about a world where EVERYONE has equal access to information on their surroundings through our life-enhancing technology."; +"donation.body" = "Please support the ongoing development of the Soundscape Community app by donating on our fundraising page. Every donation brings us a step closer to our vision of helping bring about a world where EVERYONE has equal access to information on their surroundings through our life-enhancing technology."; "menu.donate" = "Donate"; "donation.title" = "Donate to Soundscape Community"; "donation.link" = "Go to Fundraising Page"; @@ -4482,7 +4482,7 @@ "whats_new.1_3_0.0.title" = "Bose Frames Support"; "whats_new.1_3_0.0.description" = "Soundscape now supports head tracking with the Alto or Rondo versions of the Bose Frames. Once they're connected, your Bose Frames will tell Soundscape where you are facing, helping Soundscape to improve your audio experience. To connect your Bose Frames to Soundscape, go to the \"Head Tracking Headphones\" item in the Soundscape menu."; "whats_new.1_3_0.1.title" = "Testing in Texas"; -"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the main menu."; +"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the menu."; "beacon.action.navilens" = "Launch NaviLens"; "location_detail.action.beacon_or_navilens.hint" = "Double tap to launch NaviLens or set an audio beacon, based on how close this location is"; "troubleshooting.tile_server_url.explanation" = "This is the server from which Soundscape retrieves map data. You normally should not need to change this unless you are developing or testing Soundscape."; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 8ee3e8e75..303d7a706 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -212,10 +212,10 @@ "general.error.location_services_enable_description" = "Location Services are currently disabled. Soundscape cannot work when Location Services are turned off."; /* Error message to turn on location services in Soundscape to continue with instructions on how to do so on device. Keep newlines (\n) between sentences. "Location Services" is an iOS term that can be found in the Privacy section in the iPhone Settings app. {NumberedPlaceholder="\n"} */ -"general.error.location_services_enable_instructions.2" = "Turn Location Services On in the Settings app to continue.\n\n1. Press the back button (titled Settings)\n2. Select Privacy & Security\n3. Select Location Services\n4. Turn On Location Services"; +"general.error.location_services_enable_instructions.2" = "Turn Location Services On in the Settings app to continue.\n\n1. Press the back button until you get to the main settings\n2. Select Privacy & Security\n3. Select Location Services\n4. Turn On Location Services"; /* Error message to turn on location services in Soundscape to continue with instructions on how to do so on device. Keep newlines (\n) between sentences. "Location Services" is an iOS term that can be found in the Privacy section in the iPhone Settings app. {NumberedPlaceholder="\n"} */ -"general.error.location_services_enable_instructions.3" = "Turn Location Services On in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button (titled Settings)\n3. Select Privacy & Security\n4. Select Location Services\n5. Turn On Location Services"; +"general.error.location_services_enable_instructions.3" = "Turn Location Services On in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button until you get to the main settings\n3. Select Privacy & Security\n4. Select Location Services\n5. Turn On Location Services"; /* Error message Sounscape is haveing trouble determining current location */ "general.error.location_services_find_location_error" = "We are having trouble finding your current location."; @@ -279,7 +279,7 @@ "device_motion.enable.description" = "Motion & Fitness tracking is currently disabled. Soundscape cannot work when Motion & Fitness tracking is turned off."; /* Notification to enable motion and fitness activity on the device. Keep newlines (\n) between sentences. Ensure that "Motion & Fitness" is translated the same as `device_motion.title`. {NumberedPlaceholder="Soundscape"} */ -"device_motion.enable.instructions" = "Turn On Fitness Tracking in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the Back button (titled Settings)\n3. Select Privacy & Security\n4. Select Motion & Fitness\n5. Turn on Fitness Tracking\n6. Restart Soundscape"; +"device_motion.enable.instructions" = "Turn On Fitness Tracking in the Settings app to continue.\n\n1. Press Open Settings\n2. Press the back button until you get to the main settings\n3. Select Privacy & Security\n4. Select Motion & Fitness\n5. Turn on Fitness Tracking\n6. Restart Soundscape"; //------------------------------------------------------------------------------ // MARK: Motion & Fitness (Authorize) @@ -1605,7 +1605,7 @@ "filter.selected" = "%@ (selected)"; /* Message displayed when category filters are not available, %@ is a placeholder for the value of the `filter.all` translated string, Quotes written as \" {NumberedPlaceholder="%@"} */ -"filter.not_available" = "Some category filters are not available. You can still browse nearby places by selecting \"%@\"."; +"filter.not_available" = "Some category filters are not available. You can still browse nearby places by selecting \"%@\""; //------------------------------------------------------------------------------ // MARK: - Callouts @@ -2798,7 +2798,7 @@ "settings.help.section.home_screen_buttons" = "\"Hear My Surroundings\" Buttons"; /* Help content describing how user can choose a voice and download additional voices */ -"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by tapping \"Settings\" on the main menu and then from \"General Settings\" selecting \"Voice\"."; +"help.config.voices.content" = "Soundscape can use any of the voices you have downloaded in the iOS Settings app except for the Siri voices which are not available to Soundscape. We recommend choosing one of the higher quality \"Enhanced\" voices, but you will need to download it first. You can download voices in the iOS Settings app by going to Accessibility > Read & Speak > Voices and tapping on a voice. (In iOS Versions before 26, \"Read & Speak\" is called \"Spoken Content\".) Within the Soundscape App, you can select the voice you want to use by going to \"Settings\" from the menu and then from \"General Settings\" selecting \"Voice\"."; /* Help Page Title, Offline */ "help.offline.page_title" = "Why is Soundscape working offline?"; @@ -2983,7 +2983,7 @@ "first_launch.callouts.listen.accessibility_label" = "Listen"; /* Accessibility hint for button that plays example callouts {NumberedPlaceholder="Soundscape"} */ -"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of what Soundscape might call out on your next walk"; +"first_launch.callouts.listen.accessibility_hint" = "Double tap to listen to an example of Soundscape's automatic callouts"; /* Example callout for a coffee shop / cafe */ "first_launch.callouts.example.1" = "Cafe"; @@ -3095,7 +3095,7 @@ "help.text.automatic_callouts.how.1" = "Turning callouts on or off:
Turning callouts off will silence the app. Callouts can be turned on or off by going to the \"Manage Callouts\" section of the \"Settings\" screen and then toggling the \"Allow Callouts\" button. You can also turn callouts on or off by using the \"skip forward\" command (double tap and hold) if your headphones have media control buttons. Alternatively, you can use the \"Sleep\" button in the upper right-hand corner of the home screen to stop Soundscape from making callouts until you wake it up."; /* Notification, Information how to turn on callouts continued. Ensure that "Manage Callouts" is translated the same as `menu.manage_callouts` and "Allow callouts" is translated the same as `callouts.allow_callouts`. Quotes written as \" {NumberedPlaceholder="","","
"} */ -"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen within the main menu. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; +"help.text.automatic_callouts.how.2" = "Managing which callouts you hear:
To choose the types of things Soundscape will automatically call out, go to the \"Settings\" screen from the menu on the home screen. The \"Manage Callouts\" section of the \"Settings\" screen contains a list of types of things the app can call out. Each item has a toggle button that you can turn on or off. If you wish to turn off all callouts, tap the \"Allow Callouts\" toggle at the top of the list."; /* Notification, Information about what My Location does. Ensure that "My Location" is translated the same as `directions.my_location`. Quotes written as \" {NumberedPlaceholder="",""} */ "help.text.my_location.what" = "The \"My Location\" button quickly gives you information that helps you figure out where you currently are. \"My Location\" tells you about your current location including things like the direction you are facing, where nearby roads or intersections are, and where nearby points of interest are."; @@ -3137,10 +3137,10 @@ "help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; /* Notification, Information about when to use media controls on headphones. {NumberedPlaceholder="Soundscape"} */ -"help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while Soundscape is in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; +"help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while the app runs in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; /* Notification, Information about how to use media controls on headphones. Ensure that "My Location" is translated the same as `directions.my_location` and "Around Me" is translated the same as `help.orient.page_title`. Quotes written as \" {NumberedPlaceholder="

","
","⏯","

","⏭","","","⏮","⏩","⏪"} */ -"help.text.remote_control.how" = "

You can access the following features in Soundscape using the media control buttons on your headphones:


⏯ Play/Pause: Mute any current callouts and if the audio beacon is set, toggle the beacon audio.

⏭ Next: Callout \"My Location\".

⏮ Previous: Repeat last callout.

⏩ Skip Forward: Toggle callouts On and Off.

⏪ Skip Backward: Callout \"Around Me\".

"; +"help.text.remote_control.how" = "

You can access the following features in Soundscape using the media control buttons on your headphones:


⏯ Play/Pause: Mute any current callouts and if the audio beacon is set, toggle the beacon audio.

⏭ Next: Callout \"My Location\".

⏮ Previous: Repeat last callout.

⏩ Skip Forward: Toggle callouts On and Off.

⏪ Skip Backward: Callout \"Around Me\".

"; /* Notification, Markers content {NumberedPlaceholder="Soundscape"} */ "help.text.markers.content.1" = "With Soundscape, you can mark your world and anything you care about."; @@ -3521,7 +3521,7 @@ "whats_new.1_3_0.1.title" = "Testing in Texas"; /* Description of the request for testing in Texas */ -"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the main menu."; +"whats_new.1_3_0.1.description" = "If you live in the Austin or San Antonio areas in Texas and would like to help us test a feature we are working on with NaviLens, please get in touch via the \"Send Feedback\" button from the menu."; /* Description of how users can download new voices. "Settings" and "Spoken Content" should be translated in the same way they are translated in the iOS Settin gs app. {NumberedPlaceholder="iOS"} */ "voice.apple.additional" = "Additional voices, including enhanced quality voices, can be downloaded in the Read & Speak section of the iOS accessibility settings."; @@ -3593,7 +3593,7 @@ "faq.how_close_to_destination.question" = "When I set a beacon on a destination, how close will Soundscape get me there?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. {NumberedPlaceholder="Soundscape"} */ -"faq.how_close_to_destination.answer" = "Soundscape can determine the location of your destination to within several meters, but not less. When Soundscape determines that you are close to your destination, you will hear a final callout that your destination is nearby, and the beacon will turn off. You can adjust when the beacon goes silent by going to \"Audio Beacon\" from the \"Settings\" screen and then moving the \"Audio Mute Distance\" slider up or down."; +"faq.how_close_to_destination.answer" = "Soundscape can determine the location of your destination to within several meters, but not less. When Soundscape determines that you are close to your destination, you will hear a final callout that your destination is nearby, and the beacon will turn off. You can adjust the distance at which the beacon goes silent by going to \"Audio Beacon\" from the \"Settings\" screen and then moving the \"Audio Mute Distance\" slider up or down."; /* A 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. */ "faq.turn_beacon_back_on.question" = "Can I turn the beacon back on when I am close to my destination?"; @@ -3729,7 +3729,7 @@ "faq.tip.turning_beacon_off" = "You can turn on and off the rhythmic sound of the beacon using the mute button on the home screen. If the beacon is muted, you will still get updates about the distance to your destination every 50 meters or so."; /* 'Manage Callouts' is the name of one of the sections on the Soundscape Settings screen. Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. Snooze - To put the app in an idle state that is interrupted by user movement. Sleep - To put the app in an idle state for a period of time. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.tip.turning_off_auto_callouts" = "If you still want to interact with Soundscape but don’t want to hear automatic callouts, you can turn them off by going to the \"Manage Callouts\" section of the \"Settings\" screen from the menu and then turn off \"Allow Callouts\". Or, if you aren’t going to be using Soundscape, you can put it in either Sleep or Snooze mode using the \"Sleep\" button on the home screen."; +"faq.tip.turning_off_auto_callouts" = "If you still want to interact with Soundscape but don’t want to hear automatic callouts, you can turn callouts off by going to the \"Manage Callouts\" section of the \"Settings\" screen from the menu. Or, if you aren’t going to be using Soundscape, you can put it in either Sleep or Snooze mode using the \"Sleep\" button on the home screen."; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. {NumberedPlaceholder="Soundscape"} */ "faq.tip.hold_phone_flat" = "Soundscape works best when you hold the phone flat with the screen facing the sky and the top of the phone pointing away from you."; @@ -3747,7 +3747,7 @@ "donation.title" = "Donate to Soundscape Community"; /* text for donation screen */ -"donation.body" = "Please support the ongoing development of the Soundscape Community app by donating on our fundraising page. Every donation brings us a step closer to our vision of helping bring about a world where EVERYONE has equal access to information on their surroundings through our life-enhancing technology."; +"donation.body" = "Please support the ongoing development of the Soundscape Community app by donating on our fundraising page. Every donation brings us a step closer to our vision of helping bring about a world where EVERYONE has equal access to information on their surroundings through our life-enhancing technology."; /* Donation link title */ "donation.link" = "Go to Fundraising Page"; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 9d849faff..3bd3a2266 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -19,7 +19,7 @@ /* */ -"general.alert.not_now" = "Ahora no"; +"general.alert.not_now" = "No ahora"; /* */ @@ -103,7 +103,7 @@ /* */ -"general.alert.open_settings" = "Abrir Ajustes"; +"general.alert.open_settings" = "Abrir ajustes"; /* */ @@ -243,19 +243,19 @@ /* */ -"general.error.location_services.authorize.description" = "Soundscape usa tu ubicación para encontrar e informarte sobre los lugares y cosas de tu entorno. La aplicación necesita tu permiso para usar la localización."; +"general.error.location_services.authorize.description" = "Soundscape usa tu ubicación para encontrar los lugares y elementos de tu entorno e informarte de ellos. La aplicación necesita tu permiso para usar los servicios de localización."; /* */ -"general.error.location_services.authorize.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona Ubicación\n3. Selecciona Siempre o Cuando se use la app"; +"general.error.location_services.authorize.instructions" = "1. Abre la aplicación de ajustes a continuación\n2. Selecciona Ubicación\n3. Selecciona Siempre o Cuando se use la app"; /* */ -"general.error.location_services.precise_location.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Selecciona Ubicación\n3. Activa Ubicación exacta"; +"general.error.location_services.precise_location.instructions" = "1. Abre la aplicación de ajustes a continuación\n2. Selecciona Ubicación\n3. Activa Ubicación exacta"; /* */ -"general.error.location_services_resume" = "Abre Soundscape para reanudar la localización"; +"general.error.location_services_resume" = "Abre Soundscape para reanudar los servicios de localización"; /* */ @@ -263,15 +263,15 @@ /* */ -"general.error.location_services_enable_description" = "La localización está deshabilitada actualmente. Soundscape no puede funcionar cuando la localización está desactivada."; +"general.error.location_services_enable_description" = "Los servicios de localización están deshabilitados actualmente. Soundscape no puede funcionar cuando los servicios de localización están desactivados."; /* */ -"general.error.location_services_enable_instructions.2" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona el botón Atrás (en Ajustes)\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización\n4. Activa Localización"; +"general.error.location_services_enable_instructions.2" = "Activa Localización en la aplicación de ajustes para continuar.\n\n1. Presiona el botón atrás hasta llegar a los ajustes principales\n2. Selecciona Privacidad y seguridad\n3. Selecciona Localización\n4. Activa Localización"; /* */ -"general.error.location_services_enable_instructions.3" = "Activa Localización en la aplicación Ajustes para continuar.\n\n1. Presiona Abrir Ajustes\n2. Presiona el botón atrás (con el título Ajustes)\n3. Selecciona Privacidad y seguridad\n4. Selecciona Localización\n5. Activa Localización"; +"general.error.location_services_enable_instructions.3" = "Activa Localización en la aplicación de ajustes para continuar.\n\n1. Presiona Abrir ajustes\n2. Presiona el botón atrás hasta llegar a los ajustes principales\n3. Selecciona Privacidad y seguridad\n4. Selecciona Localización\n5. Activa Localización"; /* */ @@ -307,7 +307,7 @@ /* */ -"general.error.ble.unauthorized.message" = "Se requiere permiso Bluetooth para conectar tus dispositivos. Abre la aplicación Ajustes para habilitar el Bluetooth. Ten en cuenta que esto puede hacer que se reinicie la aplicación."; +"general.error.ble.unauthorized.message" = "Se requiere permiso Bluetooth para conectar tus dispositivos. Abre la aplicación de ajustes para habilitar el Bluetooth. Ten en cuenta que esto puede hacer que se reinicie la aplicación."; /* */ @@ -335,7 +335,7 @@ /* */ -"device_motion.enable.instructions" = "Activa Seguimiento deportivo en la aplicación Ajustes para continuar.\n\n1. Presiona Abrir Ajustes\n2. Presiona el botón Atrás (con el título Ajustes)\n3. Selecciona Privacidad y seguridad\n4. Selecciona Actividad física\n5. Activa Seguimiento deportivo\n6. Reinicia Soundscape"; +"device_motion.enable.instructions" = "Activa Seguimiento deportivo en la aplicación de ajustes para continuar.\n\n1. Presiona Abrir ajustes\n2. Presiona el botón atrás hasta llegar a los ajustes principales\n3. Selecciona Privacidad y seguridad\n4. Selecciona Actividad física\n5. Activa Seguimiento deportivo\n6. Reinicia Soundscape"; /* */ @@ -347,7 +347,7 @@ /* */ -"device_motion.authorize.instructions" = "1. Abre la aplicación Ajustes a continuación\n2. Activa el seguimiento de Actividad física"; +"device_motion.authorize.instructions" = "1. Abre la aplicación de ajustes a continuación\n2. Activa el seguimiento de Actividad física"; /* */ @@ -367,15 +367,15 @@ /* */ -"settings.clear_cache.markers.alert_message" = "¿Seguro que deseas eliminar todos los marcadores y rutas? ¡Elegir \"Eliminar\" restablecerá la aplicación a su estado original y no se puede deshacer!"; +"settings.clear_cache.markers.alert_message" = "¿Seguro que deseas eliminar todos los marcadores y rutas? ¡Elegir \"Eliminar\" restablecerá la aplicación a un estado de recién instalada y no se podrá deshacer!"; /* */ -"settings.clear_cache.no_service.title" = "No se pueden borrar los datos de los mapas almacenados"; +"settings.clear_cache.no_service.title" = "No se pueden borrar los datos de mapas almacenados"; /* */ -"settings.clear_cache.no_service.message" = "Soundscape actualmente no puede conectarse a internet. Se requiere una conexión a Internet para borrar los datos del mapa almacenados, para que los datos puedan actualizarse."; +"settings.clear_cache.no_service.message" = "Soundscape no puede conectarse ahora a Internet. Se requiere una conexión a Internet al borrar los datos de mapas almacenados para que se puedan actualizar los datos."; /* */ @@ -1155,11 +1155,11 @@ /* */ -"location_detail.add_waypoint.existing.hint" = "Pulsa dos veces para eliminar este marcador de tu ruta"; +"location_detail.add_waypoint.existing.hint" = "Pulsa dos veces para eliminar este marcador de la ruta"; /* */ -"location_detail.add_waypoint.new.hint" = "Pulsa dos veces para agregar este marcador a tu ruta"; +"location_detail.add_waypoint.new.hint" = "Pulsa dos veces para agregar este marcador a la ruta"; /* */ @@ -1591,7 +1591,7 @@ /* */ -"routes.no_routes.hint.2" = "Mientras te encuentres en una ruta con Soundscape, se te informará a la llegada a cada uno de los puntos de ruta, y la señal de audio avanzará automáticamente hasta el siguiente punto de ruta."; +"routes.no_routes.hint.2" = "Mientras te encuentres en una ruta con Soundscape, se te informará a la llegada a cada uno de los puntos de ruta, y la señal de audio avanzará automáticamente al siguiente."; /* */ @@ -1791,7 +1791,7 @@ /* */ -"search.no_results_found_error" = "No parece que haya lugares cerca. Si buscas un lugar específico, puedes intentar buscar por nombre o dirección."; +"search.no_results_found_error" = "No parece que haya lugares cerca. Si estás buscando un lugar específico, puedes intentar buscar por nombre o dirección."; /* */ @@ -1867,7 +1867,7 @@ /* */ -"filter.not_available" = "Algunos filtros de categoría no están disponibles. Todavía puedes examinar lugares cercanos seleccionando \"%@\"."; +"filter.not_available" = "Algunos filtros de categoría no están disponibles. Aún así, para examinar lugares cercanos, selecciona \"%@\""; /* */ @@ -1979,11 +1979,11 @@ /* */ -"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Usa Localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa el botón siguiente para reactivar ahora."; +"sleep.snoozing.message" = "Soundscape se encuentra actualmente pospuesto. Cuando salgas de tu ubicación actual, Soundscape se volverá a reactivar automáticamente. Usa los servicios de localización pero en un modo de bajo consumo para conservar la batería del teléfono. Pulsa el botón siguiente para reactivar ahora."; /* */ -"sleep.sleeping.message" = "Soundscape se encuentra actualmente en el modo de suspensión. Evita que Soundscape use Localización o descargue datos y ahorra batería cuando no se usa Soundscape. Pulsa el botón siguiente para reactivar Soundscape."; +"sleep.sleeping.message" = "Soundscape se encuentra actualmente en el modo de suspensión. Evita que Soundscape use los servicios de localización o descargue datos y ahorra batería cuando no se usa Soundscape. Pulsa el botón siguiente para reactivar Soundscape."; /* */ @@ -2570,7 +2570,7 @@ /* */ -"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para escuchar sobre los lugares en los cuatro cuadrantes que te rodean"; +"ui.action_button.around_me.acc_hint" = "Pulsa dos veces para escuchar sobre los lugares en los cuatro cuadrantes a tu alrededor"; /* */ @@ -2590,7 +2590,7 @@ /* */ -"ui.menu.close" = "Cerrar Menú"; +"ui.menu.close" = "Cerrar menú"; /* */ @@ -2710,15 +2710,15 @@ /* */ -"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo.\n\nPulsa el botón siguiente para conectar un dispositivo."; +"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo.\n\nPulsa el botón siguiente para conectar un dispositivo."; /* */ -"devices.explain_ar.connected.airpods" = "Tus AirPods están listos para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape está siguiendo la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano."; +"devices.explain_ar.connected.airpods" = "Tus AirPods están listos para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tienes que llevar el teléfono en la mano."; /* */ -"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Por favor, asegúrate de que tus auriculares están encendidos y cerca de tu teléfono."; +"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Asegúrate de que los auriculares están activados y que se encuentran cerca del teléfono."; /* */ @@ -2754,11 +2754,11 @@ /* */ -"devices.connect_headset.explanation" = "Selecciona el tipo de auriculares de la lista de auriculares compatibles que se muestra a continuación."; +"devices.connect_headset.explanation" = "Selecciona el tipo de auriculares en la lista siguiente de auriculares compatibles."; /* */ -"devices.connect_headset.audio" = "Antes de conectar los auriculares a Soundscape, asegúrate de que está emparejado con tu teléfono. Si aún no están emparejados, ve a la sección de Bluetooth en la aplicación Ajustes de iOS para emparejar tu dispositivo y luego regresa a Soundscape."; +"devices.connect_headset.audio" = "Antes de conectar los auriculares a Soundscape, asegúrate de que están emparejados con el teléfono. Si aún no lo están, ve a la sección Bluetooth en la aplicación de ajustes de iOS para emparejar el dispositivo y después vuelve a Soundscape."; /* */ @@ -2770,7 +2770,7 @@ /* */ -"devices.connect_headset.completed.airpods" = "¡Enhorabuena! Tus AirPods están listos para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano. Un solo clic en el botón de los auriculares silenciará o desactivará la señal, un doble clic avisará de tu ubicación y un triple clic repetirá el último aviso."; +"devices.connect_headset.completed.airpods" = "¡Enhorabuena! Tus AirPods están listos para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que llevar el teléfono en la mano. Un solo clic en el botón de los auriculares silenciará o reactivará la señal, un doble clic avisará de tu ubicación y un triple clic repetirá el último aviso."; /* */ @@ -2802,7 +2802,7 @@ /* */ -"devices.forget_headset.prompt.explanation" = "Esto desconectará los auriculares de Soundscape. Puedes conectarte a Soundscape de nuevo en el futuro desde aquí."; +"devices.forget_headset.prompt.explanation" = "Esto desconectará los auriculares de Soundscape. Se pueden conectar a Soundscape de nuevo en el futuro desde aquí."; /* */ @@ -3126,11 +3126,11 @@ /* */ -"tutorial.markers.text.AudioBeacon" = "También puedes establecer una señal de audio en tu marcador.\nVamos a probarlo. Esta es una señal de @!marker_name!!.\nEscucha atentamente dónde está y, manteniendo el teléfono en posición horizontal, gira hacia ella."; +"tutorial.markers.text.AudioBeacon" = "También puedes establecer una señal de audio en el marcador.\nVamos a probarlo. Esta es una señal de @!marker_name!!.\nEscucha atentamente dónde está y, manteniendo el teléfono en posición horizontal, gira hacia ella."; /* */ -"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que ya lo entiendes!\nPuedes gestionar tu lista de marcadores seleccionando Marcadores y rutas en la pantalla de inicio.\nY siempre puedes visitar las páginas de Ayuda y tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que lo has entendido!\nPara administrar tu lista de marcadores, selecciona Marcadores y rutas en la pantalla de inicio.\nTambién puedes visitar las páginas de Ayuda y tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3142,7 +3142,7 @@ /* */ -"tutorial.beacon.getting_started.text" = "Cuando estableces una señal en una ubicación, Soundscape reproducirá un sonido procedente de la dirección de esa ubicación. Este tutorial te guiará por el proceso de establecimiento de una señal y cómo usarla.\n\nPresiona el botón \"Iniciar señal de audio\" a continuación para abrir una lista de lugares cercanos. Elije una ubicación en la lista y el tutorial Comenzará."; +"tutorial.beacon.getting_started.text" = "Cuando estableces una señal en una ubicación, Soundscape reproducirá un sonido procedente de la dirección de esa ubicación. Este tutorial te guiará por el proceso de establecimiento de una señal y cómo usarla.\n\nPresiona el botón \"Iniciar señal de audio\" a continuación para abrir una lista de lugares cercanos. Elige una ubicación en la lista y el tutorial Comenzará."; /* */ @@ -3178,7 +3178,7 @@ /* */ -"tutorial.beacons.text.IntroPart2" = "Presiona el botón \"Iniciar señal de audio\" a continuación para abrir una lista de lugares cercanos. Elije una ubicación en la lista y el tutorial comenzará."; +"tutorial.beacons.text.IntroPart2" = "Presiona el botón \"Iniciar señal de audio\" a continuación para abrir una lista de lugares cercanos. Elige una ubicación en la lista y el tutorial comenzará."; /* */ @@ -3186,7 +3186,7 @@ /* */ -"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla mirando hacia arriba y con la parte superior del teléfono apuntando justo delante de ti."; +"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla orientada hacia arriba y con la parte superior del teléfono apuntando justo delante de ti."; /* */ @@ -3250,11 +3250,11 @@ /* */ -"tutorial.beacons.text.AutomaticCallout" = "A medida que avances en tu viaje, Soundscape te informará ocasionalmente de la distancia hasta el lugar marcado por la señal con un aviso como éste."; +"tutorial.beacons.text.AutomaticCallout" = "Conforme avances en tu recorrido, Soundscape irá actualizando ocasionalmente la distancia hasta el lugar marcado por la señal con un aviso como éste."; /* */ -"tutorial.beacons.text.HomeScreen" = "La información de la distancia también aparece en la pantalla principal junto con la dirección de la ubicación de la señal si la tenemos. Soundscape te notificará cuando te acerques a la ubicación de la señal, y cuando te encuentres en ella la señal de audio se silenciará."; +"tutorial.beacons.text.HomeScreen" = "La información de la distancia también aparece en la pantalla principal junto con la dirección de la ubicación de la señal si la tenemos. Soundscape te notificará cuando te acerques a la ubicación de la señal, y cuando te encuentres en ella, la señal de audio se silenciará."; /* */ @@ -3266,7 +3266,7 @@ /* */ -"tutorial.beacons.text.WrapUp" = "¡Parece que ya lo entiendes! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.beacons.text.WrapUp" = "¡Parece que lo has entendido! Si deseas repetir este tutorial, puedes obtener acceso a él en cualquier momento en la pantalla Ayuda y tutoriales. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3294,7 +3294,7 @@ /* */ -"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación Ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación Ajustes de iOS, tienes que ir a Accesibilidad > Lectura y voz > Voces y pulsar en una voz. (En las versiones de iOS anteriores a la 26, \"Lectura y voz\" se llama \"Contenido leído\".) En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: pulsa en \"Ajustes\" desde el menú principal y, a continuación, en \"Ajustes generales\", selecciona \"Voz\"."; +"help.config.voices.content" = "Soundscape puede usar cualquiera de las voces que has descargado en la aplicación de ajustes de iOS, salvo las voces de Siri, que no están disponibles en Soundscape. Te recomendamos que elijas una de las voces de calidad \"Mejorada\", pero tendrás que descargarla primero. Para descargar voces en la aplicación de ajustes de iOS, tienes que ir a Accesibilidad > Lectura y voz > Voces y pulsar en una voz. (En las versiones de iOS anteriores a la 26, \"Lectura y voz\" se llama \"Contenido leído\".) En la aplicación Soundscape, puedes seleccionar la voz que desees de la forma siguiente: ve a \"Ajustes\" desde el menú y, a continuación, en \"Ajustes generales\", selecciona \"Voz\"."; /* */ @@ -3310,7 +3310,7 @@ /* */ -"help.offline.limitations_description" = "Los avisos siguen funcionando si te encuentras en un área por la que has pasado antes y que has sido almacenada en tu historial de mensajes de texto. De forma similar, puedes colocar una señal de audio o crear un marcador en lugares que han sido almacenados en tu historial."; +"help.offline.limitations_description" = "Los avisos continuarán funcionando si te encuentras en una zona por la que has pasado antes y que se ha guardado en tu historial de avisos. De manera similar, puedes colocar una señal de audio o crear un marcador en lugares que se han almacenado en tu historial de avisos."; /* */ @@ -3438,7 +3438,7 @@ /* */ -"first_launch.location.text" = "Soundscape es una aplicación basada en la ubicación. Utilizamos tu ubicación para encontrar y avisar de las cosas de tu entorno."; +"first_launch.location.text" = "Soundscape es una aplicación basada en ubicación. Usamos tu ubicación para encontrar cosas a tu alrededor y avisarte de ellas."; /* */ @@ -3518,7 +3518,7 @@ /* */ -"first_launch.callouts.message" = "Soundscape te ayuda a estar informado de dónde te encuentras y hacia dónde vas avisando de carreteras, cruces y puntos de interés a medida que te acerques a ellos."; +"first_launch.callouts.message" = "Soundscape te ayuda a saber dónde te encuentras y hacia dónde vas avisando de carreteras, cruces y puntos de interés a medida que te acerques a ellos."; /* */ @@ -3530,7 +3530,7 @@ /* */ -"first_launch.callouts.listen.accessibility_hint" = "Pulsa dos veces para escuchar un ejemplo de lo que Soundscape podría decir en tu próximo paseo"; +"first_launch.callouts.listen.accessibility_hint" = "Pulsa dos veces para escuchar un ejemplo de los avisos automáticos de Soundscape"; /* */ @@ -3550,7 +3550,7 @@ /* */ -"first_launch.permissions.message" = "Al navegar con Soundscape, te guiará por una señal de audio. Para ello, Soundscape necesita que habilites los siguientes permisos:"; +"first_launch.permissions.message" = "Al navegar con Soundscape, te guiarás por una señal de audio. Para ello, Soundscape necesita que habilites los siguientes permisos:"; /* */ @@ -3638,11 +3638,11 @@ /* */ -"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia conocido mientras exploras una zona nueva o cuando vas a algún lugar y deseas estar informado de tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar donde te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas."; +"help.text.destination_beacons.when" = "Establecer una señal es útil cuando deseas realizar un seguimiento de un punto de referencia conocido mientras exploras una zona nueva o cuando vas a algún lugar y deseas estar informado sobre tu entorno por el camino. La característica de señal no te ofrece indicaciones paso a paso, sino que te proporciona un sonido audible continuo que te indica la dirección hasta la señal, en relación con el lugar donde te encuentras actualmente. Con la señal de audio, tus capacidades de orientación existentes e incluso tu aplicación de navegación favorita, puedes elegir cómo deseas llegar a las ubicaciones cercanas."; /* */ -"help.text.destination_beacons.how.1" = "Para establecer una señal:
Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerán ahora en la pantalla principal."; +"help.text.destination_beacons.how.1" = "Para establecer una señal:
primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; /* */ @@ -3654,7 +3654,7 @@ /* */ -"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos que se encuentran a tu alrededor conforme te acercas a ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobús e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\", y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; +"help.text.automatic_callouts.what" = "Soundscape puede indicarte los elementos a tu alrededor conforme te acercas a ellos llamándolos por su nombre desde la dirección en la que se encuentran. La aplicación hará esto automáticamente para todo tipo de elementos, como negocios, paradas de autobús e incluso cruces. Puedes configurar de qué avisa la aplicación automáticamente en la sección \"Administrar avisos\" de la pantalla \"Ajustes\", y podrás desactivar todos los avisos cuando desees que la aplicación esté en silencio."; /* */ @@ -3670,11 +3670,11 @@ /* */ -"help.text.automatic_callouts.how.1" = "Activación o desactivación de avisos:
Desactivar los avisos silenciará la aplicación. Los avisos se pueden activar o desactivar yendo a la sección \"Administrar avisos\" de la pantalla \"Ajustes\", y, a continuación, pulsando el botón \"Permitir avisos\". También puedes activar o desactivar los avisos con el comando \"saltar adelante\" (pulsa dos veces y mantén pulsado) si tus auriculares tienen botones de control multimedia. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla principal para evitar que Soundscape haga avisos hasta que lo reactives."; +"help.text.automatic_callouts.how.1" = "Activación o desactivación de avisos:
desactivar los avisos silenciará la aplicación. Para activarlos o desactivarlos, en la sección \"Administrar avisos\" de la pantalla \"Ajustes\", pulsa el botón \"Permitir avisos\". También puedes activar o desactivar avisos con el comando \"saltar adelante\" (pulsa dos veces y mantén pulsado) si los auriculares tienen botones de control multimedia. Alternativamente, puedes usar el botón \"Suspender\" en la esquina superior derecha de la pantalla principal para que Soundscape deje de realizar avisos hasta que lo reactives."; /* */ -"help.text.automatic_callouts.how.2" = "Administración de los avisos que oyes:
Para elegir los tipos de elementos de los que Soundscape avisará automáticamente, ve a la pantalla \"Ajustes\" desde el menú principal. La sección \"Administrar avisos\" de la pantalla \"Ajustes\" contiene una lista de tipos de elementos de los que puede avisar la aplicación. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, pulsa el botón \"Permitir avisos\" en la parte superior de la lista."; +"help.text.automatic_callouts.how.2" = "Administración de los avisos que oyes:
para elegir los tipos de elementos de los que avisará Soundscape automáticamente, ve a la pantalla \"Ajustes\" desde el menú de la pantalla principal. La sección \"Administrar avisos\" de la pantalla \"Ajustes\" incluye una lista de tipos de elementos de los que puede avisar la aplicación. Cada elemento tiene un botón de alternancia que se puede activar o desactivar. Si deseas desactivar todos los avisos, pulsa el botón \"Permitir avisos\" en la parte superior de la lista."; /* */ @@ -3702,7 +3702,7 @@ /* */ -"help.text.around_me.what" = "El botón \"Alrededor de mí\" te informa sobre una cosa en cada uno de los cuatro cuadrantes que se encuentran a tu alrededor (adelante, a la derecha, detrás y a la izquierda). \"Alrededor de mí\" tiene la intención de ayudarte a orientarte en tu entorno."; +"help.text.around_me.what" = "El botón \"Alrededor de mí\" te informa sobre una cosa en cada uno de los cuatro cuadrantes que se encuentran a tu alrededor (delante, a la derecha, detrás y a la izquierda). \"Alrededor de mí\" está pensado para ayudarte a orientarte en tu entorno."; /* */ @@ -3730,11 +3730,11 @@ /* */ -"help.text.remote_control.when" = "Los controles multimedia de auriculares se pueden usar mientras Soundscape se está ejecutando. Esto es así si te encuentras actualmente en Soundscape o mientras Soundscape se encuentra en segundo plano e incluso cuando el dispositivo está bloqueado. Sin embargo, ten en cuenta que los botones de control multimedia no funcionarán con Soundscape si está reproduciendo audio como música, podcasts o vídeos con otra aplicación."; +"help.text.remote_control.when" = "Los controles multimedia de auriculares se pueden usar mientras Soundscape se está ejecutando. Esto es así si te encuentras actualmente en Soundscape o mientras la aplicación se ejecuta en segundo plano e incluso cuando el dispositivo está bloqueado. Sin embargo, ten en cuenta que los botones de control multimedia no funcionarán con Soundscape si estás reproduciendo audio como música, podcasts o vídeos con otra aplicación."; /* */ -"help.text.remote_control.how" = "

Puedes obtener acceso a las siguientes funciones de Soundscape con los botones de control multimedia de los auriculares:


⏯ Reproducir/Pausa: Silenciar los avisos actuales y, si la señal de audio está establecida, activar o desactivar el audio.

⏭ Siguiente: Aviso \"Mi ubicación\".

⏮ Anterior: Repetir el último aviso.

⏩ Saltar adelante: Activar y desactivar los avisos.

⏪ Saltar atrás: Aviso \"Alrededor de mí\".

"; +"help.text.remote_control.how" = "

Puedes obtener acceso a las siguientes funciones de Soundscape con los botones de control multimedia de tus auriculares:


⏯ Reproducir/Pausa: silenciar los avisos actuales y, si la señal de audio está establecida, alternar el audio de la señal.

⏭ Siguiente: aviso \"Mi ubicación\".

⏮ Anterior: repetir último aviso.

⏩ Saltar adelante: activar y desactivar avisos.

⏪ Saltar atrás: aviso \"Alrededor de mí\".

"; /* */ @@ -3750,7 +3750,7 @@ /* */ -"help.text.creating_markers.content.1" = "Puedes crear marcadores de tres formas: buscando el lugar que deseas guardar con la barra de búsqueda, encontrando algún lugar mediante el botón \"Lugares cercanos\" o usando el botón \"Ubicación actual\", todos ellos en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; +"help.text.creating_markers.content.1" = "Puedes crear marcadores de tres maneras: buscando el lugar que deseas guardar con la barra de búsqueda, encontrando algún lugar con el botón \"Lugares cercanos\" o usando el botón \"Ubicación actual\", todos ellos en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; /* */ @@ -3758,7 +3758,7 @@ /* */ -"help.text.customizing_markers.content.1" = "Si deseas cambiar el nombre de un marcador que has creado anteriormente, o agregarle una anotación, selecciona el marcador en la pestaña \"Marcadores\" de la página \"Marcadores y rutas\" y, a continuación, \"Editar marcador\" . Puedes usarlo para asignar a los marcadores sobrenombres útiles o descriptivos, así como para proporcionarles una descripción más larga con el campo de anotación."; +"help.text.customizing_markers.content.1" = "Si deseas cambiar el nombre de un marcador que has creado anteriormente, o agregarle una anotación, selecciona el marcador en la pestaña \"Marcadores\" de la página \"Marcadores y rutas\" y, a continuación, \"Editar marcador\". Puedes usarlo para asignar a los marcadores sobrenombres útiles o descriptivos, así como para proporcionarles una descripción más larga con el campo de anotación."; /* */ @@ -3766,7 +3766,7 @@ /* */ -"help.text.routes.content.what" = "Las rutas son una serie de puntos de referencia. Se te informará a la llegada a cada uno de ellos, y la señal de audio avanzará automáticamente hasta el siguiente."; +"help.text.routes.content.what" = "Las rutas son una serie de puntos de referencia. Se te informará a la llegada a cada uno de ellos, y la señal de audio avanzará automáticamente al siguiente."; /* */ @@ -3786,7 +3786,7 @@ /* */ -"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que la aplicación funcione bien."; +"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods le indican a Soundscape la dirección en la que estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que la aplicación funcione bien."; /* */ @@ -4142,7 +4142,7 @@ /* */ -"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares descubiertos por la aplicación o lugares totalmente nuevos que hayas añadido tú mismo. Puedes guardar tu ubicación actual como marcador seleccionando el botón \"Ubicación actual\" en la pantalla principal y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que deseas guardar con la barra de búsqueda, o encontrando algún lugar mediante el botón \"Lugares cercanos\", ambos en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; +"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares que se pueden encontrar con la aplicación u otros totalmente nuevos que hayas agregado tú mismo. Para guardar tu ubicación actual como marcador, selecciona el botón \"Ubicación actual\" en la pantalla principal y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que deseas guardar con la barra de búsqueda, o encontrando algún lugar mediante el botón \"Lugares cercanos\"; ambos se encuentran en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; /* */ @@ -4154,7 +4154,7 @@ /* */ -"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como señal. Primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se encenderá una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si está disponible, aparecerá ahora en la pantalla principal."; +"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como señal. Primero, ve los detalles de una ubicación mediante la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; /* */ @@ -4186,7 +4186,7 @@ /* */ -"faq.beacon_on_home.answer" = "Soundscape permite establecer señales en direcciones. Para establecer una señal en tu casa, o en cualquier otra dirección, desde la pantalla principal, pulsa en la barra de búsqueda y escribe la dirección. En la pantalla \"Detalles de la ubicación\", pulsa el botón \"Iniciar señal de audio\"."; +"faq.beacon_on_home.answer" = "Soundscape permite establecer señales en direcciones. Para establecer una señal en tu casa, o en cualquier otra dirección, en la pantalla principal, pulsa en la barra de búsqueda y escribe la dirección. En la pantalla \"Detalles de la ubicación\", pulsa el botón \"Iniciar señal de audio\"."; /* */ @@ -4194,7 +4194,7 @@ /* */ -"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, oirás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar cuándo se silencia la señal yendo a \"Señal de audio\" en la pantalla \"Ajustes\" y moviendo el control deslizante \"Distancia de silenciar el audio\" hacia arriba o hacia abajo."; +"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, escucharás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar la distancia a la que la señal se silencia de la siguiente manera: ve a \"Señal de audio\" en la pantalla \"Ajustes\" y mueve el control deslizante \"Distancia de silenciar el audio\" hacia arriba o hacia abajo."; /* */ @@ -4234,7 +4234,7 @@ /* */ -"faq.miss_a_callout.answer" = "Soundscape tiene una lista de tus avisoss recientes para que puedas volver a visitar los avisos que te hayas perdido. Para ello, pulsa en la barra de búsqueda de la pantalla principal. En la parte inferior de esta página, hay una sección de \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar tu teléfono para repetir el último aviso. Para habilitar esta función, ve a la sección \"Administrar avisos\" de la pantalla \"Ajustes\" y activa \"Repetir avisos\"."; +"faq.miss_a_callout.answer" = "Soundscape tiene una lista de avisoss recientes para que puedas volver a visitar avisos que te hayas perdido. Para encontrarla, pulsa en la barra de búsqueda en la pantalla principal. En la parte inferior de esta página, hay una sección \"Avisos recientes\" donde aparecerá el aviso que te perdiste. También puedes agitar tu teléfono para repetir el último aviso. Para habilitar esta función, ve a la sección \"Administrar avisos\" en la pantalla \"Ajustes\" y activa \"Repetir avisos\"."; /* */ @@ -4254,7 +4254,7 @@ /* */ -"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal, y cada opción tiene sus ventajas y desventajas. El único requisito es usar auriculares estéreos para beneficiarte de los avisos acústicos espaciales 3D de Soundscape."; +"faq.supported_headsets.answer" = "Los auriculares que uses con Soundscape es una cuestión de preferencia personal, y cada opción tiene sus ventajas y desventajas. El único requisito es usar auriculares estéreos para beneficiarte de los avisos de audio espacial 3D de Soundscape."; /* */ @@ -4262,7 +4262,7 @@ /* */ -"faq.battery_impact.answer" = "La duración de la batería varía en gran medida en función del modelo y la antigüedad de tu iPhone. El mayor consumo de la batería se produce al tener la pantalla encendida, por lo que para maximizar su duración, debes mantener la pantalla bloqueada siempre que sea posible. Para ayudar a minimizar el impacto en la batería de iPhone, Soundscape tiene un modo de suspensión y un modo de aplazamiento. Para reducir aún más el uso de la batería, cuando no uses Soundscape, debes forzar cerrar la aplicación con el Selector de app de iPhone."; +"faq.battery_impact.answer" = "La duración de la batería varía en gran medida en función del modelo y la antigüedad de tu iPhone. El mayor consumo de la batería se produce al tener la pantalla encendida, por lo que para maximizar su duración, debes mantener la pantalla bloqueada siempre que sea posible. Para ayudar a minimizar el impacto en la batería de iPhone, Soundscape tiene un modo de suspensión y un modo de aplazamiento. Para reducir aún más el uso de la batería, cuando no uses Soundscape, debes forzar cerrar la aplicación con el Selector de aplicación de iPhone."; /* */ @@ -4270,7 +4270,7 @@ /* */ -"faq.sleep_mode_battery.answer" = "Para poner Soundscape en el modo de suspensión, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando lo selecciones, Soundscape dejará de usar la localización y los datos móviles hasta que lo reactives."; +"faq.sleep_mode_battery.answer" = "Para poner Soundscape en el modo de suspensión, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Al seleccionarlo, Soundscape dejará de usar Localización y los datos móviles hasta que lo reactives."; /* */ @@ -4278,7 +4278,7 @@ /* */ -"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape esté en el modo de suspensión, selecciona el botón \"Reactivar cuando salga\" y Soundscape entrará en un estado de bajo consumo hasta que te vayas de la ubicación actual."; +"faq.snooze_mode_battery.answer" = "Para poner Soundscape en el modo de aplazamiento, selecciona el botón \"Suspender\" en la esquina superior derecha de la pantalla de inicio. Cuando Soundscape se encuentre en el modo de suspensión, selecciona el botón \"Reactivar cuando salga\" y Soundscape entrará en un estado de bajo consumo de la batería hasta que te vayas de la ubicación actual."; /* */ @@ -4294,7 +4294,7 @@ /* */ -"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar dónde te encuentras. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupas el consumo de la batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa servicios de localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; +"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar dónde te encuentras. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupa el consumo de batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa los servicios de localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; /* */ @@ -4302,7 +4302,7 @@ /* */ -"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado la aplicación para que consuma solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, guardando puntos mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que regreses a un sitio donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a una red Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para poner Soundscape en suspensión, o bien cierra totalmente la aplicación."; +"faq.mobile_data_use.answer" = "La cantidad de datos móviles que use dependerá de cómo utilices Soundscape. Hemos diseñado la aplicación para que consuma solo una pequeña cantidad de datos cuando estés fuera; por ejemplo, guardando puntos mientras caminas, a fin de que no tengas que volver a descargarlos cada vez que regreses a un sitio donde ya hayas estado. Para usar menos datos móviles, conéctate siempre que puedas a Wi-Fi, en especial cuando descargues la aplicación. Cuando no uses Soundscape, pulsa el botón \"Suspender\" para poner Soundscape en suspensión, o bien cierra totalmente la aplicación."; /* */ @@ -4318,7 +4318,7 @@ /* */ -"faq.use_with_wayfinding_apps.answer" = "Soundscape se ha diseñado para ayudar a completar la información de tu entorno que es posible que no conozcas de otra manera. Aunque no se ha diseñado como una aplicación de navegación paso a paso, se puede usar junto con esas aplicaciones para proporcionar información complementaria. Para usar Soundscape con estas aplicaciones, inicia tu aplicación de navegación primero. A continuación, pasa a Soundscape y establece una señal en el mismo destino que la aplicación de navegación. En este punto, ambas aplicaciones se estarán ejecutando y oirás indicaciones de ruta a pie de tu aplicación de navegación, a la vez que recibirás de Soundscape actualizaciones sobre puntos de interés, cruces y la distancia a la que te encuentras de tu destino."; +"faq.use_with_wayfinding_apps.answer" = "Soundscape se ha diseñado para ayudar a completar la información de tu entorno que es posible que no conozcas de otra manera. Aunque no se ha diseñado como una aplicación de navegación paso a paso, se puede usar junto con esas aplicaciones para proporcionar información complementaria. Para usar Soundscape con estas aplicaciones, inicia tu aplicación de navegación primero. A continuación, pasa a Soundscape y establece una señal en el mismo destino que la aplicación de navegación. En este punto, ambas aplicaciones se estarán ejecutando y oirás indicaciones de ruta a pie de tu aplicación de navegación, a la vez que recibirás de Soundscape actualizaciones sobre puntos de interés, cruces y la distancia a tu destino."; /* */ @@ -4326,7 +4326,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias formas de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: Pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente al aproximarse al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: Cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar avisos\".\n3. Detener la señal: Hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras recibir actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; +"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias maneras de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente al aproximarse al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar avisos\".\n3. Detener la señal: hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras obtener actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; /* */ @@ -4334,7 +4334,7 @@ /* */ -"faq.holding_phone_flat.answer" = "¡No, no! Mientras caminas puedes guardar el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que estás caminando para averiguar qué avisos emitirá a tu izquierda y a tu derecha. Cuando dejas de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; +"faq.holding_phone_flat.answer" = "¡No, no! Cuando camines, puedes meter el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que caminas para averiguar qué avisos emitirá a tu izquierda y a tu derecha. Cuando dejes de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; /* */ @@ -4342,7 +4342,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape , así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Voz\" para ajustar la velocidad de habla y la configuración de voz . Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en la aplicación Ajustes de iOS en Ajustes > Accesibilidad > Lectura y voz (Contenido leído) > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar todas las distancias en pies o metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre dos opciones: Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados al pasar o acercarte a ellos, o también puedes usar el botón \"Marcadores cercanos\" en la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Estos marcadores seguirán siendo personales para ti y no estarán disponibles para nadie más.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver están activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver navegando a la aplicación Ajustes de iOS y yendo a Accesibilidad > VoiceOver > Verbosidad, y activando la configuración Leer indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, los avisos automáticos pueden resultar difíciles de oír si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los avisos de VoiceOver o a través del rotor de VoiceOver.\n3. Desbloqueo con Touch ID o Face ID: configurar el teléfono para que se desbloquee con Touch ID o Face ID hará que desbloquear el teléfono sea rápido y fácil y, a su vez, te permitirá acceder a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" lo más rápido posible cuando estés en movimiento. Configura el desbloqueo con Touch ID o Face ID en la aplicación Ajustes de iOS ."; +"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape, así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Voz\" para ajustar la velocidad de habla y la voz. Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en los ajustes de iOS en Ajustes > Accesibilidad > Lectura y voz (Contenido leído) > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar las distancias en pies o en metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados cuando pases a pie o te acerques a ellos. También puedes usar el botón \"Marcadores cercanos\" de la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Los marcadores seguirán siendo personales y nadie más podrá verlos.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver estén activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver de la siguiente manera: ve a los ajustes de iOS, luego a Accesibilidad > VoiceOver > Verbosidad y, por último, activa las indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, puede ser difícil oír los avisos automáticos si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los ajustes de VoiceOver o a través del rotor de VoiceOver.\n3. Touch ID o Face ID para desbloquear: si configuras tu teléfono para que se desbloquee con Touch ID o Face ID, será más fácil y rápido desbloquearlo, y podrás obtener acceso más deprisa a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" cuando camines. Configura el desbloqueo con Touch ID o Face ID en la aplicación de ajustes de iOS."; /* */ @@ -4354,11 +4354,11 @@ /* */ -"faq.tip.beacon_quiet" = "Si te metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia dónde estás mirando. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; +"faq.tip.beacon_quiet" = "Si metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia dónde estás mirando. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; /* */ -"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla de inicio, pulsa en la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, aparecerá una pantalla de \"Detalles de la ubicación\" con la opción para \"Iniciar señal de audio\" en la dirección. De este modo, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no estén en Open Street Map."; +"faq.tip.setting_beacon_on_address" = "Puedes establecer una señal en cualquier dirección. En la pantalla principal, pulsa en la barra de búsqueda y escribe la dirección. Tras seleccionar la dirección en los resultados de la búsqueda, aparecerá una pantalla \"Detalles de la ubicación\" con la opción para \"Iniciar señal de audio\" en la dirección. De esta manera, puedes establecer una señal en negocios, lugares, puntos de interés y residencias que no se incluyan en Open Street Map."; /* */ @@ -4366,19 +4366,19 @@ /* */ -"faq.tip.turning_beacon_off" = "Puedes activar y desactivar el sonido rítmico de la señal con el botón de silencio en la pantalla principal. Si la señal está silenciada, seguirás recibiendo actualizaciones sobre la distancia a tu destino cada 50 metros aproximadamente."; +"faq.tip.turning_beacon_off" = "Puedes activar y desactivar el sonido rítmico de la señal con el botón de silencio en la pantalla principal. Si la señal está silenciada, seguirás recibiendo actualizaciones de la distancia a tu destino cada 50 metros aproximadamente."; /* */ -"faq.tip.turning_off_auto_callouts" = "Si quieres seguir interactuando con Soundscape pero no quieres oír los avisos automáticos, puedes desactivarlos yendo a la sección\"Administrar avisos\" de la pantalla \"Ajustes\" del menú y desactivando \"Permitir avisos\". O bien, si no vas a usar Soundscape, puedes ponerlo en el modo de suspensión o de aplazamiento con el botón \"Suspender\" en la pantalla principal."; +"faq.tip.turning_off_auto_callouts" = "Si quieres seguir interactuando con Soundscape pero no deseas oír los avisos automáticos, para desactivar avisos, ve a la sección\"Administrar avisos\" de la pantalla \"Ajustes\" en el menú. O bien, si no vas a usar Soundscape, puedes ponerlo en el modo de suspensión o de aplazamiento con el botón \"Suspender\" en la pantalla principal."; /* */ -"faq.tip.hold_phone_flat" = "Soundscape funciona mejor cuando te mantienes el teléfono en posición horizontal con la pantalla hacia arriba y la parte superior del teléfono apuntando al lado contrario de ti."; +"faq.tip.hold_phone_flat" = "Soundscape funciona mejor cuando mantienes el teléfono en posición horizontal con la pantalla hacia arriba y la parte superior del teléfono apuntando al lado contrario de ti."; /* */ -"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas regularmente, establece tus paradas de recogida y salida como marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y obtendrás actualizaciones periódicas sobre lo cerca que estás a tu parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás recibiendo actualizaciones de la distancia por el camino."; +"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas a menudo, establece tus paradas de recogida y salida como marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y recibirás actualizaciones periódicas sobre lo cerca que estás a la parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás obteniendo actualizaciones de la distancia por el camino."; /* */ @@ -4428,24 +4428,24 @@ "menu.donate" = "Donar"; "donation.title" = "Donar a Soundscape Community"; "donation.link" = "Ir a la página de recaudación de fondos"; -"devices.connect_headset.completed.boseframes" = "¡Enhorabuena! Tus Bose Frames están listas para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano."; +"devices.connect_headset.completed.boseframes" = "¡Enhorabuena! Tus Bose Frames están listas para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que llevar el teléfono en la mano."; "devices.callouts.check_audio.bose_frames" = "Bose Frames conectadas."; "devices.callouts.check_audio.bose_frames.disconnected" = "Soundscape está buscando tus Bose Frames. Asegúrate de que están conectadas al teléfono."; -"devices.explain_ar.connected.boseframes" = "Tus Bose Frames están listas para usar, ¡así que puedes guardar tu teléfono en el bolsillo y ponerte en marcha! Soundscape está siguiendo la orientación de tu cabeza para que no tengas que sostener el teléfono en la mano."; +"devices.explain_ar.connected.boseframes" = "Tus Bose Frames están listas para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tienes que llevar el teléfono en la mano."; "help.using_headsets.bose_frames.title" = "Uso de Bose Frames"; "help.using_headsets.bose_frames.when" = "Puedes usar Bose Frames en cualquier momento con Soundscape. El uso de Bose Frames te proporciona un audio de alta calidad que no dificulta la audición ambiental y te permite tener una experiencia mayor de manos libres."; "help.using_headsets.bose_frames.how.3" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén habilitados en la configuración de Soundscape, podrás usarlos en las Bose Frames para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; "help.using_headsets.bose_frames.how.1" = "Conexión de un dispositivo:
ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; -"help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
Si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación de Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
Nos encantaría escuchar tus comentarios sobre la compatibilidad con las Bose Frames. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; -"help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión hacia dónde estás mirando. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. Puedes repetir esta calibración, en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; -"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames indican a Soundscape la dirección en la que estás mirando. Esto ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que la aplicación funcione bien."; +"help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
Nos encantaría escuchar tus comentarios sobre la compatibilidad con las Bose Frames. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; +"help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión hacia dónde estás mirando. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. Puedes repetir esta calibración en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; +"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames le indican a Soundscape la dirección en la que estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que la aplicación funcione bien."; "whats_new.1_3_0.0.title" = "Compatibilidad con Bose Frames"; "whats_new.1_3_0.0.description" = "Ahora Soundscape admite seguimiento de cabeza con las versiones Alto o Rondo de Bose Frames. Cuando se conecten, tus Bose Frames indicarán a Soundscape hacia dónde estás mirando, lo que ayudará a Soundscape a mejorar tu experiencia de audio. Para conectar tus Bose Frames a Soundscape, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape."; -"whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón \"Enviar comentarios\" del menú principal."; +"whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón \"Enviar comentarios\" del menú."; "whats_new.1_3_0.1.title" = "Prueba en Texas"; "beacon.action.navilens" = "Iniciar NaviLens"; "troubleshooting.tile_server_url" = "URL del servidor de teselas"; -"troubleshooting.tile_server_url.explanation" = "Este es el servidor desde el que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; +"troubleshooting.tile_server_url.explanation" = "Este es el servidor del que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso"; "route_detail.reverse.error.title" = "Falla de ruta de regreso"; "route_detail.action.start_reversed_route.disabled.hint" = "Añadir puntos antes de iniciar la ruta de regreso"; @@ -4458,6 +4458,6 @@ "beacon.suggest_navilens" = "Usa el botón NaviLens para llegar a tu destino."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; "filter.navilens" = "Códigos NaviLens"; -"troubleshooting.user_data" = "Datos del usuario"; +"troubleshooting.user_data" = "Datos de usuario"; "troubleshooting.user_data.button" = "Eliminar todos los marcadores y rutas"; -"troubleshooting.user_data.explanation" = "Borra todos los datos del mapa, incluidos los marcadores y rutas guardados. Esta acción no se puede deshacer."; +"troubleshooting.user_data.explanation" = "Borra todos los datos de mapas, incluidos los marcadores y rutas guardados. Esta acción no se puede deshacer."; diff --git a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings index 5ae8edaf4..c170e488d 100644 --- a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings @@ -2478,3 +2478,8 @@ + + + + + From 2d1feec434c2a8482d051d0dbd39bd7f0cb6d1ea Mon Sep 17 00:00:00 2001 From: "John Joseph A. Gatchalian" Date: Sat, 7 Mar 2026 16:38:37 +0100 Subject: [PATCH 74/76] Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Dutch) Currently translated at 84.5% (991 of 1172 strings) Translated using Weblate (Finnish) Currently translated at 80.2% (940 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.5% (991 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.6% (992 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.7% (993 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 99.9% (1171 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 99.9% (1171 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.4% (990 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (Persian) Currently translated at 84.6% (992 of 1172 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (1172 of 1172 strings) Translated using Weblate (English) Currently translated at 100.0% (1172 of 1172 strings) Co-authored-by: John Joseph A. Gatchalian Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/en_GB/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/es/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/fa/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/fi/ Translate-URL: https://hosted.weblate.org/projects/soundscape/ios-app/nl/ Translation: Soundscape/iOS app --- .../en-GB.lproj/Localizable.strings | 18 +- .../en-US.lproj/Localizable.strings | 18 +- .../es-ES.lproj/Localizable.strings | 174 +++++++++--------- .../fa-IR.lproj/Localizable.strings | 5 + .../fi-FI.lproj/Localizable.strings | 2 +- .../nl-NL.lproj/Localizable.strings | 2 +- 6 files changed, 112 insertions(+), 107 deletions(-) diff --git a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings index 2b4d24d39..16e202fbc 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-GB.lproj/Localizable.strings @@ -279,7 +279,7 @@ /* */ -"general.error.heading" = "Soundscape is not sure which direction you are facing. Please hold your phone flat or begin walking and try again."; +"general.error.heading" = "Soundscape is not sure which direction you are facing. Please hold your phone flat or begin walking and try again"; /* */ @@ -1784,7 +1784,7 @@ /* */ -"searching.no_results_found_title" = "Oops! No results found"; +"searching.no_results_found_title" = "Oops! No results found."; /* */ @@ -1971,7 +1971,7 @@ /* */ -"callouts.nothing_to_call_out_now" = "There is nothing to call out right now."; +"callouts.nothing_to_call_out_now" = "There is nothing to call out right now"; /* */ @@ -2714,7 +2714,7 @@ /* */ -"location_callout_cell.nearest_road" = "Nearest road, %@"; +"location_callout_cell.nearest_road" = "Nearest road, %@."; /* */ @@ -3765,7 +3765,7 @@ /* */ -"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; +"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons, so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; /* */ @@ -4177,7 +4177,7 @@ /* */ -"faq.when_to_use_soundscape.answer" = "Soundscape has features and benefits that span a variety of scenarios and time scales. Furthermore, Soundscape’s value to you may evolve over time so how you use it today may differ from how you will use it in three months. People often think about apps in terms of \"what problem is this app good at solving?\" Soundscape certainly can be used on a case by case basis when you have a specific information need – such as keeping track of a destination as you make your way there, helping to orient yourself when you emerge from a metro station, getting your bearings when exiting a car, or finding the street names for, or distance to, the next intersection. However, the philosophy behind Soundscape is one of \"lighting up your world with sound\", designed to be used anytime you are out and about to provide ambient awareness of your surroundings, such as keeping you aware of the names of the streets you are on, the direction you are heading, and the names of businesses you are passing. In this use mode, our users have referred to Soundscape as a \"nice companion app\", which supports \"serendipity\", to \"fill in the gaps in your mental map\" and provide more \"confidence when walking\". Here are some other examples of how our users are incorporating Soundscape into their life:\n\n\"Soundscape helped me get back on track after I got off the bus and headed off in the wrong direction.\"\n\n\"Even in the town where I have lived for 3 years, I have built an improved picture of what is around me [with Soundscape].\"\n\n\"The 3D sound enhances my experience of a walk, as I feel more connected to my environment…I am more likely to try a new route now that I have the app to use.\"\n\n\"I miss the serendipity of walking around and noticing things. Having Soundscape is nice – it requires no effort to hear about things around me. The relational information is useful and is a great app for situational awareness and exploring commercial corridors.\"\n\n\"[I used Soundscape] to locate a pub in the middle of York. [I] used a range of its options to first locate and then actually find it. It took me to within 3 metres of the door – brilliant!\""; +"faq.when_to_use_soundscape.answer" = "Soundscape has features and benefits that span a variety of scenarios and time scales. Furthermore, Soundscape’s value to you may evolve over time, so how you use it today may differ from how you will use it in three months. People often think about apps in terms of \"what problem is this app good at solving?\" Soundscape certainly can be used on a case by case basis when you have a specific information need – such as keeping track of a destination as you make your way there, helping to orient yourself when you emerge from a metro station, getting your bearings when exiting a car, or finding the street names for, or distance to, the next intersection. However, the philosophy behind Soundscape is one of \"lighting up your world with sound\", designed to be used anytime you are out and about to provide ambient awareness of your surroundings, such as keeping you aware of the names of the streets you are on, the direction you are heading, and the names of businesses you are passing. In this use mode, our users have referred to Soundscape as a \"nice companion app\", which supports \"serendipity\", to \"fill in the gaps in your mental map\" and provide more \"confidence when walking\". Here are some other examples of how our users are incorporating Soundscape into their life:\n\n\"Soundscape helped me get back on track after I got off the bus and headed off in the wrong direction.\"\n\n\"Even in the town where I have lived for 3 years, I have built an improved picture of what is around me [with Soundscape].\"\n\n\"The 3D sound enhances my experience of a walk, as I feel more connected to my environment…I am more likely to try a new route now that I have the app to use.\"\n\n\"I miss the serendipity of walking around and noticing things. Having Soundscape is nice – it requires no effort to hear about things around me. The relational information is useful and is a great app for situational awareness and exploring commercial corridors.\"\n\n\"[I used Soundscape] to locate a pub in the middle of York. [I] used a range of its options to first locate and then actually find it. It took me to within 3 metres of the door – brilliant!\""; /* */ @@ -4421,7 +4421,7 @@ /* */ -"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; +"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \"Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; /* */ @@ -4477,8 +4477,8 @@ "help.using_headsets.bose_frames.title" = "Using Bose Frames"; "help.using_headsets.bose_frames.how.2" = "Calibrating your Headphones:
Your Bose Frames will need to be calibrated to accurately know which way you are facing. Each time you connect them to Soundscape, you will be informed that calibration is needed by an audio chime. To calibrate your Bose Frames, follow the instructions provided on the screen. When the chime stops playing, Your Bose Frames are calibrated, and Soundscape will now track the direction of your head so you do not need to hold the phone in your hand. You can repeat this calibration at any time, even if the chime isn't playing, if you think the accuracy of your spatial audio is poor."; "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; -"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; -"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; +"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; +"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; "whats_new.1_3_0.0.title" = "Bose Frames Support"; "whats_new.1_3_0.0.description" = "Soundscape now supports head tracking with the Alto or Rondo versions of the Bose Frames. Once they're connected, your Bose Frames will tell Soundscape where you are facing, helping Soundscape to improve your audio experience. To connect your Bose Frames to Soundscape, go to the \"Head Tracking Headphones\" item in the Soundscape menu."; "whats_new.1_3_0.1.title" = "Testing in Texas"; diff --git a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings index 303d7a706..a2384bcb3 100644 --- a/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/en-US.lproj/Localizable.strings @@ -221,7 +221,7 @@ "general.error.location_services_find_location_error" = "We are having trouble finding your current location."; /* Error message when Soundscape does not know the user's heading */ -"general.error.heading" = "Soundscape is not sure which direction you are facing. Please hold your phone flat or begin walking and try again."; +"general.error.heading" = "Soundscape is not sure which direction you are facing. Please hold your phone flat or begin walking and try again"; /* Error message Soundscape is having trouble determining current location. Try again later */ "general.error.location_services_find_location_error.try_again" = "We are having trouble finding your current location. Try again later."; @@ -1517,7 +1517,7 @@ "search.no_results_found_with_hint" = "No results found. Try editing your search term."; /* Search results, No results found. */ -"searching.no_results_found_title" = "Oops! No results found"; +"searching.no_results_found_title" = "Oops! No results found."; /* Search results, No results found. */ "searching.no_results_found_message" = "If you're looking for a specific place, you can try searching by name or address."; @@ -1666,7 +1666,7 @@ "callouts.marked_points" = "Marked Points"; /* Callouts notification, There is nothing to call out right now */ -"callouts.nothing_to_call_out_now" = "There is nothing to call out right now."; +"callouts.nothing_to_call_out_now" = "There is nothing to call out right now"; /* Callouts Title, Nearby Markers */ "callouts.nearby_markers" = "Nearby Markers"; @@ -2271,7 +2271,7 @@ "location_callout_cell.marked_location" = "Marked Location"; /* Location Callout Cell for the nearest road, %@ road name, "Nearest road, <27th Avenue West>" {NumberedPlaceholder="%@"} */ -"location_callout_cell.nearest_road" = "Nearest road, %@"; +"location_callout_cell.nearest_road" = "Nearest road, %@."; /* Location Callout Cell, Nearest road and beacon set on, %1$@ road name %2$@ location, "Nearest road, <27th Avenue West>. Beacon was set on ." {NumberedPlaceholder="%1$@", "%2$@"} */ "location_callout_cell.nearest_road.beacon_set_on" = "Nearest road, %1$@. Beacon was set on %2$@."; @@ -3134,7 +3134,7 @@ "help.text.ahead_of_me.how" = "As with all four of the buttons at the bottom of the home screen, hold your phone with the screen flat (facing toward the sky) and the top of the phone pointing in the direction you are facing before you press the \"Ahead of Me\" button. This acts like a compass telling the app which direction you are facing. Simply, tap the \"Ahead of Me\" button and you will hear several points of interest all roughly ahead of you."; /* Notification, Information about what headphone media controls do in Soundscape. Keep HTML tags. {NumberedPlaceholder="Soundscape", "
"} */ -"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; +"help.text.remote_control.what" = "You can access certain features in Soundscape with the media control buttons on your headphones. This functionality works with any wired or Bluetooth headphones that have media control buttons like Play, Pause, Next, Previous and others. Different headphones may include different buttons, so please refer to the list of actions below to determine which ones are available to you.
Note that this feature only works with headphones that support Apple's media controls (such as play and pause)."; /* Notification, Information about when to use media controls on headphones. {NumberedPlaceholder="Soundscape"} */ "help.text.remote_control.when" = "Headphone media controls can be used while Soundscape is running. This is true whether you are currently in Soundscape or while the app runs in the background and even while your device is locked. Note however that headphone media control buttons will not work with Soundscape if you are playing audio like music, podcasts or videos with another app."; @@ -3194,7 +3194,7 @@ "help.using_headsets.airpods.how.2" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your AirPods to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; /* Help content describing how Bose Frames work with Soundscape and which versions are supported {NumberedPlaceholder="Soundscape","Bose Frames"} */ -"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with dynamic head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; +"help.using_headsets.bose_frames.what" = "Soundscape supports spatial audio with head tracking when using the Alto or Rondo versions of the Bose Frames. Once they're connected, sensors in the Bose Frames tell Soundscape the direction your head is facing. This helps Soundscape to improve your audio experience, making it more natural as you move around in the world. When you use Soundscape with Bose Frames connected, you do not need to hold your phone for the app to work correctly."; /* Information on when users can use Bose Frames headphones with Soundscape, {NumberedPlaceholder="Soundscape","Bose Frames"} */ "help.using_headsets.bose_frames.when" = "You can use Bose Frames with Soundscape anytime you would normally use Soundscape. Using Bose Frames provides you with high quality audio that does not occlude environmental audio and allows you to have a more hands-free experience."; @@ -3209,7 +3209,7 @@ "help.using_headsets.bose_frames.how.3" = "Using the Media Controls on your Headphones:
When media controls are enabled in the Soundscape settings, you can use the media controls on your Bose Frames to mute or unmute the beacon, to call out your location or to repeat the last callout. For more information, see the \"Using Media Controls\" help section."; /* Trouble shooting information for Bose Frames */ -"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; +"help.using_headsets.bose_frames.how.4" = "Troubleshooting your headphones:
If you are having trouble connecting your Bose Frames to Soundscape, ensure they are one of the supported models - the Altos or Rondos. If they are one of these models, then ensure that the Frames are appearing in the Bose Connect app. If they are showing and you are still having trouble with the connection, try unpairing and re-pairing the headphones via your phone's Bluetooth menu.
We would love to hear your feedback about the Bose Frames support. You can contact us by choosing the \"Send Feedback\" option in the menu."; //------------------------------------------------------------------------------ // MARK: - OSM Tags @@ -3546,7 +3546,7 @@ "faq.when_to_use_soundscape.question" = "When should I use Soundscape?"; /* Soundscape - The app that explores the use of innovative audio-based technology to enable people, particularly those with blindness or low vision, to build a richer awareness of their surroundings, thus becoming more confident and empowered to get around by using 3D audio cues to enrich ambient awareness and provide a new way to relate to the environment. ’Lighting up your way with sound’ is a marketing tagline for the app. Intersection - A junction where two or more roads meet or cross. 3D sound is where the audio through your headphones sounds as though it is coming from a given direction, as if it was actually coming from a speaker. Quotes written as \" {NumberedPlaceholder="Soundscape"} */ -"faq.when_to_use_soundscape.answer" = "Soundscape has features and benefits that span a variety of scenarios and time scales. Furthermore, Soundscape’s value to you may evolve over time so how you use it today may differ from how you will use it in three months. People often think about apps in terms of \"what problem is this app good at solving?\" Soundscape certainly can be used on a case by case basis when you have a specific information need – such as keeping track of a destination as you make your way there, helping to orient yourself when you emerge from a metro station, getting your bearings when exiting a car, or finding the street names for, or distance to, the next intersection. However, the philosophy behind Soundscape is one of \"lighting up your world with sound\", designed to be used anytime you are out and about to provide ambient awareness of your surroundings, such as keeping you aware of the names of the streets you are on, the direction you are heading, and the names of businesses you are passing. In this use mode, our users have referred to Soundscape as a \"nice companion app\", which supports \"serendipity\", to \"fill in the gaps in your mental map\" and provide more \"confidence when walking\". Here are some other examples of how our users are incorporating Soundscape into their life:\n\n\"Soundscape helped me get back on track after I got off the bus and headed off in the wrong direction.\"\n\n\"Even in the town where I have lived for 3 years, I have built an improved picture of what is around me [with Soundscape].\"\n\n\"The 3D sound enhances my experience of a walk, as I feel more connected to my environment…I am more likely to try a new route now that I have the app to use.\"\n\n\"I miss the serendipity of walking around and noticing things. Having Soundscape is nice – it requires no effort to hear about things around me. The relational information is useful and is a great app for situational awareness and exploring commercial corridors.\"\n\n\"[I used Soundscape] to locate a pub in the middle of York. [I] used a range of its options to first locate and then actually find it. It took me to within 3 meters of the door – brilliant!\""; +"faq.when_to_use_soundscape.answer" = "Soundscape has features and benefits that span a variety of scenarios and time scales. Furthermore, Soundscape’s value to you may evolve over time, so how you use it today may differ from how you will use it in three months. People often think about apps in terms of \"what problem is this app good at solving?\" Soundscape certainly can be used on a case by case basis when you have a specific information need – such as keeping track of a destination as you make your way there, helping to orient yourself when you emerge from a metro station, getting your bearings when exiting a car, or finding the street names for, or distance to, the next intersection. However, the philosophy behind Soundscape is one of \"lighting up your world with sound\", designed to be used anytime you are out and about to provide ambient awareness of your surroundings, such as keeping you aware of the names of the streets you are on, the direction you are heading, and the names of businesses you are passing. In this use mode, our users have referred to Soundscape as a \"nice companion app\", which supports \"serendipity\", to \"fill in the gaps in your mental map\" and provide more \"confidence when walking\". Here are some other examples of how our users are incorporating Soundscape into their life:\n\n\"Soundscape helped me get back on track after I got off the bus and headed off in the wrong direction.\"\n\n\"Even in the town where I have lived for 3 years, I have built an improved picture of what is around me [with Soundscape].\"\n\n\"The 3D sound enhances my experience of a walk, as I feel more connected to my environment…I am more likely to try a new route now that I have the app to use.\"\n\n\"I miss the serendipity of walking around and noticing things. Having Soundscape is nice – it requires no effort to hear about things around me. The relational information is useful and is a great app for situational awareness and exploring commercial corridors.\"\n\n\"[I used Soundscape] to locate a pub in the middle of York. [I] used a range of its options to first locate and then actually find it. It took me to within 3 meters of the door – brilliant!\""; /* Marker - A location that has been marked as important by the user or application. This can be an address, a business or a custom place such as an entrance, a bus stop or a bench. */ "faq.markers_function.question" = "What are Markers and how do I get the most out of them?"; @@ -3735,7 +3735,7 @@ "faq.tip.hold_phone_flat" = "Soundscape works best when you hold the phone flat with the screen facing the sky and the top of the phone pointing away from you."; /* Marker - A location that has been marked as important by the user or application. This can be an address, a business or a custom place such as an entrance, a bus stop or a bench. The 'beacon' is an audio signal that helps fix the position of a location - the audio signal is played from the direction of a location which helps navigating towards that direction. 'Manage Markers' is the name of one of the options in the Soundscape menu. Quotes written as \" */ -"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \" Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; +"faq.tip.create_marker_at_bus_stop" = "If there is a bus route you take regularly, set your pickup and exit stops as markers. This way they will be saved so you can find them again easily, just go to \"Markers & Routes\" from the home screen and find them on the \"Markers\" page. You can set a beacon on them and you will get periodic updates on how close you are to your exit stop. Note: you can turn off the rhythmic sound and you will still get distance updates along the way."; /* Callout - a short audio clip with speech and/or sound effect serving as a piece of information. For example, the application can output an audio callout to notify the user that the battery is low. */ "faq.tip.two_finger_double_tap" = "Tapping the screen twice with two fingers will silence any active callouts."; diff --git a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings index 3bd3a2266..1e2e6f756 100644 --- a/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/es-ES.lproj/Localizable.strings @@ -115,7 +115,7 @@ /* */ -"general.alert.confirmation_title" = "¿Estás seguro?"; +"general.alert.confirmation_title" = "¿Seguro que quieres hacerlo?"; /* */ @@ -131,7 +131,7 @@ /* */ -"general.loading.almost_ready" = "Ya casi está…"; +"general.loading.almost_ready" = "Casi está listo…"; /* */ @@ -159,11 +159,11 @@ /* */ -"general.alert.offline_search.title" = "Búsqueda no disponible"; +"general.alert.offline_search.title" = "La búsqueda no está disponible"; /* */ -"general.alert.offline_search.message" = "Cuando Soundscape funciona sin conexión, la búsqueda está deshabilitada. Descartar para volver a la pantalla anterior"; +"general.alert.offline_search.message" = "Cuando Soundscape está funcionando sin conexión, la búsqueda está deshabilitada. Descarta para regresar a la pantalla anterior"; /* */ @@ -231,11 +231,11 @@ /* */ -"general.error.location_services" = "Activar Localización para usar Soundscape"; +"general.error.location_services" = "Activa Localización para usar Soundscape"; /* */ -"general.error.precise_location" = "Activar Ubicación exacta para usar Soundscape"; +"general.error.precise_location" = "Activa Ubicación exacta para usar Soundscape"; /* */ @@ -279,7 +279,7 @@ /* */ -"general.error.heading" = "Soundscape no está seguro de qué dirección estás mirando. Por favor, mantén tu teléfono plano o empieza a caminar e inténtalo de nuevo."; +"general.error.heading" = "Soundscape no está seguro de hacia qué dirección estás orientado. Mantén el teléfono plano o comienza a caminar e inténtalo de nuevo"; /* */ @@ -287,7 +287,7 @@ /* */ -"general.error.wifi" = "¡Ay! Parece que no estás conectado a ninguna Wi-Fi."; +"general.error.wifi" = "¡Ay! No parece que estés conectado a Wi-Fi."; /* */ @@ -563,7 +563,7 @@ /* */ -"voice.settings.enhanced_available" = "Es posible que exista una versión de mayor calidad para esta voz. Para descargarla y descargar otras voces, ve a la sección Lectura y voz de los ajustes de accesibilidad de iOS."; +"voice.settings.enhanced_available" = "Es posible que exista una versión de mayor calidad de esta voz. Para descargarla, así como para descargar otras voces, ve a la sección Lectura y voz de los ajustes de accesibilidad de iOS."; /* */ @@ -599,7 +599,7 @@ /* */ -"beacon.settings.explanation" = "Selecciona un estilo de señal que sea cómodo de escuchar y que se oiga fácilmente al aire libre y en entornos ruidosos. Asegúrate de que puedes determinar con facilidad su dirección a través de tu dispositivo de escucha preferido (auriculares o altavoz del teléfono)."; +"beacon.settings.explanation" = "Selecciona un estilo de señal que resulte cómodo en los oídos y que se escuche fácilmente al aire libre y en entornos ruidosos. Asegúrate de que puedes determinar con facilidad su dirección a través de tu dispositivo de escucha preferido (auriculares o altavoz del teléfono)."; /* */ @@ -1091,7 +1091,7 @@ /* */ -"location_detail.map.edit.hint" = "Mover el mapa a la ubicación correcta"; +"location_detail.map.edit.hint" = "Mueve el mapa a la ubicación correcta"; /* */ @@ -1191,7 +1191,7 @@ /* */ -"route_detail.action.start_route.disabled.hint" = "Añadir puntos a la ruta antes de iniciarla"; +"route_detail.action.start_route.disabled.hint" = "Agregar puntos a la ruta antes de iniciarla"; /* */ @@ -1367,7 +1367,7 @@ /* */ -"route.update.fail.title" = "Falla de actualizar"; +"route.update.fail.title" = "Error al actualizar"; /* */ @@ -1447,7 +1447,7 @@ /* */ -"waypoint.callout.button.hint" = "Pulsa dos veces para escuchar información adicional"; +"waypoint.callout.button.hint" = "Pulsa dos veces para oír detalles adicionales"; /* */ @@ -1603,7 +1603,7 @@ /* */ -"routes.tutorial.title" = "Escucha los puntos de ruta de tu recorrido"; +"routes.tutorial.title" = "Oye los puntos de ruta de tu recorrido"; /* */ @@ -1759,7 +1759,7 @@ /* */ -"searching.no_results_found_title" = "¡Ay! No se han encontrado resultados"; +"searching.no_results_found_title" = "¡Ay! No se han encontrado resultados."; /* */ @@ -1935,7 +1935,7 @@ /* */ -"callouts.nothing_to_call_out_now" = "No hay nada de lo que avisar ahora mismo."; +"callouts.nothing_to_call_out_now" = "No hay nada de lo que avisar ahora mismo"; /* */ @@ -2051,7 +2051,7 @@ /* */ -"directions.intersects_with_in" = "Se cruza con %1$@ en %2$@"; +"directions.intersects_with_in" = "Cruces con %1$@ en %2$@"; /* */ @@ -2243,7 +2243,7 @@ /* */ -"directions.traveling.ne" = "Viajando al noreste"; +"directions.traveling.ne" = "Viajando al nordeste"; /* */ @@ -2251,7 +2251,7 @@ /* */ -"directions.traveling.se" = "Viajando al sureste"; +"directions.traveling.se" = "Viajando al sudeste"; /* */ @@ -2275,7 +2275,7 @@ /* */ -"directions.facing.ne" = "Mirando al noreste"; +"directions.facing.ne" = "Mirando al nordeste"; /* */ @@ -2283,7 +2283,7 @@ /* */ -"directions.facing.se" = "Mirando al sureste"; +"directions.facing.se" = "Mirando al sudeste"; /* */ @@ -2307,7 +2307,7 @@ /* */ -"directions.heading.ne" = "Caminando hacia el noreste"; +"directions.heading.ne" = "Caminando hacia el nordeste"; /* */ @@ -2315,7 +2315,7 @@ /* */ -"directions.heading.se" = "Caminando hacia el sureste"; +"directions.heading.se" = "Caminando hacia el sudeste"; /* */ @@ -2339,7 +2339,7 @@ /* */ -"directions.along.traveling.ne" = "Viajando al noreste por %@"; +"directions.along.traveling.ne" = "Viajando al nordeste por %@"; /* */ @@ -2347,7 +2347,7 @@ /* */ -"directions.along.traveling.se" = "Viajando al sureste por %@"; +"directions.along.traveling.se" = "Viajando al sudeste por %@"; /* */ @@ -2371,7 +2371,7 @@ /* */ -"directions.along.facing.ne" = "Mirando al noreste por %@"; +"directions.along.facing.ne" = "Mirando al nordeste por %@"; /* */ @@ -2379,7 +2379,7 @@ /* */ -"directions.along.facing.se" = "Mirando al sureste por %@"; +"directions.along.facing.se" = "Mirando al sudeste por %@"; /* */ @@ -2403,7 +2403,7 @@ /* */ -"directions.along.heading.ne" = "Caminando hacia el noreste por %@"; +"directions.along.heading.ne" = "Caminando hacia el nordeste por %@"; /* */ @@ -2411,7 +2411,7 @@ /* */ -"directions.along.heading.se" = "Caminando hacia el sureste por %@"; +"directions.along.heading.se" = "Caminando hacia el sudeste por %@"; /* */ @@ -2435,7 +2435,7 @@ /* */ -"directions.cardinal.north_east" = "Noreste"; +"directions.cardinal.north_east" = "Nordeste"; /* */ @@ -2443,7 +2443,7 @@ /* */ -"directions.cardinal.south_east" = "Sureste"; +"directions.cardinal.south_east" = "Sudeste"; /* */ @@ -2678,7 +2678,7 @@ /* */ -"location_callout_cell.nearest_road" = "Carretera más cercana, %@"; +"location_callout_cell.nearest_road" = "Carretera más cercana, %@."; /* */ @@ -2710,15 +2710,15 @@ /* */ -"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo.\n\nPulsa el botón siguiente para conectar un dispositivo."; +"devices.explain_ar.disconnected" = "Los auriculares con seguimiento de cabeza son auriculares Bluetooth con sensores que indican a Soundscape hacia dónde estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio, al hacerla más natural mientras te desplazas por el mundo.\n\nPulsa el botón siguiente para conectar un dispositivo."; /* */ -"devices.explain_ar.connected.airpods" = "Tus AirPods están listos para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tienes que llevar el teléfono en la mano."; +"devices.explain_ar.connected.airpods" = "Tus AirPods están listos para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tengas que llevar el teléfono en la mano."; /* */ -"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Asegúrate de que los auriculares están activados y que se encuentran cerca del teléfono."; +"devices.explain_ar.paired" = "Soundscape no está conectado actualmente a %@. Comprueba que los auriculares están activados y que se encuentran cerca del teléfono."; /* */ @@ -2762,11 +2762,11 @@ /* */ -"devices.connect_headset.calibrate" = "Los auriculares tienen que calibrarse. Quítate los de la cabeza, agítalos suavemente en todas direcciones durante unos 10 segundos y colócalos de nuevo sobre tu cabeza. Se debe repetir si el timbre de calibración sigue sonando."; +"devices.connect_headset.calibrate" = "Los auriculares tienen que calibrarse. Quítatelos y sacúdelos con suavidad en todas las direcciones durante unos 10 segundos, y vuelve a colocártelos. Se debe repetir si el timbre de calibración sigue sonando."; /* */ -"devices.connect_headset.calibrate.in_ear" = "Los auriculares tienen que calibrarse. Agita suavemente la cabeza en todas las direcciones durante unos 10 segundos. Se debe repetir si el timbre de calibración sigue sonando."; +"devices.connect_headset.calibrate.in_ear" = "Los auriculares tienen que calibrarse. Sacude la cabeza con suavidad en todas las direcciones durante unos 10 segundos. Se debe repetir si el timbre de calibración sigue sonando."; /* */ @@ -2802,7 +2802,7 @@ /* */ -"devices.forget_headset.prompt.explanation" = "Esto desconectará los auriculares de Soundscape. Se pueden conectar a Soundscape de nuevo en el futuro desde aquí."; +"devices.forget_headset.prompt.explanation" = "Esto desconectará los auriculares de Soundscape. Puedes conectarte a Soundscape de nuevo en el futuro desde aquí."; /* */ @@ -2814,7 +2814,7 @@ /* */ -"devices.callouts.needs_calibration.in_ear" = "Los auriculares tienen que calibrarse. Sacúdelos con suavidad en todas las direcciones."; +"devices.callouts.needs_calibration.in_ear" = "Los auriculares tienen que calibrarse. Sacude la cabeza con suavidad en todas las direcciones."; /* */ @@ -2910,7 +2910,7 @@ /* */ -"behavior.experience.delete.explanation" = "Si eliminas esta actividad, se eliminará de tu teléfono."; +"behavior.experience.delete.explanation" = "Si eliminas esta experiencia, se quitará del teléfono."; /* */ @@ -2998,11 +2998,11 @@ /* */ -"announced_name.named" = "Anuncio de %1$@, %2$@."; +"announced_name.named" = "%1$@, anuncio de %2$@."; /* */ -"announced_name_distance_away.named" = "Anuncio de %1$@, %2$@, %3$@ de distancia."; +"announced_name_distance_away.named" = "%1$@, anuncio de %2$@, %3$@ de distancia."; /* */ @@ -3126,11 +3126,11 @@ /* */ -"tutorial.markers.text.AudioBeacon" = "También puedes establecer una señal de audio en el marcador.\nVamos a probarlo. Esta es una señal de @!marker_name!!.\nEscucha atentamente dónde está y, manteniendo el teléfono en posición horizontal, gira hacia ella."; +"tutorial.markers.text.AudioBeacon" = "También puedes establecer una señal de audio en tu marcador.\nVamos a probarlo. Esta es una señal de @!marker_name!!.\nEscucha atentamente dónde está y, manteniendo el teléfono en posición horizontal, gira hacia ella."; /* */ -"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás mirando hacia tu marcador, @!marker_name!!.\n¡Parece que lo has entendido!\nPara administrar tu lista de marcadores, selecciona Marcadores y rutas en la pantalla de inicio.\nTambién puedes visitar las páginas de Ayuda y tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; +"tutorial.markers.text.WrapUp" = "Perfecto, ahora estás orientado hacia tu marcador, @!marker_name!!.\n¡Parece que lo has entendido!\nPara administrar tu lista de marcadores, selecciona Marcadores y rutas en la pantalla de inicio.\nTambién puedes visitar las páginas de Ayuda y tutoriales para repasar este tutorial o para leer una guía completa sobre todo lo que puedes hacer con los marcadores. La señal que has establecido para este tutorial se borrará ahora y regresarás a la pantalla anterior."; /* */ @@ -3166,7 +3166,7 @@ /* */ -"tutorial.beacon.found_the_beacon" = "¡Genial! ¡Has encontrado tu señal!"; +"tutorial.beacon.found_the_beacon" = "¡Fantástico! ¡Has encontrado la señal!"; /* */ @@ -3186,7 +3186,7 @@ /* */ -"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla orientada hacia arriba y con la parte superior del teléfono apuntando justo delante de ti."; +"tutorial.beacons.text.OrientationIsNotFlat" = "Para empezar, mantén el teléfono en posición horizontal con la pantalla mirando hacia arriba y con la parte superior del teléfono apuntando justo delante de ti."; /* */ @@ -3214,27 +3214,27 @@ /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Ahora, manteniendo todavía el teléfono en posición horizontal, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estás mirando directamente en su dirección."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate" = "Ahora, manteniendo todavía el teléfono en posición horizontal, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estés orientado directamente hacia ella."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Ahora, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estás mirando directamente en su dirección."; +"tutorial.beacons.text.BeaconOutOfBoundsRotate.ar_headset" = "Ahora, gira lentamente hacia la dirección de la señal. Oirás el sonido de un timbre cuando estés mirando directamente en su dirección."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsRepeat" = "Gira lentamente hasta que oigas el timbre que indica que estás mirando en la dirección de la señal."; +"tutorial.beacons.text.BeaconOutOfBoundsRepeat" = "Gira lentamente hasta que oigas el timbre que indica que estás orientado en la dirección de la señal."; /* */ -"tutorial.beacons.text.BeaconOutOfBoundsConfirmation" = "Perfecto, ahora estás mirando en dirección a @!destination!!."; +"tutorial.beacons.text.BeaconOutOfBoundsConfirmation" = "Perfecto, ahora estás orientado en la dirección de @!destination!!."; /* */ -"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente, oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido normal de la señal. Eso significa que estás mirando directamente hacia @!destination!!."; +"tutorial.beacons.text.BeaconInBounds" = "Si escuchas atentamente, oirás que se está reproduciendo desde justo delante de ti y que hay un sonido de timbre además del sonido de señal normal. Eso significa que te encuentras orientado directamente hacia @!destination!!."; /* */ -"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal, manteniendo todavía el teléfono en posición horizontal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Inténtalo ahora."; +"tutorial.beacons.text.BeaconInBoundsRotate" = "Ahora intenta alejarte lentamente de la dirección de la señal, mientras sigues manteniendo el teléfono en posición horizontal. El sonido del timbre se detendrá y la señal continuará mostrándote dónde se encuentra @!destination!!. Pruébalo ahora."; /* */ @@ -3246,7 +3246,7 @@ /* */ -"tutorial.beacons.text.MobilitySkills" = "La señal siempre apunta directamente hacia la ubicación que has seleccionado. No te indica las rutas que debes seguir ni te proporciona indicaciones para llegar a esa ubicación. Usa esta señal como herramienta para decidir cómo deseas llegar allí."; +"tutorial.beacons.text.MobilitySkills" = "La señal siempre señala directamente hacia la ubicación que has seleccionado. No te indica las rutas que debes seguir ni te proporciona indicaciones para llegar a esa ubicación. Usa esta señal como herramienta para decidir cómo deseas llegar allí."; /* */ @@ -3410,15 +3410,15 @@ /* */ -"terms_of_use.accept.new_features.accessibility_hint" = "Pulsa dos veces para aceptar y cerrar los anuncios"; +"terms_of_use.accept.new_features.accessibility_hint" = "Pulsa dos veces para aceptar y cerrar anuncios"; /* */ -"first_launch.get_started_button.off.acc_hint" = "Debes marcar la casilla \"Aceptar los términos de uso\" antes de poder pulsar este botón"; +"first_launch.get_started_button.off.acc_hint" = "Para poder presionar este botón, activa la casilla \"Aceptar los términos de uso\""; /* */ -"first_launch.welcome_text" = "¡Bienvenido! Antes de comenzar, tenemos que hacer algunos ajustes y pedir varios permisos. Presiona el botón Siguiente para iniciar."; +"first_launch.welcome_text" = "¡Bienvenido! Antes de comenzar, tenemos que configurar algunos valores y pedir varios permisos. Presiona el botón Siguiente para iniciar."; /* */ @@ -3434,7 +3434,7 @@ /* */ -"first_launch.soundscape_language.text" = "Selecciona el idioma que deseas usar en Soundscape. Siempre puedes cambiar tu selección en los ajustes de la aplicación."; +"first_launch.soundscape_language.text" = "Selecciona el idioma que deseas que use Soundscape. Siempre podrás cambiar tu selección en los ajustes de la aplicación."; /* */ @@ -3450,7 +3450,7 @@ /* */ -"first_launch.device_motion.text" = "Esto permite a Soundscape mejorar tu experiencia en función de si caminas, te desplazas en un vehículo o permaneces quieto."; +"first_launch.device_motion.text" = "Esto le permite a Soundscape mejorar tu experiencia en función de si vas a pie, te desplazas en un vehículo o no te mueves."; /* */ @@ -3470,7 +3470,7 @@ /* */ -"first_launch.setting_off_way" = "¿Te pones en camino?"; +"first_launch.setting_off_way" = "¿Vas a empezar el trayecto?"; /* */ @@ -3642,7 +3642,7 @@ /* */ -"help.text.destination_beacons.how.1" = "Para establecer una señal:
primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Detalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; +"help.text.destination_beacons.how.1" = "Para establecer una señal:
primero, ve los detalles de una ubicación usando la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. Luego, en la pantalla \"Detalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; /* */ @@ -3678,15 +3678,15 @@ /* */ -"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección en la que estás mirando, dónde se encuentran cruces o carreteras cercanas y dónde hay puntos de interés cercanos."; +"help.text.my_location.what" = "El botón \"Mi ubicación\" te ofrece información rápidamente que te ayuda a averiguar dónde te encuentras actualmente. \"Mi ubicación\" te informa sobre tu ubicación actual, incluidas cosas como la dirección hacia la que estás orientado, dónde se encuentran cruces o carreteras cercanas y dónde hay puntos de interés cercanos."; /* */ -"help.text.my_location.when" = "\"Mi ubicación\" es útil cuando necesitas averiguar dónde te encuentras o hacia qué dirección cardinal estás mirando."; +"help.text.my_location.when" = "\"Mi ubicación\" es útil cuando necesitas averiguar dónde te encuentras o hacia qué dirección cardinal estás orientado."; /* */ -"help.text.my_location.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Mi ubicación\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Mi ubicación\" y escuchar."; +"help.text.my_location.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Mi ubicación\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Mi ubicación\" y escuchar."; /* */ @@ -3698,7 +3698,7 @@ /* */ -"help.text.nearby_markers.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Marcadores cercanos\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Marcadores cercanos\" y escuchar hasta cuatro marcadores cerca de ti."; +"help.text.nearby_markers.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Marcadores cercanos\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Marcadores cercanos\" y escuchar hasta cuatro marcadores cerca de ti."; /* */ @@ -3710,7 +3710,7 @@ /* */ -"help.text.around_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Alrededor de mí\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Alrededor de mí\" y oirás cuatro puntos de interés situados a tu alrededor."; +"help.text.around_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Alrededor de mí\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Alrededor de mí\" y oirás cuatro puntos de interés situados a tu alrededor."; /* */ @@ -3722,7 +3722,7 @@ /* */ -"help.text.ahead_of_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Delante de mí\". Esto actúa como una brújula que le indica a la aplicación hacia dónde estás mirando. Solo tienes que pulsar el botón \"Delante de mí\" y oirás varios puntos de interés que estén más o menos delante de ti."; +"help.text.ahead_of_me.how" = "Como con los cuatro botones de la parte inferior de la pantalla principal, mantén el teléfono con la pantalla en posición horizontal (hacia arriba) y la parte superior del teléfono apuntando en la dirección en la que estás mirando antes de presionar el botón \"Delante de mí\". Esto actúa como una brújula que le indica a la aplicación hacia qué dirección estás orientado. Solo tienes que pulsar el botón \"Delante de mí\" y oirás varios puntos de interés que estén más o menos delante de ti."; /* */ @@ -3786,7 +3786,7 @@ /* */ -"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods le indican a Soundscape la dirección en la que estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que la aplicación funcione bien."; +"help.using_headsets.airpods.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar AirPods compatibles. Cuando se conecten, los sensores de los AirPods le indicarán a Soundscape la dirección en la que está orientada tu cabeza. Esto le ayuda a Soundscape a mejorar tu experiencia de audio, haciéndola más natural a medida que te mueves por el mundo. Cuando usas Soundscape con los AirPods conectados, no es necesario sostener el teléfono para que la aplicación funcione bien."; /* */ @@ -4110,7 +4110,7 @@ /* */ -"voice.apple.additional" = "Se pueden descargar voces adicionales, incluidas las de calidad mejorada, en la sección Lectura y voz de los ajustes de accesibilidad de iOS."; +"voice.apple.additional" = "Se pueden descargar más voces, incluidas las de calidad mejorada, en la sección Lectura y voz de los ajustes de accesibilidad de iOS."; /* */ @@ -4142,7 +4142,7 @@ /* */ -"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares que se pueden encontrar con la aplicación u otros totalmente nuevos que hayas agregado tú mismo. Para guardar tu ubicación actual como marcador, selecciona el botón \"Ubicación actual\" en la pantalla principal y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que deseas guardar con la barra de búsqueda, o encontrando algún lugar mediante el botón \"Lugares cercanos\"; ambos se encuentran en la pantalla principal de Soundscape. Una vez que hayas encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; +"faq.markers_function.answer" = "Los marcadores son lugares que has guardado. Pueden ser lugares que se pueden encontrar con la aplicación u otros totalmente nuevos que has agregado tú mismo. Para guardar tu ubicación actual como marcador, selecciona el botón \"Ubicación actual\" en la pantalla principal y, a continuación, \"Guardar como marcador\". Puedes guardar otras ubicaciones como marcador buscando el lugar que deseas guardar con la barra de búsqueda, o encontrando algún lugar mediante el botón \"Lugares cercanos\"; ambos se encuentran en la pantalla principal de Soundscape. Una vez que has encontrado el lugar que deseas, al seleccionarlo, irás a la página \"Detalles de la ubicación\". En esta página, selecciona el botón \"Guardar como marcador\"."; /* */ @@ -4154,7 +4154,7 @@ /* */ -"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como señal. Primero, ve los detalles de una ubicación mediante la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. A continuación, en la pantalla \"Ddetalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; +"faq.what_can_I_set.answer" = "Puedes establecer una señal de audio en cualquier negocio, lugar, punto de interés, dirección o cruce. Hay varias formas de establecer una ubicación como señal. Primero, ve los detalles de una ubicación mediante la barra de búsqueda para buscar un lugar, o pulsando uno de los botones \"Lugares cercanos\", \"Marcadores y rutas\" o \"Ubicación actual\" y seleccionando una ubicación. Luego, en la pantalla \"Detalles de la ubicación\", selecciona el botón \"Iniciar señal de audio\". Al pulsarlo, volverás a la pantalla de inicio y se activará una señal audible proveniente de la dirección del lugar que has seleccionado. El nombre del lugar junto con su distancia y dirección física, si están disponibles, aparecerán ahora en la pantalla principal."; /* */ @@ -4170,7 +4170,7 @@ /* */ -"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección en la que estás mirando. Cuando Soundscape no está seguro de hacia donde estás mirando, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apuntas en dirección contraria a ti."; +"faq.why_does_beacon_disappear.answer" = "La señal de audio de Soundscape es básicamente una indicación de dirección, que te informa de dónde se encuentra tu destino en relación con la dirección hacia la que estás orientado. Cuando Soundscape no está seguro de hacia donde estás orientado, baja el volumen de la señal. Muy a menudo esto sucede si has estado caminando con el teléfono guardado en el bolsillo o en el bolso y dejas de moverte, como para cruzar la calle. El sonido de la señal será más alto una vez que empieces a moverte de nuevo o si mantienes el teléfono en posición horizontal y lo apuntas en dirección contraria a ti."; /* */ @@ -4186,7 +4186,7 @@ /* */ -"faq.beacon_on_home.answer" = "Soundscape permite establecer señales en direcciones. Para establecer una señal en tu casa, o en cualquier otra dirección, en la pantalla principal, pulsa en la barra de búsqueda y escribe la dirección. En la pantalla \"Detalles de la ubicación\", pulsa el botón \"Iniciar señal de audio\"."; +"faq.beacon_on_home.answer" = "Soundscape admite el establecimiento de señales en direcciones. Para establecer una señal en tu casa, o en otra dirección, en la pantalla principal, pulsa en la barra de búsqueda y escribe la dirección. En la pantalla \"Detalles de la ubicación\", pulsa el botón \"Iniciar señal de audio\"."; /* */ @@ -4194,7 +4194,7 @@ /* */ -"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, escucharás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar la distancia a la que la señal se silencia de la siguiente manera: ve a \"Señal de audio\" en la pantalla \"Ajustes\" y mueve el control deslizante \"Distancia de silenciar el audio\" hacia arriba o hacia abajo."; +"faq.how_close_to_destination.answer" = "Soundscape puede determinar la ubicación de tu destino con una precisión de varios metros, pero no menos. Cuando Soundscape determine que estás cerca de tu destino, escucharás un último aviso de que tu destino está cerca y la señal se apagará. Puedes ajustar la distancia a la que la señal se silencia de la forma siguiente: ve a \"Señal de audio\" en la pantalla \"Ajustes\" y mueve el control deslizante \"Distancia de silenciar el audio\" hacia arriba o hacia abajo."; /* */ @@ -4294,7 +4294,7 @@ /* */ -"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar dónde te encuentras. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupa el consumo de batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa los servicios de localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; +"faq.background_battery_impact.answer" = "Soundscape usa Localización para determinar dónde te encuentras. En nuestras pruebas, Soundscape no consume más batería que la aplicación media de mapas, pero si te preocupa el consumo de la batería del teléfono, las siguientes son algunas sugerencias que ayudarán a reducir el uso:\n\n1. Desactiva la pantalla lo máximo posible cuando no interactúes con la aplicación.\n2. Cuando no uses la aplicación, ciérrala. Soundscape usa los servicios de localización continuamente mientras se ejecuta por lo que siempre conoce tu ubicación, incluso cuando no estás en movimiento. No te olvides de reiniciar la aplicación al reanudar el trayecto.\n3. Con tiempo frío, mantén el teléfono en una temperatura cálida ya que el rendimiento de las baterías empeora con temperaturas bajas."; /* */ @@ -4310,7 +4310,7 @@ /* */ -"faq.difference_from_map_apps.answer" = "Soundscape ofrece una descripción de tu entorno mediante la exploración y la orientación. Usando el sonido espacial, Soundscape avisará de puntos de interés, parques, carreteras y cruces desde la dirección en la que se encuentran físicamente en tu entorno inmediato mientras caminas. Por ejemplo, si pasas por una tienda que se encuentre a tu derecha, oirás el nombre de la tienda sonando a tu derecha. Cuando te acerques a un cruce, oirás el sonido del nombre de cada carretera proveniente de la dirección a la que se dirige, comenzando por la izquierda, adelante y a la derecha.\n\nEn lugar de indicaciones paso a paso, a menudo proporcionadas por otras aplicaciones de mapas, Soundscape reproducirá una señal de audio en la dirección de tu destino, lo que te permitirá llegar allí en tus condiciones con el mejor conocimiento posible de tu entorno y de la ubicación de tu destino. Soundscape se ha diseñado para ejecutarse en segundo plano, lo que te permite usar una aplicación de indicaciones paso a paso, y seguirá proporcionando todo el tiempo información del entorno mientras llegas a tu destino."; +"faq.difference_from_map_apps.answer" = "Soundscape ofrece una descripción de tu entorno mediante la exploración y la orientación. Usando el sonido espacial, Soundscape avisará de puntos de interés, parques, carreteras y cruces desde la dirección en la que se encuentran físicamente en tu entorno inmediato mientras caminas. Por ejemplo, si pasas por una tienda que se encuentre a tu derecha, oirás el nombre de la tienda sonando a tu derecha. Cuando te acerques a un cruce, oirás el sonido del nombre de cada carretera proveniente de la dirección a la que se dirige, comenzando por la izquierda, adelante y a la derecha.\n\nEn lugar de indicaciones paso a paso, a menudo proporcionadas por otras aplicaciones de mapas, Soundscape reproducirá una señal de audio en la dirección de tu destino, lo que te permitirá llegar allí en tus condiciones con el mejor conocimiento posible de tu entorno y de la ubicación de tu destino. Soundscape se ha diseñado para ejecutarse en segundo plano, lo que te permite usar una aplicación de indicaciones paso a paso, y seguirá proporcionando todo el tiempo información del entorno mientras llegues a tu destino."; /* */ @@ -4326,7 +4326,7 @@ /* */ -"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias maneras de controlar lo que oyes y cuándo:\n\n1. Detener inmediatamente todo el audio: pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo en ese momento y la señal si está activada. Los avisos se reanudarán automáticamente al aproximarse al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar avisos\".\n3. Detener la señal: hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo quieras obtener actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; +"faq.controlling_what_you_hear.answer" = "Soundscape ofrece varias maneras de controlar lo que se oye y cuándo:\n\n1. Detener inmediatamente todo el audio: pulsa dos veces en la pantalla con dos dedos para desactivar inmediatamente todo el audio, incluido cualquier aviso que se esté reproduciendo y la señal si está activada. Los avisos se reanudarán automáticamente al aproximarse al siguiente cruce o punto de interés, pero la señal de audio no. Selecciona el botón \"Reactivar señal\" en la pantalla principal para volver a oír la señal.\n2. Detener los avisos automáticos: cuando no estés viajando o hayas llegado a un destino, probablemente no necesitarás que Soundscape siga notificándote elementos de tu entorno. En lugar de salir de la aplicación, puedes poner Soundscape en el modo de aplazamiento y se reactivará cuando salgas o bien, puedes poner Soundscape en el modo de suspensión y permanecerá desactivado hasta que lo reactives. Alternativamente, puedes seleccionar \"Ajustes\" en el menú y desactivar todos los avisos en la sección \"Administrar avisos\".\n3. Detener la señal: hay varios escenarios para los que podrías establecer un destino, pero no necesitar la señal audible activada. Por ejemplo, puede que sepas exactamente cómo llegar a tu destino, pero solo desees obtener actualizaciones automáticas sobre la distancia. O puede que sepas más o menos cómo llegar a tu destino, y sólo necesites la señal de audio cuando casi hayas llegado. En cualquier caso, puedes elegir cuándo oír la señal alternando el botón \"Silenciar señal\"/\"Reactivar señal\" en la pantalla principal."; /* */ @@ -4334,7 +4334,7 @@ /* */ -"faq.holding_phone_flat.answer" = "¡No, no! Cuando camines, puedes meter el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que caminas para averiguar qué avisos emitirá a tu izquierda y a tu derecha. Cuando dejes de moverte, Soundscape no sabrá hacia dónde estás mirando. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia dónde estás mirando y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que vuelve a todo su volumen."; +"faq.holding_phone_flat.answer" = "¡No, no! Cuando camines, puedes meter el teléfono en una bolsa o bolsillo o donde sea conveniente. Soundscape usará la dirección hacia la que caminas para averiguar qué avisos emitirá a tu izquierda y a tu derecha. Cuando dejes de moverte, Soundscape no sabrá hacia dónde estás orientado. Si la señal de audio está activada, observarás que se calla hasta que vuelvas a moverte. Puedes sacar el teléfono para presionar los botones \"Escuchar mi entorno\" en la parte inferior de la pantalla principal en cualquier momento, pero asegúrate de sujetarlo con la parte superior apuntando en la dirección en la que estás mirando y con la pantalla hacia arriba. En esta posición \"plana\", Soundscape usará la brújula del teléfono para determinar hacia qué dirección estás orientado y proporcionar avisos espaciales precisos. Si la señal está activada, también observarás que el volumen se restablece por completo."; /* */ @@ -4342,7 +4342,7 @@ /* */ -"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir cuál de las voces disponibles en iOS quieres que use Soundscape, así como la velocidad a la que se pronuncian los mensajes. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Voz\" para ajustar la velocidad de habla y la voz. Se pueden descargar voces adicionales, incluidas las voces de calidad mejorada, en los ajustes de iOS en Ajustes > Accesibilidad > Lectura y voz (Contenido leído) > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar las distancias en pies o en metros. En el menú, selecciona \" Ajustes \" y, a continuación, en \" Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados cuando pases a pie o te acerques a ellos. También puedes usar el botón \"Marcadores cercanos\" de la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Los marcadores seguirán siendo personales y nadie más podrá verlos.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver estén activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver de la siguiente manera: ve a los ajustes de iOS, luego a Accesibilidad > VoiceOver > Verbosidad y, por último, activa las indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, puede ser difícil oír los avisos automáticos si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los ajustes de VoiceOver o a través del rotor de VoiceOver.\n3. Touch ID o Face ID para desbloquear: si configuras tu teléfono para que se desbloquee con Touch ID o Face ID, será más fácil y rápido desbloquearlo, y podrás obtener acceso más deprisa a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" cuando camines. Configura el desbloqueo con Touch ID o Face ID en la aplicación de ajustes de iOS."; +"faq.personalize_experience.answer" = "Soundscape te permite personalizar tres aspectos clave de los avisos que oyes cuando caminas:\n\n1. Voz: puedes elegir la voz que quieres escuchar en Soundscape entre las voces disponibles en iOS, así como la velocidad de pronunciación de los avisos. En el menú, selecciona \"Ajustes\" y luego, en \"Ajustes generales\", selecciona \"Voz\" para ajustar la velocidad de habla y la voz. Se pueden descargar más voces, incluidas las voces de calidad mejorada, en los ajustes de iOS en Ajustes > Accesibilidad > Lectura y voz (Contenido leído) > Voces.\n2. Medida de la distancia: Soundscape te permite escuchar las distancias en pies o en metros. En el menú, selecciona \"Ajustes\" y después, en \"Ajustes generales\", selecciona \"Idioma y región\". La sección Unidades de medida te permite alternar entre Imperial (pies) y Métrica (metros).\n3. Marcadores: puedes marcar tu mundo con cualquier cosa que te interese. Puedes marcar cosas que sean personales y relevantes para ti, como tu casa, tu oficina y tu tienda de comestibles preferida. Luego, Soundscape te avisará automáticamente de los lugares marcados cuando pases a pie o te acerques a ellos. También puedes usar el botón \"Marcadores cercanos\" de la parte inferior de la pantalla de inicio para oír un aviso espacial de los lugares marcados a tu alrededor. Los marcadores seguirán siendo personales y nadie más podrá verlos.\n\nAdemás de estas posibilidades, los siguientes ajustes pueden influir en el comportamiento de Soundscape:\n\n1. Consejos de VoiceOver: cuando los consejos de VoiceOver estén activados, escucharás más información sobre todos los botones en la pantalla principal. Puedes activar los consejos de VoiceOver de la siguiente manera: ve a los ajustes de iOS, luego a Accesibilidad > VoiceOver > Verbosidad y, por último, activa las indicaciones.\n2. Atenuación de audio: Soundscape está diseñado para funcionar con la atenuación de audio desactivada. Cuando la atenuación de audio está activada, puede ser difícil oír los avisos automáticos si se usa VoiceOver a la vez. Recomendamos desactivar la atenuación de audio para que sea más fácil oír todos los avisos automáticos. La atenuación de audio se puede desactivar en los ajustes de VoiceOver o a través del rotor de VoiceOver.\n3. Touch ID o Face ID para desbloquear: si configuras tu teléfono para que se desbloquee por medio de Touch ID o Face ID, será más fácil y rápido desbloquearlo, y podrás obtener acceso más deprisa a los botones \"Mi ubicación\", \"Alrededor de mí\" y \"Delante de mí\" cuando camines. Configura el desbloqueo con Touch ID o Face ID en la aplicación de ajustes de iOS."; /* */ @@ -4354,7 +4354,7 @@ /* */ -"faq.tip.beacon_quiet" = "Si metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia dónde estás mirando. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; +"faq.tip.beacon_quiet" = "Si metes el teléfono en el bolsillo y dejas de moverte, bajará el volumen del sonido de la señal porque Soundscape no sabrá hacia dónde estás orientado. Para solucionar esto, empieza a andar de nuevo o saca el teléfono y mantenlo en posición horizontal."; /* */ @@ -4378,7 +4378,7 @@ /* */ -"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas a menudo, establece tus paradas de recogida y salida como marcadores. De esta forma se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y recibirás actualizaciones periódicas sobre lo cerca que estás a la parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás obteniendo actualizaciones de la distancia por el camino."; +"faq.tip.create_marker_at_bus_stop" = "Si hay una ruta de autobús que tomas a menudo, establece tus paradas de recogida y salida como marcadores. De esta manera se guardarán para que puedas volver a encontrarlas fácilmente, sólo tienes que ir a \"Marcadores y rutas\" desde la pantalla principal y encontrarlas en la página \"Marcadores\". Puedes establecer una señal en ellas y recibirás actualizaciones periódicas sobre lo cerca que estás a la parada de salida. Nota: puedes desactivar el sonido rítmico y seguirás obteniendo actualizaciones de la distancia por el camino."; /* */ @@ -4431,14 +4431,14 @@ "devices.connect_headset.completed.boseframes" = "¡Enhorabuena! Tus Bose Frames están listas para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape seguirá ahora la orientación de tu cabeza para que no tengas que llevar el teléfono en la mano."; "devices.callouts.check_audio.bose_frames" = "Bose Frames conectadas."; "devices.callouts.check_audio.bose_frames.disconnected" = "Soundscape está buscando tus Bose Frames. Asegúrate de que están conectadas al teléfono."; -"devices.explain_ar.connected.boseframes" = "Tus Bose Frames están listas para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tienes que llevar el teléfono en la mano."; +"devices.explain_ar.connected.boseframes" = "Tus Bose Frames están listas para usar. ¡Guarda el teléfono en el bolsillo y empieza a moverte! Soundscape está siguiendo la orientación de tu cabeza para que no tengas que llevar el teléfono en la mano."; "help.using_headsets.bose_frames.title" = "Uso de Bose Frames"; "help.using_headsets.bose_frames.when" = "Puedes usar Bose Frames en cualquier momento con Soundscape. El uso de Bose Frames te proporciona un audio de alta calidad que no dificulta la audición ambiental y te permite tener una experiencia mayor de manos libres."; "help.using_headsets.bose_frames.how.3" = "Uso de los controles multimedia en los auriculares:
cuando los controles multimedia estén habilitados en la configuración de Soundscape, podrás usarlos en las Bose Frames para silenciar o reactivar la señal, avisar de tu ubicación o repetir el último aviso de llamada. Para obtener más información, ve la sección de ayuda \"Uso de controles multimedia\"."; "help.using_headsets.bose_frames.how.1" = "Conexión de un dispositivo:
ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape para conectar las Bose Frames y sigue las instrucciones que aparecen en pantalla. Ten en cuenta que tendrás que emparejar las Bose Frames en los ajustes de Bluetooth del teléfono antes de conectarlas a Soundscape."; "help.using_headsets.bose_frames.how.4" = "Solución de problemas de los auriculares:
si tienes problemas para conectar las Bose Frames a Soundscape, asegúrate de que son de uno de los modelos compatibles: Altos o Rondos. Si son uno de estos modelos, asegúrate de que las Frames aparecen en la aplicación Bose Connect. Si se muestran y sigues teniendo problemas con la conexión, intenta desemparejar y volver a emparejar los auriculares a través del menú Bluetooth del teléfono.
Nos encantaría escuchar tus comentarios sobre la compatibilidad con las Bose Frames. Puedes contactarnos eligiendo la opción \"Enviar comentarios\" en el menú."; "help.using_headsets.bose_frames.how.2" = "Calibración de los auriculares:
tus Bose Frames tendrán que calibrarse para saber con precisión hacia dónde estás mirando. cada vez que las conectes a Soundscape, se te informará que se las necesitan calibrar mediante un timbre de audio. Para calibrar las Bose Frames, sigue las instrucciones que aparecen en la pantalla. Cuando el timbre deje de sonar, las Bose Frames estarán calibradas. Soundscape seguirá ahora la dirección de tu cabeza para que no tengas que llevar el teléfono en la mano. Puedes repetir esta calibración en cualquier momento, incluso si no está sonando el timbre, si crees que la precisión del audio espacial no es buena."; -"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento dinámico de la cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames le indican a Soundscape la dirección en la que estás mirando. Esto le ayuda a Soundscape a mejorar tu experiencia de audio haciendo que sea más natural a medida que te mueves por el mundo. Cuando uses Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que la aplicación funcione bien."; +"help.using_headsets.bose_frames.what" = "Soundscape admite audio espacial con seguimiento de cabeza al usar las versiones Alto o Rondo de Bose Frames. Cuando se conecten, los sensores de las Bose Frames le indicarán a Soundscape la dirección en la que está orientada tu cabeza. Esto le ayuda a Soundscape a mejorar tu experiencia de audio, haciéndola más natural a medida que te mueves por el mundo. Cuando usas Soundscape con las Bose Frames conectadas, no es necesario sostener el teléfono para que la aplicación funcione bien."; "whats_new.1_3_0.0.title" = "Compatibilidad con Bose Frames"; "whats_new.1_3_0.0.description" = "Ahora Soundscape admite seguimiento de cabeza con las versiones Alto o Rondo de Bose Frames. Cuando se conecten, tus Bose Frames indicarán a Soundscape hacia dónde estás mirando, lo que ayudará a Soundscape a mejorar tu experiencia de audio. Para conectar tus Bose Frames a Soundscape, ve a la opción \"Auriculares con seguimiento de cabeza\" en el menú de Soundscape."; "whats_new.1_3_0.1.description" = "Si vives en las áreas de Austin o San Antonio en Texas y deseas ayudarnos a probar una función en la que estamos trabajando con NaviLens, comuníquate con nosotros a través del botón \"Enviar comentarios\" del menú."; @@ -4447,14 +4447,14 @@ "troubleshooting.tile_server_url" = "URL del servidor de teselas"; "troubleshooting.tile_server_url.explanation" = "Este es el servidor del que Soundscape obtiene los datos de mapas. Normalmente no debes cambiar este a menos que estés desarrollando o probando Soundscape."; "route_detail.action.start_reversed_route.hint" = "Pulsa dos veces para iniciar esta ruta de regreso"; -"route_detail.reverse.error.title" = "Falla de ruta de regreso"; -"route_detail.action.start_reversed_route.disabled.hint" = "Añadir puntos antes de iniciar la ruta de regreso"; +"route_detail.reverse.error.title" = "Error al invertir la ruta"; +"route_detail.action.start_reversed_route.disabled.hint" = "Agregar puntos antes de iniciar la ruta de regreso"; "route_detail.reverse.error.message" = "Se ha producido un error al intentar invertir la ruta. Inténtalo de nuevo."; "routes.reverse_name_format" = "%@ de regreso"; "route_detail.action.start_reversed_route" = "Iniciar ruta de regreso"; -"faq.tip.reverse_route" = "Cuando seleccionas \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden de regreso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; +"faq.tip.reverse_route" = "Cuando selecciones \"Iniciar ruta de regreso\" en la pantalla \"Detalles de la ruta\", será más fácil tomar una ruta de regreso, y se guardará una copia de la ruta con los puntos en orden inverso. Ten en cuenta que \"Iniciar ruta de regreso\" no guardará otra copia de la ruta ya guardada."; "help.text.routes.content.how.1a" = "Seguimiento de una ruta:
selecciona tu ruta en la página \"Marcadores y rutas\" y, a continuación, \"Iniciar ruta\". Volverás a la pantalla de inicio y Soundscape establecerá una señal en el primer punto de ruta. A medida que vayas por la ruta, la señal avanzará al siguiente punto hasta completar la ruta. Si en cualquier momento deseas saltar hacia delante o hacia atrás un punto de ruta, pulsa en \"Siguiente punto de ruta\" o \"Punto de ruta anterior\"."; -"location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o iniciar una señal de audio según qué tan cerca esté esta ubicación"; +"location_detail.action.beacon_or_navilens.hint" = "Pulsa dos veces para iniciar NaviLens o establecer una señal de audio según qué tan cerca esté esta ubicación"; "beacon.suggest_navilens" = "Usa el botón NaviLens para llegar a tu destino."; "location_detail.action.beacon_or_navilens" = "Iniciar NaviLens o señal de audio"; "filter.navilens" = "Códigos NaviLens"; diff --git a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings index c170e488d..e10139546 100644 --- a/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/fa-IR.lproj/Localizable.strings @@ -2483,3 +2483,8 @@ + + + + + diff --git a/apps/ios/GuideDogs/Assets/Localization/fi-FI.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/fi-FI.lproj/Localizable.strings index 840f33418..787957c27 100644 --- a/apps/ios/GuideDogs/Assets/Localization/fi-FI.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/fi-FI.lproj/Localizable.strings @@ -4131,7 +4131,7 @@ /* */ -"faq.when_to_use_soundscape.answer" = "Soundscapella on ominaisuuksia ja hyötyjä monissa erilaisissa skenaarioissa ja aikajaksoilla. Kokemasi Soundscapen hyödyllisyys voi myös kehittyä ajan myötä, joten saatat käyttää sitä tänään eri tavalla kuin kolmen kuukauden päästä. Sovelluksista ajatellaan usein: \"Minkä ongelman tämä sovellus ratkaisee hyvin?\" Soundscapea voidaan käyttää tapauskohtaisesti erityisten tietotarpeiden täyttämiseen, kuten päämäärän seurantaan matkalla sinne, suunnistamisen helpottamiseen metroasemalta poistuttaessa, sijainnin ymmärtämiseen autosta poistuttaessa tai seuraavan risteyksen kadunnimien tai etäisyyden selvittämiseen. Soundscapen filosofia on kuitenkin \"valaisee maailmasi äänellä\", ja se on suunniteltu käytettäväksi joka kerta, kun olet ulkona tarjoamaan tietoisuutta ympäristöstä, kuten pysymään ajan tasalla kaduista, joilla liikut, kulkusuunnastasi ja niiden yritysten nimistä, joiden ohi kävelet. Käyttäjämme ovat kutsuneet Soundscapea tässä käyttötilassa \"kivaksi seuralaissovellukseksi\", joka tukee \"intuitiivista näkemystä\" \"mielikuvakartan aukkojen täyttämisestä\" ja tarjoaa parempaa \"itseluottamusta kävellessä\". Tässä on lisää esimerkintöjä siitä, kuinka käyttäjämme sisällyttävät Soundscapen elämäänsä:\n\n\"Soundscape auttoi minut takaisin oikealle reitille, kun poistuin linja-autosta ja lähdin väärään suuntaan.\"\n\n\Jopa kaupungissa, jossa olen asunut kolme vuotta, olen rakentanut paremman kuvan siitä, mitä ympärilläni on [Soundscapen avulla].\"\n\n\"3D-ääni parantaa kävelykokemustani, koska tunnen olevani paremmassa yhteydessä ympäristööni…kokeilen todennäköisemmin uutta reittiä, kun sovellus on käytössäni.\"\n\n\"Kaipaan intuitiivista kokemusta ympäriinsä kävelystä ja asioiden huomaamisesta. Soundscapen käyttö on mukavaa, sillä ympäristöni asioista kuuleminen on vaivatonta. Tiedot suhteista ovat hyödyllisiä ja se on mahtava sovellus ympäristötietoisuuden kehittämiseksi ja kauppakäytävien tutkimiseen.\"\n\n\"[Käytin Soundscapea] löytääkseni pubin keskellä Yorkia. [Käytin] useita sovelluksen toimintoja selvittääkseni ensin sen sijainnin ja sitten löytääkseni sen. Sovellus toi minut kolmen metrin päähän ovesta, upeaa!\""; +"faq.when_to_use_soundscape.answer" = "Soundscapella on ominaisuuksia ja hyötyjä monissa erilaisissa skenaarioissa ja aikajaksoilla. Kokemasi Soundscapen hyödyllisyys voi myös kehittyä ajan myötä, joten saatat käyttää sitä tänään eri tavalla kuin kolmen kuukauden päästä. Sovelluksista ajatellaan usein: \"Minkä ongelman tämä sovellus ratkaisee hyvin?\" Soundscapea voidaan käyttää tapauskohtaisesti erityisten tietotarpeiden täyttämiseen, kuten päämäärän seurantaan matkalla sinne, suunnistamisen helpottamiseen metroasemalta poistuttaessa, sijainnin ymmärtämiseen autosta poistuttaessa tai seuraavan risteyksen kadunnimien tai etäisyyden selvittämiseen. Soundscapen filosofia on kuitenkin \"valaisee maailmasi äänellä\", ja se on suunniteltu käytettäväksi joka kerta, kun olet ulkona tarjoamaan tietoisuutta ympäristöstä, kuten pysymään ajan tasalla kaduista, joilla liikut, kulkusuunnastasi ja niiden yritysten nimistä, joiden ohi kävelet. Käyttäjämme ovat kutsuneet Soundscapea tässä käyttötilassa \"kivaksi seuralaissovellukseksi\", joka tukee \"intuitiivista näkemystä\" \"mielikuvakartan aukkojen täyttämisestä\" ja tarjoaa parempaa \"itseluottamusta kävellessä\". Tässä on lisää esimerkintöjä siitä, kuinka käyttäjämme sisällyttävät Soundscapen elämäänsä:\n\n\"Soundscape auttoi minut takaisin oikealle reitille, kun poistuin linja-autosta ja lähdin väärään suuntaan.\"\n\nJopa kaupungissa, jossa olen asunut kolme vuotta, olen rakentanut paremman kuvan siitä, mitä ympärilläni on [Soundscapen avulla].\"\n\n\"3D-ääni parantaa kävelykokemustani, koska tunnen olevani paremmassa yhteydessä ympäristööni…kokeilen todennäköisemmin uutta reittiä, kun sovellus on käytössäni.\"\n\n\"Kaipaan intuitiivista kokemusta ympäriinsä kävelystä ja asioiden huomaamisesta. Soundscapen käyttö on mukavaa, sillä ympäristöni asioista kuuleminen on vaivatonta. Tiedot suhteista ovat hyödyllisiä ja se on mahtava sovellus ympäristötietoisuuden kehittämiseksi ja kauppakäytävien tutkimiseen.\"\n\n\"[Käytin Soundscapea] löytääkseni pubin keskellä Yorkia. [Käytin] useita sovelluksen toimintoja selvittääkseni ensin sen sijainnin ja sitten löytääkseni sen. Sovellus toi minut kolmen metrin päähän ovesta, upeaa!\""; /* */ diff --git a/apps/ios/GuideDogs/Assets/Localization/nl-NL.lproj/Localizable.strings b/apps/ios/GuideDogs/Assets/Localization/nl-NL.lproj/Localizable.strings index ca15fd969..0ab5e416f 100644 --- a/apps/ios/GuideDogs/Assets/Localization/nl-NL.lproj/Localizable.strings +++ b/apps/ios/GuideDogs/Assets/Localization/nl-NL.lproj/Localizable.strings @@ -4131,7 +4131,7 @@ /* */ -"faq.when_to_use_soundscape.answer" = "Soundscape heeft voorzieningen en voordelen voor allerlei verschillende scenario’s en momenten. Bovendien kan de waarde van Soundscape voor u in de loop der tijd veranderen doordat u het over drie maanden misschien anders gebruikt dan nu. Mensen proberen vaak te bedenken \"waarvoor kan deze app goed worden gebruikt?\" U kunt Soundscape incidenteel gebruiken, wanneer u specifieke informatie zoekt, zoals het bijhouden van de voortgang naar uw bestemming, voor oriëntatie als u uit de metro komt, het bepalen van uw positie wanneer u uit de auto stapt, het zoeken naar straatnamen of het bepalen van de afstand tot het volgende kruispunt. Soundscape is echter gebaseerd op de filosofie \"de wereld verlichten met geluid \", en ontworpen voor wanneer u onderweg bent, om u meer bewust te maken van uw omgeving, zoals de namen van de straat waarin u loopt, de richting waarin u gaat en de namen van de bedrijven die u passeert. Gebruikers beschrijven deze toepassing van Soundscape als volgt: \"fijne companion-app\" met \"meerwaarde\", om \"lacunes op te vullen in mijn mentale voorstelling\" en om met \"extra zelfvertrouwen te lopen\". Hier zijn nog een paar voorbeelden van hoe gebruikers Soundscape toepassen:\n\n\"Soundscape hielp me om de juiste route terug te vinden toen ik na het uitstappen uit de bus de verkeerde kant op liep.\\n\n\Zelfs in de stad waar ik al 3 jaar woon, heb ik [met Soundscape] een beter beeld gekregen van wat er Om me heen is.\\n\n\Het 3D-geluid geeft een betere beleving bij het lopen en ik voel meer verbinding met mijn omgeving… Ik zal met deze app nu eerder een nieuwe route uitproberen.\\n\n\Als je gewoon rondloopt, weet je veel dingen niet en mis je van alles. Met Soundscape hoef je geen moeite te doen om van alles te horen over je omgeving. De relationele informatie is nuttig en het is een geweldige app om je bewust te worden van je situatie en het ontdekken van winkelstraten.\"\n\n\"[Ik heb Soundscape gebruikt] om een pub te zoeken midden in York. Met allerlei opties heb ik eerst de pub geselecteerd en daarna de route gevolgd. De app bracht me tot 3 meter voor de deur. Geweldig!\""; +"faq.when_to_use_soundscape.answer" = "Soundscape heeft voorzieningen en voordelen voor allerlei verschillende scenario’s en momenten. Bovendien kan de waarde van Soundscape voor u in de loop der tijd veranderen doordat u het over drie maanden misschien anders gebruikt dan nu. Mensen proberen vaak te bedenken \"waarvoor kan deze app goed worden gebruikt?\" U kunt Soundscape incidenteel gebruiken, wanneer u specifieke informatie zoekt, zoals het bijhouden van de voortgang naar uw bestemming, voor oriëntatie als u uit de metro komt, het bepalen van uw positie wanneer u uit de auto stapt, het zoeken naar straatnamen of het bepalen van de afstand tot het volgende kruispunt. Soundscape is echter gebaseerd op de filosofie \"de wereld verlichten met geluid \", en ontworpen voor wanneer u onderweg bent, om u meer bewust te maken van uw omgeving, zoals de namen van de straat waarin u loopt, de richting waarin u gaat en de namen van de bedrijven die u passeert. Gebruikers beschrijven deze toepassing van Soundscape als volgt: \"fijne companion-app\" met \"meerwaarde\", om \"lacunes op te vullen in mijn mentale voorstelling\" en om met \"extra zelfvertrouwen te lopen\". Hier zijn nog een paar voorbeelden van hoe gebruikers Soundscape toepassen:\n\n\"Soundscape hielp me om de juiste route terug te vinden toen ik na het uitstappen uit de bus de verkeerde kant op liep.\\n\nZelfs in de stad waar ik al 3 jaar woon, heb ik [met Soundscape] een beter beeld gekregen van wat er Om me heen is.\\n\nHet 3D-geluid geeft een betere beleving bij het lopen en ik voel meer verbinding met mijn omgeving… Ik zal met deze app nu eerder een nieuwe route uitproberen.\\n\nAls je gewoon rondloopt, weet je veel dingen niet en mis je van alles. Met Soundscape hoef je geen moeite te doen om van alles te horen over je omgeving. De relationele informatie is nuttig en het is een geweldige app om je bewust te worden van je situatie en het ontdekken van winkelstraten.\"\n\n\"[Ik heb Soundscape gebruikt] om een pub te zoeken midden in York. Met allerlei opties heb ik eerst de pub geselecteerd en daarna de route gevolgd. De app bracht me tot 3 meter voor de deur. Geweldig!\""; /* */ From 38a117a786ca98a8e49350c9765d9da474f42529 Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Thu, 12 Mar 2026 12:54:23 -0400 Subject: [PATCH 75/76] Redundant Language Header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed the Language screen localization key from settings.language.screen_title to settings.language.screen_title.2. This makes the top heading use “Language & Region” instead of the redundant “Language.” --- apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard index ebc77e8fb..506dc4c9f 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard @@ -1065,7 +1065,7 @@ - + From 9526c5b2caa47e8c1eeaeb40a2197f9035f47293 Mon Sep 17 00:00:00 2001 From: MBtheOtaku Date: Fri, 13 Mar 2026 16:44:55 -0400 Subject: [PATCH 76/76] Reverted back to old version --- apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard index 19076f80b..986e696b5 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/Settings.storyboard @@ -36,7 +36,7 @@ - +