Skip to content

Commit ac90bcc

Browse files
authored
Merge pull request #290 from mattrubin/display-options
Settings screen for password digit grouping
2 parents 713a80f + a8a7e33 commit ac90bcc

18 files changed

+619
-78
lines changed

Authenticator.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
C9A1C1A91E501D8B009E65D6 /* Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A1C1A81E501D8B009E65D6 /* Info.swift */; };
3636
C9A1C1AC1E5021A6009E65D6 /* BackupInfo.html in Resources */ = {isa = PBXBuildFile; fileRef = C9A1C1AA1E502195009E65D6 /* BackupInfo.html */; };
3737
C9A1C1CE1E6CDBFB009E65D6 /* RootTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A1C1CD1E6CDBFB009E65D6 /* RootTests.swift */; };
38+
C9A23F2E2159C28200615846 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A23F2D2159C28200615846 /* Settings.swift */; };
3839
C9A262D01E170BD4004E6CEB /* AuthenticatorScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A262CF1E170BD4004E6CEB /* AuthenticatorScreenshots.swift */; };
3940
C9A262D81E170E3A004E6CEB /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A262D71E170E3A004E6CEB /* SnapshotHelper.swift */; };
4041
C9A262DA1E176A18004E6CEB /* Demo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A262D91E176A18004E6CEB /* Demo.swift */; };
@@ -49,11 +50,14 @@
4950
C9CC09511BA903B7008C54FE /* TokenFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC09501BA903B7008C54FE /* TokenFormViewController.swift */; };
5051
C9CC09531BA9133B008C54FE /* FocusCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC09521BA9133B008C54FE /* FocusCell.swift */; };
5152
C9CC09551BA91D1C008C54FE /* TableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC09541BA91D1C008C54FE /* TableViewModel.swift */; };
53+
C9CDD1CF209662E100636056 /* DisplayOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CDD1CE209662E100636056 /* DisplayOptions.swift */; };
54+
C9CDD1D12096635300636056 /* DisplayOptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CDD1D02096635300636056 /* DisplayOptionsViewController.swift */; };
5255
C9D6C83F1906BD68004F0E08 /* SegmentedControlRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D6C83E1906BD68004F0E08 /* SegmentedControlRow.swift */; };
5356
C9D6C8461906CD54004F0E08 /* TextFieldRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D6C8451906CD54004F0E08 /* TextFieldRow.swift */; };
5457
C9D6C84C19075044004F0E08 /* ProgressRingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D6C84B19075044004F0E08 /* ProgressRingView.swift */; };
5558
C9DE02E71ED2234D00D7E01C /* InfoList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DE02E61ED2234D00D7E01C /* InfoList.swift */; };
5659
C9DE02E91ED227D600D7E01C /* InfoListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DE02E81ED227D600D7E01C /* InfoListViewController.swift */; };
60+
C9E11E1121543E2A00C1AA53 /* Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E11E1021543E2A00C1AA53 /* Menu.swift */; };
5761
C9E3FB9A1E281CBC00EFA8BB /* TokenScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E3FB991E281CBC00EFA8BB /* TokenScanner.swift */; };
5862
C9E3FB9C1E2860DD00EFA8BB /* TokenScannerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E3FB9B1E2860DD00EFA8BB /* TokenScannerTests.swift */; };
5963
C9EB448E1C52A74200ACFA87 /* Component.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EB448D1C52A74200ACFA87 /* Component.swift */; };
@@ -157,6 +161,7 @@
157161
C9A1C1A81E501D8B009E65D6 /* Info.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Info.swift; sourceTree = "<group>"; };
158162
C9A1C1AA1E502195009E65D6 /* BackupInfo.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = BackupInfo.html; sourceTree = "<group>"; };
159163
C9A1C1CD1E6CDBFB009E65D6 /* RootTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootTests.swift; sourceTree = "<group>"; };
164+
C9A23F2D2159C28200615846 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
160165
C9A262CD1E170BD4004E6CEB /* AuthenticatorScreenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AuthenticatorScreenshots.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
161166
C9A262CF1E170BD4004E6CEB /* AuthenticatorScreenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticatorScreenshots.swift; sourceTree = "<group>"; };
162167
C9A262D71E170E3A004E6CEB /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotHelper.swift; path = fastlane/SnapshotHelper.swift; sourceTree = SOURCE_ROOT; };
@@ -172,13 +177,16 @@
172177
C9CC09501BA903B7008C54FE /* TokenFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenFormViewController.swift; sourceTree = "<group>"; };
173178
C9CC09521BA9133B008C54FE /* FocusCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FocusCell.swift; sourceTree = "<group>"; };
174179
C9CC09541BA91D1C008C54FE /* TableViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewModel.swift; sourceTree = "<group>"; };
180+
C9CDD1CE209662E100636056 /* DisplayOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayOptions.swift; sourceTree = "<group>"; };
181+
C9CDD1D02096635300636056 /* DisplayOptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayOptionsViewController.swift; sourceTree = "<group>"; };
175182
C9D6C83E1906BD68004F0E08 /* SegmentedControlRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SegmentedControlRow.swift; sourceTree = "<group>"; };
176183
C9D6C8451906CD54004F0E08 /* TextFieldRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldRow.swift; sourceTree = "<group>"; };
177184
C9D6C84B19075044004F0E08 /* ProgressRingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressRingView.swift; sourceTree = "<group>"; };
178185
C9D844341D4C576B00D5E343 /* CONTRIBUTING.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = "<group>"; };
179186
C9D844361D4C59D600D5E343 /* CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONDUCT.md; sourceTree = "<group>"; };
180187
C9DE02E61ED2234D00D7E01C /* InfoList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfoList.swift; sourceTree = "<group>"; };
181188
C9DE02E81ED227D600D7E01C /* InfoListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfoListViewController.swift; sourceTree = "<group>"; };
189+
C9E11E1021543E2A00C1AA53 /* Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Menu.swift; sourceTree = "<group>"; };
182190
C9E3FB991E281CBC00EFA8BB /* TokenScanner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenScanner.swift; sourceTree = "<group>"; };
183191
C9E3FB9B1E2860DD00EFA8BB /* TokenScannerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenScannerTests.swift; sourceTree = "<group>"; };
184192
C9EB448D1C52A74200ACFA87 /* Component.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Component.swift; sourceTree = "<group>"; };
@@ -440,10 +448,13 @@
440448
C9A1C1A71E501D5F009E65D6 /* Info */ = {
441449
isa = PBXGroup;
442450
children = (
451+
C9E11E1021543E2A00C1AA53 /* Menu.swift */,
443452
C9DE02E61ED2234D00D7E01C /* InfoList.swift */,
444453
C9DE02E81ED227D600D7E01C /* InfoListViewController.swift */,
445454
C9A1C1A81E501D8B009E65D6 /* Info.swift */,
446455
C9A1C1A51E501CB2009E65D6 /* InfoViewController.swift */,
456+
C9CDD1CE209662E100636056 /* DisplayOptions.swift */,
457+
C9CDD1D02096635300636056 /* DisplayOptionsViewController.swift */,
447458
);
448459
name = Info;
449460
sourceTree = "<group>";
@@ -505,6 +516,7 @@
505516
isa = PBXGroup;
506517
children = (
507518
C9F7A8601C4D90B50082E5AE /* TokenStore.swift */,
519+
C9A23F2D2159C28200615846 /* Settings.swift */,
508520
);
509521
name = "Data Store";
510522
sourceTree = "<group>";
@@ -656,7 +668,10 @@
656668
buildActionMask = 2147483647;
657669
files = (
658670
C93AD15219CD51BE007480E9 /* Colors.swift in Sources */,
671+
C9CDD1D12096635300636056 /* DisplayOptionsViewController.swift in Sources */,
672+
C9CDD1CF209662E100636056 /* DisplayOptions.swift in Sources */,
659673
C9DE02E71ED2234D00D7E01C /* InfoList.swift in Sources */,
674+
C9A23F2E2159C28200615846 /* Settings.swift in Sources */,
660675
C93BD6251C16841D00FFFB8F /* RootViewController.swift in Sources */,
661676
C9919CE01BA721A1006237C1 /* ButtonHeaderView.swift in Sources */,
662677
C9EB44901C52AE4500ACFA87 /* AppController.swift in Sources */,
@@ -683,6 +698,7 @@
683698
C9D6C83F1906BD68004F0E08 /* SegmentedControlRow.swift in Sources */,
684699
C968D1151CB4C639004ED7BB /* DisplayTime.swift in Sources */,
685700
8B0028B511EB75920092DE18 /* ScannerOverlayView.swift in Sources */,
701+
C9E11E1121543E2A00C1AA53 /* Menu.swift in Sources */,
686702
C9CC09551BA91D1C008C54FE /* TableViewModel.swift in Sources */,
687703
C92708AC19CFB0750033128B /* TokenListViewController.swift in Sources */,
688704
C9A262DA1E176A18004E6CEB /* Demo.swift in Sources */,

Authenticator/Source/AppController.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ import SVProgressHUD
3131

3232
class AppController {
3333
private let store: TokenStore
34+
private let settings: Settings
3435
private var component: Root {
3536
didSet {
3637
updateView()
3738
}
3839
}
3940
private lazy var view: RootViewController = {
4041
let (currentViewModel, nextRefreshTime) = self.component.viewModel(with: self.store.persistentTokens,
41-
at: .currentDisplayTime())
42+
at: .currentDisplayTime(),
43+
digitGroupSize: settings.digitGroupSize)
4244
self.setTimer(withNextRefreshTime: nextRefreshTime)
4345
return RootViewController(
4446
viewModel: currentViewModel,
@@ -68,6 +70,8 @@ class AppController {
6870
fatalError("Failed to load token store: \(error)")
6971
}
7072

73+
settings = Settings()
74+
7175
// If this is a demo, show the scanner even in the simulator.
7276
let deviceCanScan = QRScanner.deviceCanScan || CommandLine.isDemo
7377
component = Root(deviceCanScan: deviceCanScan)
@@ -76,7 +80,8 @@ class AppController {
7680
@objc
7781
func updateView() {
7882
let (currentViewModel, nextRefreshTime) = component.viewModel(with: store.persistentTokens,
79-
at: .currentDisplayTime())
83+
at: .currentDisplayTime(),
84+
digitGroupSize: settings.digitGroupSize)
8085
setTimer(withNextRefreshTime: nextRefreshTime)
8186
view.update(with: currentViewModel)
8287
}
@@ -174,6 +179,10 @@ class AppController {
174179
// Fallback on earlier versions
175180
UIApplication.shared.openURL(url)
176181
}
182+
183+
case let .setDigitGroupSize(digitGroupSize):
184+
settings.digitGroupSize = digitGroupSize
185+
updateView()
177186
}
178187
}
179188

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// DisplayOptions.swift
3+
// Authenticator
4+
//
5+
// Copyright (c) 2018 Authenticator authors
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
//
25+
26+
struct DisplayOptions {
27+
// MARK: View Model
28+
29+
struct ViewModel {
30+
let digitGroupSize: Int
31+
}
32+
33+
func viewModel(digitGroupSize: Int) -> ViewModel {
34+
return ViewModel(digitGroupSize: digitGroupSize)
35+
}
36+
37+
// MARK: Actions
38+
39+
enum Effect {
40+
case setDigitGroupSize(Int)
41+
case done
42+
}
43+
}

0 commit comments

Comments
 (0)