diff --git a/TraccarClient.xcodeproj/project.pbxproj b/TraccarClient.xcodeproj/project.pbxproj index 44dcceb4cb3ed422645cfaf7c2b460a054882711..923762f3512349c44457f7262d6583587b516cd9 100644 --- a/TraccarClient.xcodeproj/project.pbxproj +++ b/TraccarClient.xcodeproj/project.pbxproj @@ -106,6 +106,8 @@ 53554AE22AED1B480018BAEE /* ButtonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53554ADD2AED1B480018BAEE /* ButtonTableViewCell.swift */; }; 53554AE32AED1B480018BAEE /* KNButtonView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53554ADE2AED1B480018BAEE /* KNButtonView.xib */; }; 53554AE52AED1BF10018BAEE /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53554AE42AED1BF10018BAEE /* UIButton.swift */; }; + 536CAD372B7239BC00AAA15F /* SettingsResetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CAD352B7239BC00AAA15F /* SettingsResetTableViewCell.swift */; }; + 536CAD382B7239BC00AAA15F /* SettingsResetTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 536CAD362B7239BC00AAA15F /* SettingsResetTableViewCell.xib */; }; 5370B4702AEFB8A900AE08CC /* splash.json in Resources */ = {isa = PBXBuildFile; fileRef = 5370B46F2AEFB8A900AE08CC /* splash.json */; }; 5392C4232B037942004EF18A /* ShiftsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5392C4222B037942004EF18A /* ShiftsModel.swift */; }; 53A306212B0CA92900FAEA00 /* TrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A306202B0CA92900FAEA00 /* TrackingView.swift */; }; @@ -294,6 +296,8 @@ 53554ADD2AED1B480018BAEE /* ButtonTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonTableViewCell.swift; sourceTree = "<group>"; }; 53554ADE2AED1B480018BAEE /* KNButtonView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KNButtonView.xib; sourceTree = "<group>"; }; 53554AE42AED1BF10018BAEE /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; }; + 536CAD352B7239BC00AAA15F /* SettingsResetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsResetTableViewCell.swift; sourceTree = "<group>"; }; + 536CAD362B7239BC00AAA15F /* SettingsResetTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsResetTableViewCell.xib; sourceTree = "<group>"; }; 5370B46F2AEFB8A900AE08CC /* splash.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = splash.json; sourceTree = "<group>"; }; 5392C4222B037942004EF18A /* ShiftsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShiftsModel.swift; sourceTree = "<group>"; }; 53A306202B0CA92900FAEA00 /* TrackingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackingView.swift; sourceTree = "<group>"; }; @@ -730,6 +734,15 @@ path = Cell; sourceTree = "<group>"; }; + 536CAD342B7239A200AAA15F /* SettingsResetTableViewCell */ = { + isa = PBXGroup; + children = ( + 536CAD352B7239BC00AAA15F /* SettingsResetTableViewCell.swift */, + 536CAD362B7239BC00AAA15F /* SettingsResetTableViewCell.xib */, + ); + path = SettingsResetTableViewCell; + sourceTree = "<group>"; + }; 53A3061E2B0CA86D00FAEA00 /* ShiftsView */ = { isa = PBXGroup; children = ( @@ -778,6 +791,7 @@ 53EBC5FB2AF199E200601AA7 /* Cells */ = { isa = PBXGroup; children = ( + 536CAD342B7239A200AAA15F /* SettingsResetTableViewCell */, 53200CE52B5945F300D1445D /* SettingsPrivacyPolicyTableViewCell */, 53EBC60D2AF395EA00601AA7 /* SettingsLogoutTableViewCell */, 53EBC6082AF1A5A800601AA7 /* SettingsSegmentTableViewCell */, @@ -1069,6 +1083,7 @@ 53D62E402AEFA31200C80BAC /* InitialViewController.xib in Resources */, 5326833D2AE9175900A364C0 /* LoginViewController.xib in Resources */, CE5899C81B115C9100ED70D2 /* Images.xcassets in Resources */, + 536CAD382B7239BC00AAA15F /* SettingsResetTableViewCell.xib in Resources */, 5326835F2AE91A6F00A364C0 /* Montserrat-Black.ttf in Resources */, 53EBC5FF2AF199FF00601AA7 /* SettingsTextTableViewCell.xib in Resources */, 532683742AE923A500A364C0 /* KNTextFieldView.xib in Resources */, @@ -1173,6 +1188,7 @@ 532683AB2AE94BA500A364C0 /* UIView.swift in Sources */, 532FDC1B2B00BED500EDFC99 /* Network+Shifts.swift in Sources */, 5326839A2AE9482300A364C0 /* Network+Types.swift in Sources */, + 536CAD372B7239BC00AAA15F /* SettingsResetTableViewCell.swift in Sources */, CB4197991F67724F008F301C /* NetworkManager.swift in Sources */, 532683B32AE98D0000A364C0 /* UILabel.swift in Sources */, 5326838D2AE92D9900A364C0 /* CGFLoat.swift in Sources */, @@ -1362,10 +1378,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = Z7STA3KGEU; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -1384,6 +1400,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teams; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1406,7 +1423,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = HK8L8KQMEZ; + DEVELOPMENT_TEAM = Z7STA3KGEU; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1539,9 +1556,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 4; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 5; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = Z7STA3KGEU; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -1559,6 +1576,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teams; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1576,10 +1594,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = Z7STA3KGEU; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -1597,6 +1615,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teams; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1618,7 +1637,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = HK8L8KQMEZ; + DEVELOPMENT_TEAM = Z7STA3KGEU; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1660,7 +1679,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = HK8L8KQMEZ; + DEVELOPMENT_TEAM = Z7STA3KGEU; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate index 61c2f14815924865f064a0b5604f61c3570abeb3..952ea67c5c28428f9b52f6d5f0902a42c09e19ba 100644 Binary files a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TraccarClient.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/TraccarClient.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index b7e446a85998f4b098752db381a9dc7223ca9690..5e0af6ed2164476a5d793154de204bef86e03ecf 100644 --- a/TraccarClient.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/TraccarClient.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,22 +3,4 @@ uuid = "C69DA6DD-5592-40A4-92DB-D8BF97EDB011" type = "1" version = "2.0"> - <Breakpoints> - <BreakpointProxy - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> - <BreakpointContent - uuid = "AA2B4F9E-62D5-43E3-8D0D-3F2413C92F94" - shouldBeEnabled = "No" - ignoreCount = "0" - continueAfterRunningActions = "No" - filePath = "TraccarClient/ShiftsModel.swift" - startingColumnNumber = "9223372036854775807" - endingColumnNumber = "9223372036854775807" - startingLineNumber = "63" - endingLineNumber = "63" - landmarkName = "getStartTimeForToday(dayName:)" - landmarkType = "7"> - </BreakpointContent> - </BreakpointProxy> - </Breakpoints> </Bucket> diff --git a/TraccarClient/AppManager.swift b/TraccarClient/AppManager.swift index ecb4bead906c4349d62856ce4c5fa00515f0747d..c6b751cecf53048e4d88654cd0266c84a0f299e3 100644 --- a/TraccarClient/AppManager.swift +++ b/TraccarClient/AppManager.swift @@ -39,7 +39,7 @@ final class AppManager { ] // MARK: - Data - var environment: KNEnvironment = .production + var environment: KNEnvironment = .sandbox var delegate: AppDelegate! var isUpdatingProfile: Bool = false var isLoggedIn: Bool { diff --git a/TraccarClient/Images.xcassets/resetSettings.imageset/Contents.json b/TraccarClient/Images.xcassets/resetSettings.imageset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..acbf2335c990f9f491be37e6d8e0422dcb964306 --- /dev/null +++ b/TraccarClient/Images.xcassets/resetSettings.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "icons8-reset-30.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "icons8-reset-50.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icons8-reset-100.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-100.png b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-100.png new file mode 100644 index 0000000000000000000000000000000000000000..4101aff13da870df4f78031c5ae11c0f246310e7 Binary files /dev/null and b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-100.png differ diff --git a/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-30.png b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-30.png new file mode 100644 index 0000000000000000000000000000000000000000..2230e448f7a8bb89887aad2691e629fba89c2f62 Binary files /dev/null and b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-30.png differ diff --git a/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-50.png b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-50.png new file mode 100644 index 0000000000000000000000000000000000000000..b4906bb672b73d881a9de39464e5a23e5a6bc29d Binary files /dev/null and b/TraccarClient/Images.xcassets/resetSettings.imageset/icons8-reset-50.png differ diff --git a/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.swift b/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.swift new file mode 100644 index 0000000000000000000000000000000000000000..609b0e24c86ee68bfb8502a2cf98468b05ae06cd --- /dev/null +++ b/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.swift @@ -0,0 +1,37 @@ +// +// SettingsResetTableViewCell.swift +// TraccarClient +// +// Created by George Makhoul on 06/02/2024. +// Copyright © 2024 Traccar. All rights reserved. +// + +import UIKit +protocol SettingsResetTableViewCellDelegate { + func reset() +} + +class SettingsResetTableViewCell: UITableViewCell { + + @IBOutlet weak var iconImage: UIImageView! + @IBOutlet weak var titleLabel: UILabel! + + // MARK: - Properties + var delegate: SettingsResetTableViewCellDelegate? + + // MARK: - LifeCycle + override func awakeFromNib() { + super.awakeFromNib() + titleLabel.set(text: "", color: .main, font: .bold(16)) + iconImage.set(icon: .reset) + } + + @IBAction func logoutTapped(_ sender: UIButton) { + delegate?.reset() + } + + func set(title: String) { + titleLabel.set(text: title) + } + +} diff --git a/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.xib b/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.xib new file mode 100644 index 0000000000000000000000000000000000000000..04c6df2c143f2bee82728bc0d8a0a85dab4c9aa5 --- /dev/null +++ b/TraccarClient/SettingsViewController/Cells/SettingsResetTableViewCell/SettingsResetTableViewCell.xib @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_12" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="61" id="KGk-i7-Jjw" customClass="SettingsResetTableViewCell" customModule="TraccarClient" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="320" height="61"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM"> + <rect key="frame" x="0.0" y="0.0" width="320" height="61"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LAQ-b8-Ohc"> + <rect key="frame" x="16" y="11.666666666666664" width="38" height="38"/> + <constraints> + <constraint firstAttribute="height" constant="38" id="634-ms-ADd"/> + <constraint firstAttribute="width" constant="38" id="VHK-KO-Fhm"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l94-kv-jxP"> + <rect key="frame" x="70" y="12" width="234" height="37"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K7H-RJ-he1"> + <rect key="frame" x="0.0" y="0.0" width="320" height="61"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <connections> + <action selector="logoutTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="kt5-Ep-dMr"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstAttribute="trailing" secondItem="K7H-RJ-he1" secondAttribute="trailing" id="7AX-aC-cet"/> + <constraint firstItem="LAQ-b8-Ohc" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="7IG-sW-Jlk"/> + <constraint firstAttribute="bottom" secondItem="K7H-RJ-he1" secondAttribute="bottom" id="JmP-Zp-lr9"/> + <constraint firstAttribute="trailing" secondItem="l94-kv-jxP" secondAttribute="trailing" constant="16" id="KGR-nY-PhP"/> + <constraint firstItem="l94-kv-jxP" firstAttribute="leading" secondItem="LAQ-b8-Ohc" secondAttribute="trailing" constant="16" id="KfF-YG-UnD"/> + <constraint firstItem="K7H-RJ-he1" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="LvC-ZY-NZT"/> + <constraint firstItem="K7H-RJ-he1" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="MqB-JQ-LLH"/> + <constraint firstAttribute="bottom" secondItem="l94-kv-jxP" secondAttribute="bottom" constant="12" id="PjF-Vq-z7L"/> + <constraint firstItem="l94-kv-jxP" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="12" id="ho6-4I-Y0t"/> + <constraint firstItem="LAQ-b8-Ohc" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="r8b-6c-r2J"/> + </constraints> + </tableViewCellContentView> + <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> + <connections> + <outlet property="iconImage" destination="LAQ-b8-Ohc" id="5Df-H1-pod"/> + <outlet property="titleLabel" destination="l94-kv-jxP" id="MHa-5u-KV2"/> + </connections> + <point key="canvasLocation" x="13.740458015267174" y="26.408450704225352"/> + </tableViewCell> + </objects> +</document> diff --git a/TraccarClient/SettingsViewController/DefaultsModel.swift b/TraccarClient/SettingsViewController/DefaultsModel.swift index 57e302fa6bd3199708c09234759a7ea070a5f337..dbbcf797b9c981b33aa86a974b5fee0535e1a985 100644 --- a/TraccarClient/SettingsViewController/DefaultsModel.swift +++ b/TraccarClient/SettingsViewController/DefaultsModel.swift @@ -9,11 +9,28 @@ import Foundation import UIKit -struct DefaultsModel { - var title: String = "" - var value: Any? - var key: String = "" - var keyboardType: UIKeyboardType = .default +struct DefaultsModel: Equatable { + + var title: String = "" + var value: Any? + var key: String = "" + var keyboardType: UIKeyboardType = .default + + static func == (lhs: DefaultsModel, rhs: DefaultsModel) -> Bool { + guard lhs.title == rhs.title, + lhs.key == rhs.key else { + return false + } + + // Compare `value` property + switch (lhs.value, rhs.value) { + case let (lhs as String, rhs as String): + return lhs == rhs + case let (lhs as Bool, rhs as Bool): + return lhs == rhs + default: + return false + } } init() { @@ -24,6 +41,6 @@ struct DefaultsModel { self.value = value self.keyboardType = keyboardType self.key = key - + } } diff --git a/TraccarClient/SettingsViewController/SettingsViewController.swift b/TraccarClient/SettingsViewController/SettingsViewController.swift index 19a35c9229bba65a73a11aea1cad3d9d67d91c88..faa86ba79feae09b4bbefee0ea1c1866167415c8 100644 --- a/TraccarClient/SettingsViewController/SettingsViewController.swift +++ b/TraccarClient/SettingsViewController/SettingsViewController.swift @@ -15,30 +15,12 @@ final class SettingsViewController: KNViewController { @IBOutlet weak var tableView: UITableView! // MARK: - Properties - private var textDefaults: [DefaultsModel] = [DefaultsModel(title: "Frequency", - value: UserDefaults.standard.string(forKey: "frequency_preference") ?? "", - keyboardType: .numberPad, - key: "frequency_preference"), - - DefaultsModel(title: "Distance", - value: UserDefaults.standard.string(forKey: "distance_preference") ?? "", - keyboardType: .numberPad, - key: "distance_preference"), - - DefaultsModel(title: "Angle", - value: UserDefaults.standard.string(forKey: "angle_preference") ?? "", - keyboardType: .numberPad, - key: "angle_preference")] + private var textDefaults: [DefaultsModel] = [] - private var switchDefaults: [DefaultsModel] = [DefaultsModel(title: "Offline buffering", - value: UserDefaults.standard.bool(forKey: "buffer_preference") , - keyboardType: .default, - key: "buffer_preference")] + private var switchDefaults: [DefaultsModel] = [] + + private var multiChoicesDefaults: [DefaultsModel] = [] - private var multiChoicesDefaults: [DefaultsModel] = [DefaultsModel(title: "Accuracy", - value: UserDefaults.standard.string(forKey: "accuracy_preference") ?? "", - keyboardType: .default, - key: "accuracy_preference")] private var editedTextDefaults: [DefaultsModel] = [] private var editedSwitchDefaults: [DefaultsModel] = [] private var editedMultiChoicesDefaults: [DefaultsModel] = [] @@ -53,6 +35,7 @@ final class SettingsViewController: KNViewController { } private func setupUI() { + setDefaults() customHeaderView.set(type: .settings, delegate: self) tableView.delegate = self @@ -62,12 +45,40 @@ final class SettingsViewController: KNViewController { SettingsSwitchTableViewCell.self, SettingsSegmentTableViewCell.self, SettingsLogoutTableViewCell.self, - SettingsPrivacyPolicyTableViewCell.self]) + SettingsPrivacyPolicyTableViewCell.self, + SettingsResetTableViewCell.self]) tableView.allowsSelection = false tableView.separatorStyle = .none } + private func setDefaults() { + textDefaults = [DefaultsModel(title: "Frequency", + value: UserDefaults.standard.string(forKey: "frequency_preference") ?? "", + keyboardType: .numberPad, + key: "frequency_preference"), + + DefaultsModel(title: "Distance", + value: UserDefaults.standard.string(forKey: "distance_preference") ?? "", + keyboardType: .numberPad, + key: "distance_preference"), + + DefaultsModel(title: "Angle", + value: UserDefaults.standard.string(forKey: "angle_preference") ?? "", + keyboardType: .numberPad, + key: "angle_preference")] + + switchDefaults = [DefaultsModel(title: "Offline buffering", + value: UserDefaults.standard.bool(forKey: "buffer_preference") , + keyboardType: .default, + key: "buffer_preference")] + + multiChoicesDefaults = [DefaultsModel(title: "Accuracy", + value: UserDefaults.standard.string(forKey: "accuracy_preference") ?? "", + keyboardType: .default, + key: "accuracy_preference")] + } + private func isChangesOccured() -> Bool{ for defaultItem in textDefaults { if let editedItem = editedTextDefaults.first(where: { $0.key == defaultItem.key }) { @@ -99,6 +110,7 @@ extension SettingsViewController: CustomHeaderViewDelegate { view.endEditing(true) if isChangesOccured() { alert(confirm: "Yes", destructive: "No", message: "Are you sure you want to change settings?") { + UserDefaults.standard.setValue(true, forKey: "params_changed") for item in self.editedTextDefaults { UserDefaults.standard.setValue(item.value, forKey: item.key) } @@ -109,6 +121,11 @@ extension SettingsViewController: CustomHeaderViewDelegate { UserDefaults.standard.setValue(item.value, forKey: item.key) } if AppDelegate.instance.trackingController != nil { + + TransactionsViewController.addMessage(NSLocalizedString("Settings Changed", comment: "")) + AppDelegate.instance.trackingController?.stop() + AppDelegate.instance.trackingController = nil + AppDelegate.instance.trackingController = TrackingController() AppDelegate.instance.trackingController?.start() } @@ -125,7 +142,7 @@ extension SettingsViewController: CustomHeaderViewDelegate { view.endEditing(true) if isChangesOccured() { alert(presentingBy: self, confirm: "Save Changes", destructive: "Discard Changes", message: "You have unsaved changes. What do you want to do?") { - + UserDefaults.standard.setValue(true, forKey: "params_changed") for item in self.editedTextDefaults { UserDefaults.standard.setValue(item.value, forKey: item.key) } @@ -139,6 +156,10 @@ extension SettingsViewController: CustomHeaderViewDelegate { } if AppDelegate.instance.trackingController != nil { + TransactionsViewController.addMessage(NSLocalizedString("Settings Changed", comment: "")) + AppDelegate.instance.trackingController?.stop() + AppDelegate.instance.trackingController = nil + AppDelegate.instance.trackingController = TrackingController() AppDelegate.instance.trackingController?.start() } @@ -183,7 +204,7 @@ extension SettingsViewController: CustomHeaderViewDelegate { extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { - UserDefaults.standard.bool(forKey: Keys.User.updateSettings) ? 4 : 1 + UserDefaults.standard.bool(forKey: Keys.User.updateSettings) ? 5 : 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -197,9 +218,10 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { case 2: return switchDefaults.count - case 3: return 1 + case 4: + return 2 default: return 0 @@ -215,7 +237,7 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { return "Tracking Parameters" } - if section == 3 { + if section == 4 { return "Settings" } } @@ -248,11 +270,26 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { } if indexPath.section == 3 { - let cell = tableView.dequeue(withCell: SettingsLogoutTableViewCell.self) - cell.set(title: "Logout") + let cell = tableView.dequeue(withCell: SettingsResetTableViewCell.self) + cell.set(title: "Reset") cell.delegate = self return cell } + + if indexPath.section == 4 { + if indexPath.row == 1 { + let cell = tableView.dequeue(withCell: SettingsLogoutTableViewCell.self) + cell.set(title: "Logout") + cell.delegate = self + return cell + } + if indexPath.row == 0 { + let privacyCell = tableView.dequeue(withCell: SettingsPrivacyPolicyTableViewCell.self) + privacyCell.set(title: "Privacy Policy") + privacyCell.delegate = self + return privacyCell + } + } } else { if indexPath.row == 1 { @@ -261,11 +298,12 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { cell.delegate = self return cell } - if indexPath.row == 0 { } - let privacyCell = tableView.dequeue(withCell: SettingsPrivacyPolicyTableViewCell.self) - privacyCell.set(title: "Privacy Policy") - privacyCell.delegate = self - return privacyCell + if indexPath.row == 0 { + let privacyCell = tableView.dequeue(withCell: SettingsPrivacyPolicyTableViewCell.self) + privacyCell.set(title: "Privacy Policy") + privacyCell.delegate = self + return privacyCell + } } return UITableViewCell() } @@ -321,9 +359,9 @@ extension SettingsViewController: SettingsLogoutTableViewCellDelegate { extension SettingsViewController: SettingsPrivacyTableViewCellDelegate { func showPrivacy() { guard let url = URL(string: "https://dev-nextcloud.nmo.ai/apps/teams/img/privacy-policy.html") else { - return //be safe + return //be safe } - + if #available(iOS 10.0, *) { UIApplication.shared.open(url, options: [:], completionHandler: nil) } else { @@ -331,3 +369,23 @@ extension SettingsViewController: SettingsPrivacyTableViewCellDelegate { } } } + +// MARK: - SettingsResetTableViewCellDelegate +extension SettingsViewController: SettingsResetTableViewCellDelegate { + func reset() { + alert(presentingBy: self, confirm: "Yes" , destructive: "Cancel", message: "Are you sure you want to reset tracking parameters?") { + self.dismiss(animated: true) + UserDefaults.standard.setValue(false, forKey: "params_changed") + let spinner = self.spin() + api.parameters { result in + spinner.stop() + if result.success { + self.setDefaults() + self.tableView.reloadData() + } else { + ok(result) + } + } + } + } +} diff --git a/TraccarClient/TrackingParametersModel.swift b/TraccarClient/TrackingParametersModel.swift index 032de07a0769fe5811ea071f6a50d5e053e59549..53b7d39a4c2e8469768c9bd503a66a03d6addadd 100644 --- a/TraccarClient/TrackingParametersModel.swift +++ b/TraccarClient/TrackingParametersModel.swift @@ -29,7 +29,7 @@ final class TrackingParametersModel: KNObject { offline_buffering = dict["offline_buffering"] as? Bool ?? false accuracy = dict["accuracy"] as? String ?? "" - if save { + if save && !UserDefaults.standard.bool(forKey: "params_changed"){ saveToDefaults() } } diff --git a/TraccarClient/UIImage.swift b/TraccarClient/UIImage.swift index 1a9fe31ea382d8141f4b80acce111ae785a9cd52..2781d6985fd34438bec1793f78df9623beee0f0a 100644 --- a/TraccarClient/UIImage.swift +++ b/TraccarClient/UIImage.swift @@ -29,6 +29,7 @@ extension UIImage { static let handle = img("handle") static let privacy = img("privacyPolicy") static let alertIcon = img("alertIcon") + static let reset = img("resetSettings") } func img(_ name: String) -> UIImage {