Created
June 12, 2020 23:42
-
-
Save nbhasin2/b70548933d37a144daa3308e2ea6cee0 to your computer and use it in GitHub Desktop.
6779.patch - sample diff for https://github.com/mozilla-mobile/firefox-ios/pull/6779/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/Client.xcodeproj/project.pbxproj b/Client.xcodeproj/project.pbxproj | |
| index b0a2f2129..a1345ccc4 100644 | |
| --- a/Client.xcodeproj/project.pbxproj | |
| +++ b/Client.xcodeproj/project.pbxproj | |
| @@ -252,6 +252,8 @@ | |
| 435D7CC02461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CBF2461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift */; }; | |
| 435D7CC32461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CC22461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift */; }; | |
| 435D7CC5246209AA0043ACB9 /* IntroViewControllerV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CC4246209AA0043ACB9 /* IntroViewControllerV2.swift */; }; | |
| + 4360D9AC24943AF10041EE16 /* ListSelectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4360D9AB24943AF10041EE16 /* ListSelectionController.swift */; }; | |
| + 4360D9AF24943C220041EE16 /* LoginDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4360D9AE24943C220041EE16 /* LoginDataSource.swift */; }; | |
| 4390F7F1246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7F0246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift */; }; | |
| 4390F7F5246CE04300570811 /* IntroViewModelV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7F4246CE04300570811 /* IntroViewModelV2.swift */; }; | |
| 4390F7FF246DAFBE00570811 /* FirefoxColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7FE246DAFBE00570811 /* FirefoxColors.swift */; }; | |
| @@ -1400,6 +1402,8 @@ | |
| 435D7CC22461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroScreenSyncViewV2.swift; sourceTree = "<group>"; }; | |
| 435D7CC4246209AA0043ACB9 /* IntroViewControllerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroViewControllerV2.swift; sourceTree = "<group>"; }; | |
| 435FAB17242404B400AE9310 /* FullscreenHelper.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FullscreenHelper.js; path = Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/FullscreenHelper.js; sourceTree = SOURCE_ROOT; }; | |
| + 4360D9AB24943AF10041EE16 /* ListSelectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListSelectionController.swift; sourceTree = "<group>"; }; | |
| + 4360D9AE24943C220041EE16 /* LoginDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDataSource.swift; sourceTree = "<group>"; }; | |
| 4390F7F0246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroWelcomeAndSyncViewV1.swift; sourceTree = "<group>"; }; | |
| 4390F7F4246CE04300570811 /* IntroViewModelV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroViewModelV2.swift; sourceTree = "<group>"; }; | |
| 4390F7FE246DAFBE00570811 /* FirefoxColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxColors.swift; sourceTree = "<group>"; }; | |
| @@ -3135,6 +3139,8 @@ | |
| E63ED7D71BFCD9990097D08E /* LoginTableViewCell.swift */, | |
| E63ED8E01BFD25580097D08E /* LoginListViewController.swift */, | |
| CA520E7924913C1B00CCAB48 /* LoginListViewModel.swift */, | |
| + 4360D9AB24943AF10041EE16 /* ListSelectionController.swift */, | |
| + 4360D9AE24943C220041EE16 /* LoginDataSource.swift */, | |
| E633E2D91C21EAF8001FFF6C /* LoginDetailViewController.swift */, | |
| CA77ABF424772D98005079F9 /* BreachAlertsManager.swift */, | |
| CA03B269247F1D9E00382B62 /* BreachAlertsClient.swift */, | |
| @@ -5123,6 +5129,7 @@ | |
| D87F84AC20B891160091F2DA /* TabDisplayManager.swift in Sources */, | |
| D0C95EF6201A55A800E4E51C /* BrowserViewController+UIDropInteractionDelegate.swift in Sources */, | |
| D31CF65C1CC1959A001D0BD0 /* PrivilegedRequest.swift in Sources */, | |
| + 4360D9AF24943C220041EE16 /* LoginDataSource.swift in Sources */, | |
| D8D33A7D1FBD080300A20A28 /* SnapKitExtensions.swift in Sources */, | |
| E650755C1E37F747006961AC /* Swizzling.m in Sources */, | |
| 74821FC51DB56A2500EEEA72 /* OpenWithSettingsViewController.swift in Sources */, | |
| @@ -5171,6 +5178,7 @@ | |
| E6927EC01C7B6FB800D03F75 /* ErrorToast.swift in Sources */, | |
| D30B101E1AA7F9C600C01CA3 /* LibraryPanels.swift in Sources */, | |
| F84B22041A0910F600AAB793 /* AppDelegate.swift in Sources */, | |
| + 4360D9AC24943AF10041EE16 /* ListSelectionController.swift in Sources */, | |
| D8C75DF3207584C400BB8AD0 /* UIImageViewAligned.m in Sources */, | |
| E653422D1C5944F90039DD9E /* BrowserPrompts.swift in Sources */, | |
| 2FDE87FE1ABB3817005317B1 /* RemoteTabsPanel.swift in Sources */, | |
| diff --git a/Client/Frontend/Login Management/ListSelectionController.swift b/Client/Frontend/Login Management/ListSelectionController.swift | |
| new file mode 100644 | |
| index 000000000..9408abfa5 | |
| --- /dev/null | |
| +++ b/Client/Frontend/Login Management/ListSelectionController.swift | |
| @@ -0,0 +1,47 @@ | |
| +/* This Source Code Form is subject to the terms of the Mozilla Public | |
| + * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| + | |
| +import Foundation | |
| + | |
| +/// Controller that keeps track of selected indexes | |
| +class ListSelectionController: NSObject { | |
| + private unowned let tableView: UITableView | |
| + private(set) var selectedIndexPaths = [IndexPath]() | |
| + | |
| + var selectedCount: Int { | |
| + return selectedIndexPaths.count | |
| + } | |
| + | |
| + init(tableView: UITableView) { | |
| + self.tableView = tableView | |
| + super.init() | |
| + } | |
| + | |
| + func selectIndexPath(_ indexPath: IndexPath) { | |
| + selectedIndexPaths.append(indexPath) | |
| + } | |
| + | |
| + func indexPathIsSelected(_ indexPath: IndexPath) -> Bool { | |
| + return selectedIndexPaths.contains(indexPath) { path1, path2 in | |
| + return path1.row == path2.row && path1.section == path2.section | |
| + } | |
| + } | |
| + | |
| + func deselectIndexPath(_ indexPath: IndexPath) { | |
| + guard let foundSelectedPath = (selectedIndexPaths.filter { $0.row == indexPath.row && $0.section == indexPath.section }).first, | |
| + let indexToRemove = selectedIndexPaths.firstIndex(of: foundSelectedPath) else { | |
| + return | |
| + } | |
| + | |
| + selectedIndexPaths.remove(at: indexToRemove) | |
| + } | |
| + | |
| + func deselectAll() { | |
| + selectedIndexPaths.removeAll() | |
| + } | |
| + | |
| + func selectIndexPaths(_ indexPaths: [IndexPath]) { | |
| + selectedIndexPaths += indexPaths | |
| + } | |
| +} | |
| diff --git a/Client/Frontend/Login Management/LoginDataSource.swift b/Client/Frontend/Login Management/LoginDataSource.swift | |
| new file mode 100644 | |
| index 000000000..06832e6cf | |
| --- /dev/null | |
| +++ b/Client/Frontend/Login Management/LoginDataSource.swift | |
| @@ -0,0 +1,76 @@ | |
| +/* This Source Code Form is subject to the terms of the Mozilla Public | |
| + * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| + | |
| +import UIKit | |
| +import Storage | |
| +import Shared | |
| +import Foundation | |
| + | |
| +/// Data source for handling LoginData objects from a Cursor | |
| +class LoginDataSource: NSObject, UITableViewDataSource { | |
| + fileprivate let emptyStateView = NoLoginsView() | |
| + fileprivate var viewModel: LoginListViewModel | |
| + | |
| + let boolSettings: (BoolSetting, BoolSetting) | |
| + | |
| + init(viewModel: LoginListViewModel) { | |
| + self.viewModel = viewModel | |
| + boolSettings = ( | |
| + BoolSetting(prefs: viewModel.profile.prefs, prefKey: PrefsKeys.LoginsSaveEnabled, defaultValue: true, attributedTitleText: NSAttributedString(string: Strings.SettingToSaveLogins)), | |
| + BoolSetting(prefs: viewModel.profile.prefs, prefKey: PrefsKeys.LoginsShowShortcutMenuItem, defaultValue: true, attributedTitleText: NSAttributedString(string: Strings.SettingToShowLoginsInAppMenu))) | |
| + super.init() | |
| + } | |
| + | |
| + @objc func numberOfSections(in tableView: UITableView) -> Int { | |
| + if viewModel.dataSourceViewModel.loginRecordSections.isEmpty { | |
| + tableView.backgroundView = emptyStateView | |
| + return 1 | |
| + } | |
| + | |
| + tableView.backgroundView = nil | |
| + // Add one section for the settings section. | |
| + return viewModel.dataSourceViewModel.loginRecordSections.count + 1 | |
| + } | |
| + | |
| + @objc func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
| + if section == LoginsSettingsSection { | |
| + return 2 | |
| + } | |
| + return viewModel.dataSourceViewModel.loginsForSection(section)?.count ?? 0 | |
| + } | |
| + | |
| + @objc func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
| + let cell = ThemedTableViewCell(style: .subtitle, reuseIdentifier: CellReuseIdentifier) | |
| + | |
| + if indexPath.section == LoginsSettingsSection { | |
| + let hideSettings = viewModel.dataSourceViewModel.searchController?.isActive ?? false || tableView.isEditing | |
| + let setting = indexPath.row == 0 ? boolSettings.0 : boolSettings.1 | |
| + setting.onConfigureCell(cell) | |
| + if hideSettings { | |
| + cell.isHidden = true | |
| + } | |
| + | |
| + // Fade in the cell while dismissing the search or the cell showing suddenly looks janky | |
| + if viewModel.isDuringSearchControllerDismiss { | |
| + cell.isHidden = false | |
| + cell.contentView.alpha = 0 | |
| + cell.accessoryView?.alpha = 0 | |
| + UIView.animate(withDuration: 0.6) { | |
| + cell.contentView.alpha = 1 | |
| + cell.accessoryView?.alpha = 1 | |
| + } | |
| + } | |
| + } else { | |
| + guard let login = viewModel.dataSourceViewModel.loginAtIndexPath(indexPath) else { return cell } | |
| + cell.textLabel?.text = login.hostname | |
| + cell.detailTextColor = UIColor.theme.tableView.rowDetailText | |
| + cell.detailTextLabel?.text = login.username | |
| + cell.accessoryType = .disclosureIndicator | |
| + } | |
| + // Need to override the default background multi-select color to support theming | |
| + cell.multipleSelectionBackgroundView = UIView() | |
| + cell.applyTheme() | |
| + return cell | |
| + } | |
| +} | |
| diff --git a/Client/Frontend/Login Management/LoginListViewController.swift b/Client/Frontend/Login Management/LoginListViewController.swift | |
| index 89d98b204..5aafa2762 100644 | |
| --- a/Client/Frontend/Login Management/LoginListViewController.swift | |
| +++ b/Client/Frontend/Login Management/LoginListViewController.swift | |
| @@ -18,9 +18,9 @@ private extension UITableView { | |
| } | |
| } | |
| -private let CellReuseIdentifier = "cell-reuse-id" | |
| -private let SectionHeaderId = "section-header-id" | |
| -private let LoginsSettingsSection = 0 | |
| +let CellReuseIdentifier = "cell-reuse-id" | |
| +let SectionHeaderId = "section-header-id" | |
| +let LoginsSettingsSection = 0 | |
| class LoginListViewController: SensitiveViewController { | |
| @@ -241,15 +241,13 @@ extension LoginListViewController: UISearchResultsUpdating { | |
| } | |
| } | |
| -fileprivate var isDuringSearchControllerDismiss = false | |
| - | |
| extension LoginListViewController: UISearchControllerDelegate { | |
| func willDismissSearchController(_ searchController: UISearchController) { | |
| - isDuringSearchControllerDismiss = true | |
| + viewModel.isDuringSearchControllerDismiss = true | |
| } | |
| func didDismissSearchController(_ searchController: UISearchController) { | |
| - isDuringSearchControllerDismiss = false | |
| + viewModel.isDuringSearchControllerDismiss = false | |
| } | |
| } | |
| @@ -431,112 +429,3 @@ extension LoginListViewController: SearchInputViewDelegate { | |
| } | |
| } | |
| -/// Controller that keeps track of selected indexes | |
| -fileprivate class ListSelectionController: NSObject { | |
| - private unowned let tableView: UITableView | |
| - private(set) var selectedIndexPaths = [IndexPath]() | |
| - | |
| - var selectedCount: Int { | |
| - return selectedIndexPaths.count | |
| - } | |
| - | |
| - init(tableView: UITableView) { | |
| - self.tableView = tableView | |
| - super.init() | |
| - } | |
| - | |
| - func selectIndexPath(_ indexPath: IndexPath) { | |
| - selectedIndexPaths.append(indexPath) | |
| - } | |
| - | |
| - func indexPathIsSelected(_ indexPath: IndexPath) -> Bool { | |
| - return selectedIndexPaths.contains(indexPath) { path1, path2 in | |
| - return path1.row == path2.row && path1.section == path2.section | |
| - } | |
| - } | |
| - | |
| - func deselectIndexPath(_ indexPath: IndexPath) { | |
| - guard let foundSelectedPath = (selectedIndexPaths.filter { $0.row == indexPath.row && $0.section == indexPath.section }).first, | |
| - let indexToRemove = selectedIndexPaths.firstIndex(of: foundSelectedPath) else { | |
| - return | |
| - } | |
| - | |
| - selectedIndexPaths.remove(at: indexToRemove) | |
| - } | |
| - | |
| - func deselectAll() { | |
| - selectedIndexPaths.removeAll() | |
| - } | |
| - | |
| - func selectIndexPaths(_ indexPaths: [IndexPath]) { | |
| - selectedIndexPaths += indexPaths | |
| - } | |
| -} | |
| - | |
| -/// Data source for handling LoginData objects from a Cursor | |
| -class LoginDataSource: NSObject, UITableViewDataSource { | |
| - fileprivate let emptyStateView = NoLoginsView() | |
| - fileprivate var viewModel: LoginListViewModel | |
| - | |
| - let boolSettings: (BoolSetting, BoolSetting) | |
| - | |
| - init(viewModel: LoginListViewModel) { | |
| - self.viewModel = viewModel | |
| - boolSettings = ( | |
| - BoolSetting(prefs: viewModel.profile.prefs, prefKey: PrefsKeys.LoginsSaveEnabled, defaultValue: true, attributedTitleText: NSAttributedString(string: Strings.SettingToSaveLogins)), | |
| - BoolSetting(prefs: viewModel.profile.prefs, prefKey: PrefsKeys.LoginsShowShortcutMenuItem, defaultValue: true, attributedTitleText: NSAttributedString(string: Strings.SettingToShowLoginsInAppMenu))) | |
| - super.init() | |
| - } | |
| - | |
| - @objc func numberOfSections(in tableView: UITableView) -> Int { | |
| - if viewModel.dataSourceViewModel.loginRecordSections.isEmpty { | |
| - tableView.backgroundView = emptyStateView | |
| - return 1 | |
| - } | |
| - | |
| - tableView.backgroundView = nil | |
| - // Add one section for the settings section. | |
| - return viewModel.dataSourceViewModel.loginRecordSections.count + 1 | |
| - } | |
| - | |
| - @objc func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
| - if section == LoginsSettingsSection { | |
| - return 2 | |
| - } | |
| - return viewModel.dataSourceViewModel.loginsForSection(section)?.count ?? 0 | |
| - } | |
| - | |
| - @objc func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
| - let cell = ThemedTableViewCell(style: .subtitle, reuseIdentifier: CellReuseIdentifier) | |
| - | |
| - if indexPath.section == LoginsSettingsSection { | |
| - let hideSettings = viewModel.dataSourceViewModel.searchController?.isActive ?? false || tableView.isEditing | |
| - let setting = indexPath.row == 0 ? boolSettings.0 : boolSettings.1 | |
| - setting.onConfigureCell(cell) | |
| - if hideSettings { | |
| - cell.isHidden = true | |
| - } | |
| - | |
| - // Fade in the cell while dismissing the search or the cell showing suddenly looks janky | |
| - if isDuringSearchControllerDismiss { | |
| - cell.isHidden = false | |
| - cell.contentView.alpha = 0 | |
| - cell.accessoryView?.alpha = 0 | |
| - UIView.animate(withDuration: 0.6) { | |
| - cell.contentView.alpha = 1 | |
| - cell.accessoryView?.alpha = 1 | |
| - } | |
| - } | |
| - } else { | |
| - guard let login = viewModel.dataSourceViewModel.loginAtIndexPath(indexPath) else { return cell } | |
| - cell.textLabel?.text = login.hostname | |
| - cell.detailTextColor = UIColor.theme.tableView.rowDetailText | |
| - cell.detailTextLabel?.text = login.username | |
| - cell.accessoryType = .disclosureIndicator | |
| - } | |
| - // Need to override the default background multi-select color to support theming | |
| - cell.multipleSelectionBackgroundView = UIView() | |
| - cell.applyTheme() | |
| - return cell | |
| - } | |
| -} | |
| diff --git a/Client/Frontend/Login Management/LoginListViewModel.swift b/Client/Frontend/Login Management/LoginListViewModel.swift | |
| index 83425a6ae..5068c9943 100644 | |
| --- a/Client/Frontend/Login Management/LoginListViewModel.swift | |
| +++ b/Client/Frontend/Login Management/LoginListViewModel.swift | |
| @@ -13,6 +13,10 @@ final class LoginListViewModel { | |
| let profile: Profile | |
| fileprivate var activeLoginQuery: Deferred<Maybe<[LoginRecord]>>? | |
| var dataSourceViewModel: LoginListDataSourceViewModel | |
| +// fileprivate lazy var loginSelectionController: ListSelectionController = { | |
| +// return ListSelectionController(tableView: self.tableView) | |
| +// }() | |
| + var isDuringSearchControllerDismiss = false | |
| init(profile: Profile, searchController: UISearchController) { | |
| self.profile = profile | |
| diff --git a/Client/Frontend/Login Management/NoLoginsView.swift b/Client/Frontend/Login Management/NoLoginsView.swift | |
| index ea6f67eb1..df7929fca 100644 | |
| --- a/Client/Frontend/Login Management/NoLoginsView.swift | |
| +++ b/Client/Frontend/Login Management/NoLoginsView.swift | |
| @@ -1,11 +1,6 @@ | |
| -// | |
| -// NoLoginsView.swift | |
| -// Client | |
| -// | |
| -// Created by Vanna Phong on 6/11/20. | |
| -// Copyright © 2020 Mozilla. All rights reserved. | |
| -// | |
| - | |
| +/* This Source Code Form is subject to the terms of the Mozilla Public | |
| + * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| import Foundation | |
| /// Empty state view when there is no logins to display. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment