diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict b/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict index 557d0ff11..bfada7844 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.stringsdict @@ -283,9 +283,9 @@ NSStringFormatValueTypeKey d one - %1$d meter + Every %1$d meter other - %1$d meters + Every %1$d meters NSStringLocalizedFormatKey %#@COUNT@ diff --git a/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/AdvancedSettingsScreenModels.swift b/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/AdvancedSettingsScreenModels.swift index 5dc19d436..8273bdc08 100644 --- a/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/AdvancedSettingsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/AdvancedSettingsScreenModels.swift @@ -61,6 +61,7 @@ protocol AdvancedSettingsProtocol: AnyObject { var sharePresence: Bool { get set } var optimizeMediaUploads: Bool { get set } var liveLocationMinimumDistanceUpdate: Int { get set } + var liveLocationSharingEnabled: Bool { get set } } extension AppSettings: AdvancedSettingsProtocol { } diff --git a/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/View/AdvancedSettingsScreen.swift b/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/View/AdvancedSettingsScreen.swift index 690022131..f2ab8e17f 100644 --- a/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/View/AdvancedSettingsScreen.swift +++ b/ElementX/Sources/Screens/Settings/AdvancedSettingsScreen/View/AdvancedSettingsScreen.swift @@ -10,6 +10,13 @@ import Compound import SwiftUI struct AdvancedSettingsScreen: View { + static let measurementFormatter = { + let formatter = MeasurementFormatter() + formatter.unitOptions = .providedUnit + formatter.unitStyle = .short + return formatter + }() + @Bindable var context: AdvancedSettingsScreenViewModel.Context var body: some View { @@ -37,7 +44,9 @@ struct AdvancedSettingsScreen: View { moderationAndSafetySection timelineMediaSection - liveLocationSection + if context.liveLocationSharingEnabled { + liveLocationSection + } } .compoundList() .navigationTitle(L10n.commonAdvancedSettings) @@ -86,15 +95,41 @@ struct AdvancedSettingsScreen: View { } } + @ViewBuilder private var liveLocationSection: some View { + let binding = Binding(get: { + Double(context.liveLocationMinimumDistanceUpdate) + }, set: { newValue in + context.liveLocationMinimumDistanceUpdate = Int(newValue) + }) + Section { ListRow(kind: .custom { - Stepper(L10n.screenAdvancedSettingsLiveLocationUpdateDistance(context.liveLocationMinimumDistanceUpdate), - value: $context.liveLocationMinimumDistanceUpdate, in: 1...100) - .font(.compound.bodyLG) - .foregroundStyle(.compound.textPrimary) - .padding(.horizontal, ListRowPadding.horizontal) - .padding(.vertical, ListRowPadding.vertical) + VStack(alignment: .leading, spacing: 0) { + Text(L10n.screenAdvancedSettingsLiveLocationUpdateDistance(context.liveLocationMinimumDistanceUpdate)) + .font(.compound.bodyLG) + .foregroundStyle(.compound.textPrimary) + // The internal hidden label of the slider will read voice over + .accessibilityHidden(true) + Slider(value: binding, in: 1...100) { + Text(L10n.screenAdvancedSettingsLiveLocationUpdateDistance(context.liveLocationMinimumDistanceUpdate)) + } minimumValueLabel: { + Text(Self.measurementFormatter.string(from: .init(value: 1, + unit: UnitLength.meters))) + .font(.compound.bodyLG) + .foregroundStyle(.compound.textSecondary) + .padding(.trailing, 15) + } maximumValueLabel: { + Text(Self.measurementFormatter.string(from: .init(value: 100, + unit: UnitLength.meters))) + .font(.compound.bodyLG) + .foregroundStyle(.compound.textSecondary) + .padding(.leading, 15) + } + .tint(.compound.iconAccentPrimary) + } + .padding(.horizontal, ListRowPadding.horizontal) + .padding(.vertical, ListRowPadding.vertical) }) } header: { VStack(alignment: .leading, spacing: 4) { @@ -127,10 +162,16 @@ private extension AppAppearance { // MARK: - Previews struct AdvancedSettingsScreen_Previews: PreviewProvider, TestablePreview { - static let viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings, - analytics: ServiceLocator.shared.analytics, - clientProxy: ClientProxyMock(.init()), - userIndicatorController: UserIndicatorControllerMock()) + static let viewModel = { + AppSettings.resetAllSettings() + let appSettings = AppSettings() + appSettings.liveLocationSharingEnabled = true + return AdvancedSettingsScreenViewModel(advancedSettings: appSettings, + analytics: ServiceLocator.shared.analytics, + clientProxy: ClientProxyMock(.init()), + userIndicatorController: UserIndicatorControllerMock()) + }() + static var previews: some View { ElementNavigationStack { AdvancedSettingsScreen(context: viewModel.context) diff --git a/ElementX/Sources/Services/Location/LiveLocationManager.swift b/ElementX/Sources/Services/Location/LiveLocationManager.swift index 26ac4cf93..771a83e69 100644 --- a/ElementX/Sources/Services/Location/LiveLocationManager.swift +++ b/ElementX/Sources/Services/Location/LiveLocationManager.swift @@ -173,7 +173,7 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana appSettings.$liveLocationMinimumDistanceUpdate .removeDuplicates() - .debounce(for: .seconds(3), scheduler: DispatchQueue.main) + .debounce(for: .seconds(1), scheduler: DispatchQueue.main) .sink { [weak self] minimumDistance in self?.setupMinimumDistance(minimumDistance) } diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-en-GB-0.png index 1eeef47ce..9e9fa2dd7 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c30282bd1093590cb60fda722552305473fd3cacad999bed81044c2eccc9d57c -size 171794 +oid sha256:7cf54519ba66ea01ee0fbb2cac517ad99bdb0018409d6a70e66c5d6f383ecf8f +size 192815 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-pseudo-0.png index 23eaa7214..b45ec7546 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d02782eb9595efd43c2fff296316cae7b350ef8bb9d14aefabefcbef29f0da7 -size 211907 +oid sha256:5f9ebe7f8b2081eaa353a8c6cc491d9667e9d58785d792d05dceb1c6b499285c +size 241765 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPhone-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPhone-en-GB-0.png index 6cb504ec1..394ad6331 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPhone-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/advancedSettingsScreen.iPhone-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:497c7f492ee43082bb72ec58ff20353e72d33be936b66ff9478eda5b653332a0 -size 125423 +oid sha256:0727ef553dcdd695436b11d8f167d035636678dddeaf55326b23ed88060b0ec3 +size 136037