diff --git a/CHANGELOG.md b/CHANGELOG.md index eb20c2dfe..d6e9a77d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ #CHANGELOG +## [1.0.26] (Public Beta) - 2019-06-29 + +### Added +- [Frequently asked questions](https://keepassium.com/faq) +- AutoFill setup instructions +- Option to lock the app not only immediately, but after a few seconds in background (closes #14) [thanks, J.B.] +- Option to automatically delete old backup copies (closes #12) [thanks, Dragonblitz10] +- Button in AutoFill to discard auto-suggestions and start manual search (closes #9) [thanks, Dragonblitz10] +- Option to copy OTP to clipboard when using AutoFill (closes #7) [thanks, Thunder33345] +- When long-pressing a file, suggest swiping instead [thanks, u/bananajoe] + +### Changed +- "Remember master keys" option now defaults to "on" on first launch +- Manual search now checks the names of custom entry fields, even protected ones (related to #8) +- Moved backup setings to a separate page +- Refined the Settings screens + +### Fixed +- Diagnostics viewer scrolls to bottom +- Error message animation in Create Database dialog [thanks, Tobias] +- Regression: files are not syncronized (#10, #13) [thanks, Sunil and AndiB.] +- Database loading error 'Nil value in Entry/Times/ExpiryTime' in some cases [thanks, u/yacob841] + + ## [1.0.25] (Public Beta) - 2019-06-19 ### Fixed diff --git a/KeePassium AutoFill/Info.plist b/KeePassium AutoFill/Info.plist index f9aec9fe3..99eca8493 100644 --- a/KeePassium AutoFill/Info.plist +++ b/KeePassium AutoFill/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 25 + 26 LSSupportsOpeningDocumentsInPlace NSExtension diff --git a/KeePassium AutoFill/MainCoordinator.swift b/KeePassium AutoFill/MainCoordinator.swift index 1fcfa9d7e..d15c776ae 100644 --- a/KeePassium AutoFill/MainCoordinator.swift +++ b/KeePassium AutoFill/MainCoordinator.swift @@ -92,6 +92,18 @@ class MainCoordinator: NSObject, Coordinator { func returnCredentials(entry: Entry) { watchdog.restart() + + let settings = Settings.current + if settings.isCopyTOTPOnAutoFill, + let totpGenerator = TOTPGeneratorFactory.makeGenerator(for: entry) + { + let totpString = totpGenerator.generate() + Clipboard.general.insert( + text: totpString, + timeout: TimeInterval(settings.clipboardTimeout.seconds) + ) + } + let passwordCredential = ASPasswordCredential(user: entry.userName, password: entry.password) rootController.extensionContext.completeRequest( withSelectedCredential: passwordCredential, diff --git a/KeePassium AutoFill/controllers/DatabaseChooserVC.swift b/KeePassium AutoFill/controllers/DatabaseChooserVC.swift index 5f4907f69..34ac0abf2 100644 --- a/KeePassium AutoFill/controllers/DatabaseChooserVC.swift +++ b/KeePassium AutoFill/controllers/DatabaseChooserVC.swift @@ -37,6 +37,11 @@ class DatabaseChooserVC: UITableViewController, Refreshable { refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged) self.refreshControl = refreshControl + let longPressGestureRecognizer = UILongPressGestureRecognizer( + target: self, + action: #selector(didLongPressTableView)) + tableView.addGestureRecognizer(longPressGestureRecognizer) + refresh() } @@ -76,6 +81,15 @@ class DatabaseChooserVC: UITableViewController, Refreshable { delegate?.databaseChooserShouldAddDatabase(self) } + @objc func didLongPressTableView(_ gestureRecognizer: UILongPressGestureRecognizer) { + let point = gestureRecognizer.location(in: tableView) + guard gestureRecognizer.state == .began, + let indexPath = tableView.indexPathForRow(at: point), + tableView(tableView, canEditRowAt: indexPath), + let cell = tableView.cellForRow(at: indexPath) else { return } + cell.demoShowEditActions(lastActionColor: UIColor.destructiveTint) + } + override func numberOfSections(in tableView: UITableView) -> Int { return 1 diff --git a/KeePassium AutoFill/controllers/DiagnosticsViewerVC.swift b/KeePassium AutoFill/controllers/DiagnosticsViewerVC.swift index 67f79c776..5c8ee32f8 100644 --- a/KeePassium AutoFill/controllers/DiagnosticsViewerVC.swift +++ b/KeePassium AutoFill/controllers/DiagnosticsViewerVC.swift @@ -52,9 +52,17 @@ class DiagnosticsViewerVC: UITableViewController { tableView.rowHeight = UITableView.automaticDimension items = Diag.itemsSnapshot() super.viewDidLoad() + + if items.count > 0 { + let lastRowIndexPath = IndexPath(row: items.count - 1, section: 0) + DispatchQueue.main.async { + self.tableView.scrollToRow(at: lastRowIndexPath, at: .none, animated: true) + } + } } + @IBAction func didPressCopy(_ sender: Any) { Watchdog.shared.restart() let logText = Diag.toString() diff --git a/KeePassium AutoFill/controllers/EntryFinderVC.swift b/KeePassium AutoFill/controllers/EntryFinderVC.swift index 9635e207a..64eb124e1 100644 --- a/KeePassium AutoFill/controllers/EntryFinderVC.swift +++ b/KeePassium AutoFill/controllers/EntryFinderVC.swift @@ -50,11 +50,19 @@ class EntryFinderVC: UITableViewController { private var searchHelper = SearchHelper() private var searchResults = SearchResults(exactMatch: [], partialMatch: []) private var searchController: UISearchController! + private var manualSearchButton: UIBarButtonItem! override func viewDidLoad() { super.viewDidLoad() self.clearsSelectionOnViewWillAppear = false setupSearch() + + manualSearchButton = UIBarButtonItem( + barButtonSystemItem: .search, + target: self, + action: #selector(didPressManualSearch)) + navigationItem.rightBarButtonItem = manualSearchButton + refreshDatabaseName() updateSearchCriteria() } @@ -211,6 +219,12 @@ class EntryFinderVC: UITableViewController { } } + @objc func didPressManualSearch(_ sender: Any) { + serviceIdentifiers.removeAll() + updateSearchCriteria() + searchController.searchBar.becomeFirstResponder() + } + @IBAction func didPressLockDatabase(_ sender: Any) { Watchdog.shared.restart() delegate?.entryFinderShouldLockDatabase(self) diff --git a/KeePassium AutoFill/controllers/KeyFileChooserVC.swift b/KeePassium AutoFill/controllers/KeyFileChooserVC.swift index 7b259a2b8..ff9db136b 100644 --- a/KeePassium AutoFill/controllers/KeyFileChooserVC.swift +++ b/KeePassium AutoFill/controllers/KeyFileChooserVC.swift @@ -32,6 +32,11 @@ class KeyFileChooserVC: UITableViewController, Refreshable { refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged) self.refreshControl = refreshControl + let longPressGestureRecognizer = UILongPressGestureRecognizer( + target: self, + action: #selector(didLongPressTableView)) + tableView.addGestureRecognizer(longPressGestureRecognizer) + refresh() } @@ -135,4 +140,13 @@ class KeyFileChooserVC: UITableViewController, Refreshable { FileKeeper.shared.removeExternalReference(fileRef, fileType: .keyFile) refresh() } + + @objc func didLongPressTableView(_ gestureRecognizer: UILongPressGestureRecognizer) { + let point = gestureRecognizer.location(in: tableView) + guard gestureRecognizer.state == .began, + let indexPath = tableView.indexPathForRow(at: point), + tableView(tableView, canEditRowAt: indexPath), + let cell = tableView.cellForRow(at: indexPath) else { return } + cell.demoShowEditActions(lastActionColor: UIColor.destructiveTint) + } } diff --git a/KeePassium.xcodeproj/project.pbxproj b/KeePassium.xcodeproj/project.pbxproj index a58e27029..bce6fb69d 100755 --- a/KeePassium.xcodeproj/project.pbxproj +++ b/KeePassium.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 750433AF2274CDD5000FE96B /* DatabaseCreatorCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750433AE2274CDD5000FE96B /* DatabaseCreatorCoordinator.swift */; }; + 75065A3322C41B3A00958243 /* SettingsAutoFillVC.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75065A3222C41B3A00958243 /* SettingsAutoFillVC.storyboard */; }; + 75065A3522C41B5200958243 /* SettingsAutoFillVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75065A3422C41B5200958243 /* SettingsAutoFillVC.swift */; }; 750C683220D767F6001A6AA0 /* EditEntryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750C683120D767F6001A6AA0 /* EditEntryVC.swift */; }; 750CFBC821BA9ACD00E62B09 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7550D231215D758800360E0C /* AuthenticationServices.framework */; }; 750CFBCB21BA9ACD00E62B09 /* CredentialProviderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 750CFBCA21BA9ACD00E62B09 /* CredentialProviderViewController.swift */; }; @@ -70,6 +72,12 @@ 75779864223023D3006671BD /* ProgressViewHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75779863223023D3006671BD /* ProgressViewHost.swift */; }; 75779865223023D3006671BD /* ProgressViewHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75779863223023D3006671BD /* ProgressViewHost.swift */; }; 75781A2D20CA3D7A00BE474F /* SettingsFileSortingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75781A2C20CA3D7A00BE474F /* SettingsFileSortingVC.swift */; }; + 7578487D22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7578487C22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift */; }; + 7578487E22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7578487C22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift */; }; + 7578488422C165B700BBEF9A /* SettingsBackupVC.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7578488322C165B700BBEF9A /* SettingsBackupVC.storyboard */; }; + 7578488622C165C900BBEF9A /* SettingsBackupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7578488522C165C900BBEF9A /* SettingsBackupVC.swift */; }; + 7578488D22C1DFC400BBEF9A /* SettingsBackupTimeoutPickerVC.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7578488C22C1DFC400BBEF9A /* SettingsBackupTimeoutPickerVC.storyboard */; }; + 7578488F22C1DFF400BBEF9A /* SettingsBackupTimeoutPickerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7578488E22C1DFF400BBEF9A /* SettingsBackupTimeoutPickerVC.swift */; }; 757D336120EF382D000A47F0 /* SettingsDatabaseTimeoutVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757D336020EF382D000A47F0 /* SettingsDatabaseTimeoutVC.swift */; }; 757D336320EF5081000A47F0 /* SettingsClipboardTimeoutVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757D336220EF5081000A47F0 /* SettingsClipboardTimeoutVC.swift */; }; 757EF2F520EB3D1C0024AACD /* PasswordGeneratorVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757EF2F420EB3D1C0024AACD /* PasswordGeneratorVC.swift */; }; @@ -198,6 +206,8 @@ /* Begin PBXFileReference section */ 750433AE2274CDD5000FE96B /* DatabaseCreatorCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseCreatorCoordinator.swift; sourceTree = ""; }; + 75065A3222C41B3A00958243 /* SettingsAutoFillVC.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SettingsAutoFillVC.storyboard; sourceTree = ""; }; + 75065A3422C41B5200958243 /* SettingsAutoFillVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAutoFillVC.swift; sourceTree = ""; }; 750C683120D767F6001A6AA0 /* EditEntryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditEntryVC.swift; sourceTree = ""; }; 750CFBC721BA9ACD00E62B09 /* KeePassium AutoFill.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "KeePassium AutoFill.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 750CFBCA21BA9ACD00E62B09 /* CredentialProviderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialProviderViewController.swift; sourceTree = ""; }; @@ -252,6 +262,11 @@ 756FF64320BAB20300FF890B /* UIColor+namedColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+namedColors.swift"; sourceTree = ""; }; 75779863223023D3006671BD /* ProgressViewHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressViewHost.swift; sourceTree = ""; }; 75781A2C20CA3D7A00BE474F /* SettingsFileSortingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFileSortingVC.swift; sourceTree = ""; }; + 7578487C22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+demoEditActions.swift"; sourceTree = ""; }; + 7578488322C165B700BBEF9A /* SettingsBackupVC.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SettingsBackupVC.storyboard; sourceTree = ""; }; + 7578488522C165C900BBEF9A /* SettingsBackupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupVC.swift; sourceTree = ""; }; + 7578488C22C1DFC400BBEF9A /* SettingsBackupTimeoutPickerVC.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SettingsBackupTimeoutPickerVC.storyboard; sourceTree = ""; }; + 7578488E22C1DFF400BBEF9A /* SettingsBackupTimeoutPickerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBackupTimeoutPickerVC.swift; sourceTree = ""; }; 757D336020EF382D000A47F0 /* SettingsDatabaseTimeoutVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDatabaseTimeoutVC.swift; sourceTree = ""; }; 757D336220EF5081000A47F0 /* SettingsClipboardTimeoutVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsClipboardTimeoutVC.swift; sourceTree = ""; }; 757EF2F420EB3D1C0024AACD /* PasswordGeneratorVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordGeneratorVC.swift; sourceTree = ""; }; @@ -362,6 +377,15 @@ name = Frameworks; sourceTree = ""; }; + 75065A3122C41B2200958243 /* autoFill */ = { + isa = PBXGroup; + children = ( + 75065A3222C41B3A00958243 /* SettingsAutoFillVC.storyboard */, + 75065A3422C41B5200958243 /* SettingsAutoFillVC.swift */, + ); + path = autoFill; + sourceTree = ""; + }; 750CFBC921BA9ACD00E62B09 /* KeePassium AutoFill */ = { isa = PBXGroup; children = ( @@ -380,7 +404,9 @@ 7546FBC420C1024200C5D834 /* settings */ = { isa = PBXGroup; children = ( + 75065A3122C41B2200958243 /* autoFill */, 75C3800F217A0497006F74C2 /* appLock */, + 7578488722C16D7D00BBEF9A /* backup */, 7546FBC520C1027700C5D834 /* SettingsVC.swift */, 7546FBC920C104EE00C5D834 /* SettingsVC.storyboard */, 75781A2C20CA3D7A00BE474F /* SettingsFileSortingVC.swift */, @@ -447,6 +473,7 @@ 75C5C3752129DE0800CD7FE3 /* UIAlertController+extensions.swift */, 756FF64320BAB20300FF890B /* UIColor+namedColors.swift */, 755E9C4C20BE5DC200FD7C7A /* UIImage+extensions.swift */, + 7578487C22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift */, 75C3801A217A0B76006F74C2 /* UIViewController+storyboard.swift */, 7542D2412129640F00C8A926 /* String+extensions.swift */, 7523F71C21C98D620025C706 /* SupportEmailComposer.swift */, @@ -523,6 +550,17 @@ path = database; sourceTree = ""; }; + 7578488722C16D7D00BBEF9A /* backup */ = { + isa = PBXGroup; + children = ( + 7578488522C165C900BBEF9A /* SettingsBackupVC.swift */, + 7578488322C165B700BBEF9A /* SettingsBackupVC.storyboard */, + 7578488E22C1DFF400BBEF9A /* SettingsBackupTimeoutPickerVC.swift */, + 7578488C22C1DFC400BBEF9A /* SettingsBackupTimeoutPickerVC.storyboard */, + ); + path = backup; + sourceTree = ""; + }; 758BF0D920D21EE500897C83 /* general */ = { isa = PBXGroup; children = ( @@ -743,11 +781,13 @@ 75C38047217A3254006F74C2 /* ChooseDatabaseVC.storyboard in Resources */, 75C38033217A26DC006F74C2 /* AboutVC.storyboard in Resources */, 754BF08D2082A6BD00E3A292 /* LaunchScreen.storyboard in Resources */, + 7578488422C165B700BBEF9A /* SettingsBackupVC.storyboard in Resources */, 75C38041217A284A006F74C2 /* ChooseKeyFileVC.storyboard in Resources */, 75C3800E217A0344006F74C2 /* SettingsItemListVC.storyboard in Resources */, 75C38039217A27A7006F74C2 /* ChooseIconVC.storyboard in Resources */, 75C38013217A053D006F74C2 /* SettingsAppTimeoutVC.storyboard in Resources */, 75C38021217A1F0A006F74C2 /* ViewEntryFieldsVC.storyboard in Resources */, + 7578488D22C1DFC400BBEF9A /* SettingsBackupTimeoutPickerVC.storyboard in Resources */, 75C38035217A271B006F74C2 /* ViewDiagnosticsVC.storyboard in Resources */, 75C3801F217A1EE1006F74C2 /* EditEntryVC.storyboard in Resources */, 75C3803D217A27FE006F74C2 /* ChangeMasterKeyVC.storyboard in Resources */, @@ -767,6 +807,7 @@ 75C38045217A3204006F74C2 /* PlaceholderVC.storyboard in Resources */, 75C38017217A0750006F74C2 /* SettingsDatabaseTimeoutVC.storyboard in Resources */, 75C3800C217A02DD006F74C2 /* SettingsFileSortingVC.storyboard in Resources */, + 75065A3322C41B3A00958243 /* SettingsAutoFillVC.storyboard in Resources */, 75C3803F217A281D006F74C2 /* UnlockDatabaseVC.storyboard in Resources */, 75C38019217A078D006F74C2 /* SettingsClipboardTimeoutVC.storyboard in Resources */, 752ED68B2235543F00C20D3E /* SettingsDataProtectionVC.storyboard in Resources */, @@ -790,6 +831,7 @@ 75CBAB9F21C1671F00B8AFE2 /* MainCoordinator.swift in Sources */, 75D3A3B121BAE66F00255FC3 /* DatabaseFileListCell.swift in Sources */, 7523F71521C94DD90025C706 /* DiagnosticsViewerVC.swift in Sources */, + 7578487E22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift in Sources */, 75B24DBA21C3CADB003C9486 /* EntryFinderVC.swift in Sources */, 750CFC0921BADBA500E62B09 /* DatabaseChooserVC.swift in Sources */, 757FB3CD21F9C50700F016FA /* ValidatingTextField.swift in Sources */, @@ -873,6 +915,8 @@ 75CD364121537A320018AF46 /* AppStoreReviewHelper.swift in Sources */, 75B5FB7720D53EA700D402D9 /* ViewEntryFieldsVC.swift in Sources */, 75B3B7BC20EABD9D007E8FA9 /* PlaceholderVC.swift in Sources */, + 7578488622C165C900BBEF9A /* SettingsBackupVC.swift in Sources */, + 75065A3522C41B5200958243 /* SettingsAutoFillVC.swift in Sources */, 7546FBD920C3A3F600C5D834 /* Watchdog.swift in Sources */, 75CA73912144381200ADAD64 /* KeyboardLayoutConstraint.swift in Sources */, 757FB3CA21F8D34A00F016FA /* PasscodeInputVC.swift in Sources */, @@ -881,10 +925,12 @@ 7529EAE9211416170093B117 /* SettingsAppLockVC.swift in Sources */, 758BF0D820D1B1DA00897C83 /* ValidatingTextField.swift in Sources */, 754BF09A20984DEE00E3A292 /* UnlockDatabaseVC.swift in Sources */, + 7578488F22C1DFF400BBEF9A /* SettingsBackupTimeoutPickerVC.swift in Sources */, 75C5C3762129DE0800CD7FE3 /* UIAlertController+extensions.swift in Sources */, 75F4ACFC21776F4800B22D8B /* LString.swift in Sources */, 750D127E20CF071600BE0CCE /* EditGroupVC.swift in Sources */, 75C94C5B20B4B8C2004FA29D /* ViewEntryVC.swift in Sources */, + 7578487D22C02A9100BBEF9A /* UITableViewCell+demoEditActions.swift in Sources */, 75779864223023D3006671BD /* ProgressViewHost.swift in Sources */, 7596771E20FB36BD00E54827 /* SettingsAppTimeoutVC.swift in Sources */, 7546FBDB20C3AC5E00C5D834 /* main.swift in Sources */, diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/Contents.json b/KeePassium/Assets.xcassets/autofill-onboarding/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/KeePassium/Assets.xcassets/autofill-onboarding/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/Contents.json b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/Contents.json new file mode 100644 index 000000000..13893c166 --- /dev/null +++ b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ios-settings_iconfinder-2697651_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ios-settings_iconfinder-2697651_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ios-settings_iconfinder-2697651_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@1.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@1.png new file mode 100644 index 000000000..68de65f40 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@1.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@2.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@2.png new file mode 100644 index 000000000..dfaf61720 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@2.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@3.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@3.png new file mode 100644 index 000000000..abacd5b8f Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-1.imageset/ios-settings_iconfinder-2697651_29@3.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/Contents.json b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/Contents.json new file mode 100644 index 000000000..1e154c019 --- /dev/null +++ b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "passwords_ownwork_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "passwords_ownwork_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "passwords_ownwork_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@1.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@1.png new file mode 100644 index 000000000..8327307de Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@1.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@2.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@2.png new file mode 100644 index 000000000..8300cf2ec Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@2.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@3.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@3.png new file mode 100644 index 000000000..4853a01b6 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-2.imageset/passwords_ownwork_29@3.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/Contents.json b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/Contents.json new file mode 100644 index 000000000..74fc08246 --- /dev/null +++ b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "autofill_ownwork_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "autofill_ownwork_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "autofill_ownwork_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@1.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@1.png new file mode 100644 index 000000000..6c5498324 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@1.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@2.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@2.png new file mode 100644 index 000000000..cc4613381 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@2.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@3.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@3.png new file mode 100644 index 000000000..24a44889c Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-3.imageset/autofill_ownwork_29@3.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/Contents.json b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/Contents.json new file mode 100644 index 000000000..e31fd3abb --- /dev/null +++ b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "keepassium-icon_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "keepassium-icon_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "keepassium-icon_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@1.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@1.png new file mode 100644 index 000000000..9d6d72ec1 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@1.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@2.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@2.png new file mode 100644 index 000000000..1d33ec0c8 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@2.png differ diff --git a/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@3.png b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@3.png new file mode 100644 index 000000000..0c4ed2092 Binary files /dev/null and b/KeePassium/Assets.xcassets/autofill-onboarding/autofill-setup-4.imageset/keepassium-icon_29@3.png differ diff --git a/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/Contents.json b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/Contents.json new file mode 100644 index 000000000..5761b37e3 --- /dev/null +++ b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "EnterMacKey_icons8_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "EnterMacKey_icons8_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "EnterMacKey_icons8_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@1.png b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@1.png new file mode 100644 index 000000000..ded4e9cf9 Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@1.png differ diff --git a/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@2.png b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@2.png new file mode 100644 index 000000000..7c10f518f Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@2.png differ diff --git a/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@3.png b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@3.png new file mode 100644 index 000000000..9e210484a Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-autofill-listitem.imageset/EnterMacKey_icons8_29@3.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/Contents.json b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/Contents.json new file mode 100755 index 000000000..37393571b --- /dev/null +++ b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "database-backup_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "database-backup_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "database-backup_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@1.png b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@1.png new file mode 100644 index 000000000..59222f133 Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@1.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@2.png b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@2.png new file mode 100644 index 000000000..cc21eac8b Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@2.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@3.png b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@3.png new file mode 100644 index 000000000..8700d1530 Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-duration-listitem.imageset/database-backup_29@3.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/Contents.json b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/Contents.json new file mode 100644 index 000000000..621a5686f --- /dev/null +++ b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "umbrella_feather_29@1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "umbrella_feather_29@2.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "umbrella_feather_29@3.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@1.png b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@1.png new file mode 100644 index 000000000..5a013f8c1 Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@1.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@2.png b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@2.png new file mode 100644 index 000000000..1ee2ecf2a Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@2.png differ diff --git a/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@3.png b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@3.png new file mode 100644 index 000000000..44445c3c7 Binary files /dev/null and b/KeePassium/Assets.xcassets/settings-backup-listitem.imageset/umbrella_feather_29@3.png differ diff --git a/KeePassium/Info.plist b/KeePassium/Info.plist index 6b6c38880..ff75ea14a 100644 --- a/KeePassium/Info.plist +++ b/KeePassium/Info.plist @@ -56,7 +56,7 @@ CFBundleShortVersionString 1.0 CFBundleVersion - 25 + 26 LSRequiresIPhoneOS LSSupportsOpeningDocumentsInPlace diff --git a/KeePassium/database/ChooseDatabaseVC.swift b/KeePassium/database/ChooseDatabaseVC.swift index 30474ba07..510a9e9bb 100755 --- a/KeePassium/database/ChooseDatabaseVC.swift +++ b/KeePassium/database/ChooseDatabaseVC.swift @@ -60,9 +60,14 @@ class ChooseDatabaseVC: UITableViewController, Refreshable { clearsSelectionOnViewWillAppear = false + let longPressGestureRecognizer = UILongPressGestureRecognizer( + target: self, + action: #selector(didLongPressTableView)) + tableView.addGestureRecognizer(longPressGestureRecognizer) + updateDetailView(onlyInTwoPaneMode: false) } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationController?.isToolbarHidden = false @@ -164,6 +169,15 @@ class ChooseDatabaseVC: UITableViewController, Refreshable { showDetailViewController(aboutVC, sender: self) } + @objc func didLongPressTableView(_ gestureRecognizer: UILongPressGestureRecognizer) { + let point = gestureRecognizer.location(in: tableView) + guard gestureRecognizer.state == .began, + let indexPath = tableView.indexPathForRow(at: point), + tableView(tableView, canEditRowAt: indexPath), + let cell = tableView.cellForRow(at: indexPath) else { return } + cell.demoShowEditActions(lastActionColor: UIColor.destructiveTint) + } + @IBAction func didPressAddDatabase(_ sender: Any) { let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) diff --git a/KeePassium/database/ChooseKeyFileVC.swift b/KeePassium/database/ChooseKeyFileVC.swift index fa5d0d65b..6266da1be 100644 --- a/KeePassium/database/ChooseKeyFileVC.swift +++ b/KeePassium/database/ChooseKeyFileVC.swift @@ -53,6 +53,11 @@ class ChooseKeyFileVC: UITableViewController, Refreshable { refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged) self.refreshControl = refreshControl + let longPressGestureRecognizer = UILongPressGestureRecognizer( + target: self, + action: #selector(didLongPressTableView)) + tableView.addGestureRecognizer(longPressGestureRecognizer) + refresh() self.clearsSelectionOnViewWillAppear = true } @@ -117,6 +122,15 @@ class ChooseKeyFileVC: UITableViewController, Refreshable { } } + @objc func didLongPressTableView(_ gestureRecognizer: UILongPressGestureRecognizer) { + let point = gestureRecognizer.location(in: tableView) + guard gestureRecognizer.state == .began, + let indexPath = tableView.indexPathForRow(at: point), + tableView(tableView, canEditRowAt: indexPath), + let cell = tableView.cellForRow(at: indexPath) else { return } + cell.demoShowEditActions(lastActionColor: UIColor.destructiveTint) + } + override func numberOfSections(in tableView: UITableView) -> Int { return 1 diff --git a/KeePassium/database/DatabaseCreatorVC.storyboard b/KeePassium/database/DatabaseCreatorVC.storyboard index eb44aede9..0b6ba1c39 100644 --- a/KeePassium/database/DatabaseCreatorVC.storyboard +++ b/KeePassium/database/DatabaseCreatorVC.storyboard @@ -259,6 +259,7 @@ + diff --git a/KeePassium/database/DatabaseCreatorVC.swift b/KeePassium/database/DatabaseCreatorVC.swift index de5f8ea07..d38ca0b06 100644 --- a/KeePassium/database/DatabaseCreatorVC.swift +++ b/KeePassium/database/DatabaseCreatorVC.swift @@ -32,6 +32,7 @@ class DatabaseCreatorVC: UIViewController { @IBOutlet var errorMessagePanel: UIView! @IBOutlet weak var errorLabel: UILabel! @IBOutlet weak var keyboardLayoutConstraint: KeyboardLayoutConstraint! + @IBOutlet weak var scrollView: UIScrollView! weak var delegate: DatabaseCreatorDelegate? @@ -109,13 +110,24 @@ class DatabaseCreatorVC: UIViewController { func setError(message: String?, animated: Bool) { errorLabel.text = message - let visible = message?.isNotEmpty ?? false + let isToShow = message?.isNotEmpty ?? false + let isToHide = !isToShow + + if isToShow { + self.scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: animated) + } + + guard errorMessagePanel.isHidden != isToHide else { + return + } if animated { - UIView.animate(withDuration: 0.3) { - self.errorMessagePanel.isHidden = !visible + UIView.animate(withDuration: 0.3) { + self.errorMessagePanel.isHidden = isToHide + self.errorMessagePanel.superview?.layoutIfNeeded() } } else { - self.errorMessagePanel.isHidden = !visible + errorMessagePanel.isHidden = isToHide + errorMessagePanel.superview?.layoutIfNeeded() } } diff --git a/KeePassium/database/entry/ViewableEntryFieldFactory.swift b/KeePassium/database/entry/ViewableEntryFieldFactory.swift index 7fcacdd67..ced39c5ca 100755 --- a/KeePassium/database/entry/ViewableEntryFieldFactory.swift +++ b/KeePassium/database/entry/ViewableEntryFieldFactory.swift @@ -137,7 +137,7 @@ class ViewableEntryFieldFactory { result.append(viewableField) } - if let _ = TOTPGeneratorFactory.makeGenerator(from: entry.fields), + if let _ = TOTPGeneratorFactory.makeGenerator(for: entry), !excludeNonEditable { result.append(TOTPViewableField(fields: entry.fields)) diff --git a/KeePassium/database/group/ViewGroupVC.swift b/KeePassium/database/group/ViewGroupVC.swift index cbd71abc5..da49cbdfb 100755 --- a/KeePassium/database/group/ViewGroupVC.swift +++ b/KeePassium/database/group/ViewGroupVC.swift @@ -95,6 +95,11 @@ open class ViewGroupVC: UITableViewController, Refreshable { groupChangeNotifications = GroupChangeNotifications(observer: self) entryChangeNotifications = EntryChangeNotifications(observer: self) settingsNotifications = SettingsNotifications(observer: self) + + let longPressGestureRecognizer = UILongPressGestureRecognizer( + target: self, + action: #selector(didLongPressTableView)) + tableView.addGestureRecognizer(longPressGestureRecognizer) } override open func viewDidAppear(_ animated: Bool) { @@ -601,6 +606,15 @@ open class ViewGroupVC: UITableViewController, Refreshable { present(vc, animated: true, completion: nil) } + @objc func didLongPressTableView(_ gestureRecognizer: UILongPressGestureRecognizer) { + let point = gestureRecognizer.location(in: tableView) + guard gestureRecognizer.state == .began, + let indexPath = tableView.indexPathForRow(at: point), + tableView(tableView, canEditRowAt: indexPath), + let cell = tableView.cellForRow(at: indexPath) else { return } + cell.demoShowEditActions(lastActionColor: UIColor.destructiveTint) + } + func saveDatabase() { databaseManagerNotifications.startObserving() diff --git a/KeePassium/general/AboutVC.storyboard b/KeePassium/general/AboutVC.storyboard index 708142f2c..12610fd40 100755 --- a/KeePassium/general/AboutVC.storyboard +++ b/KeePassium/general/AboutVC.storyboard @@ -153,17 +153,18 @@