Skip to content

Commit

Permalink
"Enter Vicinity Distance" setting
Browse files Browse the repository at this point in the history
Adds a setting to configure the distance threshold for stopping beacon audio.

Fixes #78
  • Loading branch information
steinbro committed Aug 11, 2024
1 parent efcfa26 commit 153a8c3
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 6 deletions.
4 changes: 4 additions & 0 deletions apps/ios/GuideDogs.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@
B9EE98081E3656B7007ADBED /* UIDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9EE98071E3656B7007ADBED /* UIDeviceManager.swift */; };
B9F0F96B1E10A40700F32F70 /* BaseTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F0F96A1E10A40700F32F70 /* BaseTableViewController.swift */; };
B9F749A21F16153900DC10C6 /* CoreLocation+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9F749A11F16153900DC10C6 /* CoreLocation+Extensions.swift */; };
BDA963AE2C69483300261EF2 /* SettingStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA963AD2C69483300261EF2 /* SettingStepper.swift */; };
C3060705205C544E00C39489 /* AddressGeocoderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3060704205C544E00C39489 /* AddressGeocoderProtocol.swift */; };
C306DF8522F0D71300248E9F /* CompoundFilterPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C306DF8422F0D71300248E9F /* CompoundFilterPredicate.swift */; };
C30DBD2023A2C19400082B27 /* SearchResultsUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30DBD1F23A2C19400082B27 /* SearchResultsUpdater.swift */; };
Expand Down Expand Up @@ -1646,6 +1647,7 @@
B9EE98071E3656B7007ADBED /* UIDeviceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UIDeviceManager.swift; path = Code/Devices/UIDeviceManager.swift; sourceTree = "<group>"; };
B9F0F96A1E10A40700F32F70 /* BaseTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BaseTableViewController.swift; path = "Code/Visual UI/View Controllers/BaseTableViewController.swift"; sourceTree = "<group>"; };
B9F749A11F16153900DC10C6 /* CoreLocation+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "CoreLocation+Extensions.swift"; path = "Code/App/Framework Extensions/Geo Extensions/CoreLocation+Extensions.swift"; sourceTree = "<group>"; };
BDA963AD2C69483300261EF2 /* SettingStepper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingStepper.swift; sourceTree = "<group>"; };
C3060704205C544E00C39489 /* AddressGeocoderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AddressGeocoderProtocol.swift; path = Code/Generators/Geocoding/Protocols/AddressGeocoderProtocol.swift; sourceTree = "<group>"; };
C306DF8422F0D71300248E9F /* CompoundFilterPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CompoundFilterPredicate.swift; path = Code/Data/Models/Helpers/Filter/CompoundFilterPredicate.swift; sourceTree = "<group>"; };
C30DBD1F23A2C19400082B27 /* SearchResultsUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsUpdater.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2603,6 +2605,7 @@
2896378326D7099B001694C0 /* Beacon */ = {
isa = PBXGroup;
children = (
BDA963AD2C69483300261EF2 /* SettingStepper.swift */,
2832D36526D54DE60052EE47 /* BeaconSelectionView.swift */,
2832D36726D54E0B0052EE47 /* BeaconSelectionHostViewController.swift */,
2896378826D70D3F001694C0 /* BeaconOptionCell.swift */,
Expand Down Expand Up @@ -5718,6 +5721,7 @@
62CE14CF25C0DEC3001CBC0B /* HeadphoneCalibration.swift in Sources */,
C37E33D52368DBA60033D640 /* NotificationManager.swift in Sources */,
C317F26523722ECF000579BA /* NotificationObserver.swift in Sources */,
BDA963AE2C69483300261EF2 /* SettingStepper.swift in Sources */,
C317F26923722F1A000579BA /* NotificationObserverDelegate.swift in Sources */,
62B11A3727ACAAC50094FE66 /* RoundedBackground.swift in Sources */,
C37E33C423677EC00033D640 /* AlertType.swift in Sources */,
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,10 @@
/* Title of the settings screen for beacons. This screen allows users to configure the way the audio beacon sounds. See Terms for the definition of "beacon". */
"beacon.settings_title" = "Beacon Settings";


/* Title of a section in the beacon settings page where the user can select the distance threshold when a beacon automatically stops playing. */
"beacon.settings.vicinity" = "Enter Vicinity Distance";

/* Title of a section in the beacon settings page where the user can select a style for their beacon. The various styles mainly differ in the sounds that are played for the beacon, though there are two styles that include some haptics as well. */
"beacon.settings.style" = "Audio Styles";

Expand Down
28 changes: 25 additions & 3 deletions apps/ios/GuideDogs/Code/App/Settings/SettingsContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation
import AVFoundation
import CoreLocation

extension Notification.Name {
static let automaticCalloutsEnabledChanged = Notification.Name("GDAAutomaticCalloutsChanged")
Expand Down Expand Up @@ -53,6 +54,8 @@ class SettingsContext {
fileprivate static let previewIntersectionsIncludeUnnamedRoads = "GDASettingsPreviewIntersectionsIncludeUnnamedRoads"
fileprivate static let audioSessionMixesWithOthers = "GDAAudioSessionMixesWithOthers"
fileprivate static let markerSortStyle = "GDAMarkerSortStyle"
fileprivate static let leaveImmediateVicinityDistance = "GDALeaveImmediateVicinityDistance"
fileprivate static let enterImmediateVicinityDistance = "GDAEnterImmediateVicinityDistance"

fileprivate static let ttsGain = "GDATTSAudioGain"
fileprivate static let beaconGain = "GDABeaconAudioGain"
Expand Down Expand Up @@ -102,7 +105,9 @@ class SettingsContext {
Keys.senseDestination: true,
Keys.previewIntersectionsIncludeUnnamedRoads: false,
Keys.audioSessionMixesWithOthers: true,
Keys.markerSortStyle: SortStyle.distance.rawValue
Keys.markerSortStyle: SortStyle.distance.rawValue,
Keys.leaveImmediateVicinityDistance: 30.0,
Keys.enterImmediateVicinityDistance: 15.0
])

resetLocaleIfNeeded()
Expand All @@ -117,7 +122,7 @@ class SettingsContext {
}

// MARK: Properties

var appUseCount: Int {
get {
return userDefaults.integer(forKey: Keys.appUseCount)
Expand Down Expand Up @@ -315,7 +320,7 @@ class SettingsContext {
}

// MARK: Push Notifications

var apnsDeviceToken: Data? {
get {
return userDefaults.data(forKey: Keys.apnsDeviceToken)
Expand Down Expand Up @@ -366,6 +371,23 @@ class SettingsContext {
}
}

var leaveImmediateVicinityDistance: CLLocationDistance {
get {
return userDefaults.double(forKey: Keys.leaveImmediateVicinityDistance) as CLLocationDistance
}
set {
userDefaults.set(newValue, forKey: Keys.leaveImmediateVicinityDistance)
}
}

var enterImmediateVicinityDistance: CLLocationDistance {
get {
return userDefaults.double(forKey: Keys.enterImmediateVicinityDistance) as CLLocationDistance
}
set {
userDefaults.set(newValue, forKey: Keys.enterImmediateVicinityDistance)
}
}
}

extension SettingsContext: AutoCalloutSettingsProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ enum DestinationManagerError: Error {

class DestinationManager: DestinationManagerProtocol {

static let LeaveImmediateVicinityDistance: CLLocationDistance = 30.0
static let EnterImmediateVicinityDistance: CLLocationDistance = 15.0
static let LeaveImmediateVicinityDistance: CLLocationDistance = SettingsContext.shared.leaveImmediateVicinityDistance
static let EnterImmediateVicinityDistance: CLLocationDistance = SettingsContext.shared.enterImmediateVicinityDistance

// MARK: Notification Keys

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ struct BeaconSelectionView: View {
@State var isPresented: Bool = false
@State var selectedBeaconKey: String
@State var areMelodiesEnabled: Bool
@State var enterImmediateVicinityDistance: Double

let initialBeacon: String
let initialMelodies: Bool

init() {
_selectedBeaconKey = State(initialValue: SettingsContext.shared.selectedBeacon)
_areMelodiesEnabled = State(initialValue: SettingsContext.shared.playBeaconStartAndEndMelodies)
_enterImmediateVicinityDistance = State(initialValue: SettingsContext.shared.enterImmediateVicinityDistance)
initialBeacon = SettingsContext.shared.selectedBeacon
initialMelodies = SettingsContext.shared.playBeaconStartAndEndMelodies
}
Expand Down Expand Up @@ -52,7 +54,20 @@ struct BeaconSelectionView: View {
SettingsContext.shared.playBeaconStartAndEndMelodies = areMelodiesEnabled
beaconDemo.play(styleChanged: true)
})


TableHeaderCell(text: GDLocalizedString("beacon.settings.vicinity"))

SettingStepper(
value: $enterImmediateVicinityDistance,
unitsLocalization: "distance.format.meters",
stepSize: 5.0,
minValue: 5.0,
maxValue: 50.0
)
.onChange(of: enterImmediateVicinityDistance, perform: { _ in
SettingsContext.shared.enterImmediateVicinityDistance = enterImmediateVicinityDistance
})

TableHeaderCell(text: GDLocalizedString("beacon.settings.style"))

ForEach(BeaconOption.allAvailableCases(for: .standard)) { details in
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// SettingStepper.swift
// Soundscape
//
// Created by Daniel W. Steinbrook on 8/11/24.
// Copyright © 2024 Soundscape community. All rights reserved.
//

import SwiftUI

/// Defines a stepper (increment/decrement buttons) that can be used for settings like Enter Vicinity Distance.
/// Takes a step size, min, max, and localization key for printing the value with units..
/// `unitsLocalization` should be a localization key like "distance.format.meters".
struct SettingStepper: View {
@Binding var value: Double
private let unitsLocalization: String
private let stepSize: Double
private let minValue: Double
private let maxValue: Double

init(value: Binding<Double>, unitsLocalization: String, stepSize: Double, minValue: Double, maxValue: Double) {
self._value = value
self.unitsLocalization = unitsLocalization
self.stepSize = stepSize
self.minValue = minValue
self.maxValue = maxValue
}

// Increment and Decrement actions
private func increment() {
let newValue = value + stepSize
value = min(max(newValue, minValue), maxValue)
}

private func decrement() {
let newValue = value - stepSize
value = min(max(newValue, minValue), maxValue)
}

var body: some View {
VStack {
Stepper(
onIncrement: increment,
onDecrement: decrement
) {
// truncate `value` at the decimal point
Text(GDLocalizedString(unitsLocalization, String(format: "%.0f", value)))
.foregroundColor(.primaryForeground)
.font(.body)
.lineLimit(nil)
}
.padding()
.background(Color.primaryBackground)
}
}
}

0 comments on commit 153a8c3

Please sign in to comment.