allow users to set live location minimum distance update
This commit is contained in:
@@ -66,6 +66,7 @@ final class AppSettings {
|
||||
|
||||
case voiceMessagePlaybackSpeed
|
||||
case liveLocationSharingTimeoutDatesByRoomID
|
||||
case liveLocationMinimumDistanceUpdate
|
||||
|
||||
// Feature flags
|
||||
case publicSearchEnabled
|
||||
@@ -349,6 +350,9 @@ final class AppSettings {
|
||||
@UserPreference(key: UserDefaultsKeys.liveLocationSharingTimeoutDatesByRoomID, defaultValue: [String: Date](), storageType: .userDefaults(store))
|
||||
var liveLocationSharingTimeoutDatesByRoomID
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.liveLocationMinimumDistanceUpdate, defaultValue: 10, storageType: .userDefaults(store))
|
||||
var liveLocationMinimumDistanceUpdate
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.frequentlyUsedSystemEmojis, defaultValue: [FrequentlyUsedEmoji](), storageType: .userDefaults(store))
|
||||
var frequentlyUsedSystemEmojis
|
||||
|
||||
|
||||
@@ -2199,6 +2199,11 @@ class CLLocationManagerMock: CLLocationManagerProtocol, @unchecked Sendable {
|
||||
set(value) { underlyingDesiredAccuracy = value }
|
||||
}
|
||||
var underlyingDesiredAccuracy: CLLocationAccuracy!
|
||||
var distanceFilter: CLLocationDistance {
|
||||
get { return underlyingDistanceFilter }
|
||||
set(value) { underlyingDistanceFilter = value }
|
||||
}
|
||||
var underlyingDistanceFilter: CLLocationDistance!
|
||||
var pausesLocationUpdatesAutomatically: Bool {
|
||||
get { return underlyingPausesLocationUpdatesAutomatically }
|
||||
set(value) { underlyingPausesLocationUpdatesAutomatically = value }
|
||||
|
||||
@@ -7,12 +7,30 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
struct AdvancedSettingsScreenViewState: BindableState {
|
||||
init(timelineMediaVisibility: TimelineMediaVisibility, hideInviteAvatars: Bool, isWaitingTimelineMediaVisibility: Bool = false, isWaitingHideInviteAvatars: Bool = false, bindings: AdvancedSettingsScreenViewStateBindings) {
|
||||
self.timelineMediaVisibility = timelineMediaVisibility
|
||||
self.hideInviteAvatars = hideInviteAvatars
|
||||
self.isWaitingTimelineMediaVisibility = isWaitingTimelineMediaVisibility
|
||||
self.isWaitingHideInviteAvatars = isWaitingHideInviteAvatars
|
||||
self.bindings = bindings
|
||||
|
||||
let linkPlaceholder = "{link}"
|
||||
var footerString = AttributedString(L10n.screenAdvancedSettingsLiveLocationSectionFooter(linkPlaceholder))
|
||||
var linkString = AttributedString(L10n.screenAdvancedSettingsLiveLocationSectionFooterLink)
|
||||
linkString.link = URL(string: UIApplication.openSettingsURLString)
|
||||
linkString.bold()
|
||||
footerString.replace(linkPlaceholder, with: linkString)
|
||||
liveLocationUpdateFooterAttributedString = footerString
|
||||
}
|
||||
|
||||
let liveLocationUpdateFooterAttributedString: AttributedString
|
||||
var timelineMediaVisibility: TimelineMediaVisibility
|
||||
var hideInviteAvatars: Bool
|
||||
var isWaitingTimelineMediaVisibility = false
|
||||
var isWaitingHideInviteAvatars = false
|
||||
var isWaitingTimelineMediaVisibility: Bool
|
||||
var isWaitingHideInviteAvatars: Bool
|
||||
var bindings: AdvancedSettingsScreenViewStateBindings
|
||||
}
|
||||
|
||||
@@ -42,6 +60,7 @@ protocol AdvancedSettingsProtocol: AnyObject {
|
||||
var appAppearance: AppAppearance { get set }
|
||||
var sharePresence: Bool { get set }
|
||||
var optimizeMediaUploads: Bool { get set }
|
||||
var liveLocationMinimumDistanceUpdate: Int { get set }
|
||||
}
|
||||
|
||||
extension AppSettings: AdvancedSettingsProtocol { }
|
||||
|
||||
@@ -37,6 +37,7 @@ struct AdvancedSettingsScreen: View {
|
||||
|
||||
moderationAndSafetySection
|
||||
timelineMediaSection
|
||||
liveLocationSection
|
||||
}
|
||||
.compoundList()
|
||||
.navigationTitle(L10n.commonAdvancedSettings)
|
||||
@@ -84,6 +85,30 @@ struct AdvancedSettingsScreen: View {
|
||||
.compoundListSectionFooter()
|
||||
}
|
||||
}
|
||||
|
||||
private var liveLocationSection: some View {
|
||||
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)
|
||||
})
|
||||
} header: {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(L10n.screenAdvancedSettingsLiveLocationSectionTitle)
|
||||
.compoundListSectionHeader()
|
||||
Text(L10n.screenAdvancedSettingsLiveLocationSectionDescription)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundStyle(.compound.textSecondary)
|
||||
}
|
||||
} footer: {
|
||||
Text(context.viewState.liveLocationUpdateFooterAttributedString)
|
||||
.compoundListSectionFooter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension AppAppearance {
|
||||
|
||||
@@ -12,6 +12,7 @@ protocol CLLocationManagerProtocol: AnyObject {
|
||||
var delegate: CLLocationManagerDelegate? { get set }
|
||||
var allowsBackgroundLocationUpdates: Bool { get set }
|
||||
var desiredAccuracy: CLLocationAccuracy { get set }
|
||||
var distanceFilter: CLLocationDistance { get set }
|
||||
var pausesLocationUpdatesAutomatically: Bool { get set }
|
||||
var authorizationStatus: CLAuthorizationStatus { get }
|
||||
|
||||
|
||||
@@ -47,9 +47,8 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
||||
|
||||
self.locationManager.delegate = self
|
||||
self.locationManager.allowsBackgroundLocationUpdates = true
|
||||
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
||||
self.locationManager.pausesLocationUpdatesAutomatically = false
|
||||
|
||||
setupMinumDistance(appSettings.liveLocationMinimumDistanceUpdate)
|
||||
setupSubscriptions()
|
||||
}
|
||||
|
||||
@@ -162,6 +161,27 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
||||
locationUpdatesTask = nil
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
appSettings.$liveLocationMinimumDistanceUpdate
|
||||
.removeDuplicates()
|
||||
.debounce(for: .seconds(3), scheduler: DispatchQueue.main)
|
||||
.sink { [weak self] minimumDistance in
|
||||
self?.setupMinumDistance(minimumDistance)
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
/// Sets up the distance filter and the most optimal accuracy given the minimum distance to save battery,
|
||||
private func setupMinumDistance(_ minimumDistance: Int) {
|
||||
switch minimumDistance {
|
||||
case 0..<10:
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
||||
case 10..<100:
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
||||
default:
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
||||
}
|
||||
locationManager.distanceFilter = CLLocationDistance(minimumDistance)
|
||||
}
|
||||
|
||||
private func syncActiveRoomProxies(with sessions: [String: Date]) {
|
||||
|
||||
Reference in New Issue
Block a user