2017-01-19 21:15:47 +08:00
|
|
|
//
|
|
|
|
|
// PasswordTableViewController.swift
|
|
|
|
|
// pass
|
|
|
|
|
//
|
|
|
|
|
// Created by Mingshen Sun on 18/1/2017.
|
|
|
|
|
// Copyright © 2017 Bob Sun. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
|
import Result
|
|
|
|
|
import SVProgressHUD
|
|
|
|
|
|
2017-01-23 12:48:20 +08:00
|
|
|
|
2017-01-23 13:43:06 +08:00
|
|
|
class PasswordsTableViewController: UITableViewController {
|
2017-01-19 21:15:47 +08:00
|
|
|
private var passwordEntities: [PasswordEntity]?
|
2017-01-23 12:48:20 +08:00
|
|
|
var filteredPasswordEntities = [PasswordEntity]()
|
|
|
|
|
let searchController = UISearchController(searchResultsController: nil)
|
2017-02-02 15:03:34 +08:00
|
|
|
var sections : [(index: Int, length :Int, title: String)] = Array()
|
2017-01-23 13:43:06 +08:00
|
|
|
|
2017-01-23 16:29:36 +08:00
|
|
|
@IBAction func refreshPasswords(_ sender: UIBarButtonItem) {
|
2017-01-23 17:36:10 +08:00
|
|
|
SVProgressHUD.setDefaultMaskType(.black)
|
|
|
|
|
SVProgressHUD.show(withStatus: "Pull Remote Repository")
|
2017-01-23 16:29:36 +08:00
|
|
|
DispatchQueue.global(qos: .userInitiated).async {
|
2017-01-23 17:36:10 +08:00
|
|
|
if PasswordStore.shared.pullRepository(transferProgressBlock: {(git_transfer_progress, stop) in
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
|
SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Pull Remote Repository")
|
|
|
|
|
}
|
|
|
|
|
}) {
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
|
SVProgressHUD.showSuccess(withStatus: "Done")
|
|
|
|
|
SVProgressHUD.dismiss(withDelay: 1)
|
|
|
|
|
}
|
2017-01-23 16:29:36 +08:00
|
|
|
print("pull success")
|
|
|
|
|
self.passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData()
|
2017-02-02 16:09:54 +08:00
|
|
|
self.generateSections(item: self.passwordEntities!)
|
2017-01-23 16:29:36 +08:00
|
|
|
self.tableView.reloadData()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-19 21:15:47 +08:00
|
|
|
override func viewDidLoad() {
|
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData()
|
2017-01-23 13:43:06 +08:00
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(PasswordsTableViewController.actOnPasswordUpdatedNotification), name: NSNotification.Name(rawValue: "passwordUpdated"), object: nil)
|
2017-01-23 12:48:20 +08:00
|
|
|
searchController.searchResultsUpdater = self
|
|
|
|
|
searchController.dimsBackgroundDuringPresentation = false
|
|
|
|
|
definesPresentationContext = true
|
2017-02-01 23:15:44 +08:00
|
|
|
// tableView.setContentOffset(CGPoint(x: 0, y: 44), animated: false)
|
2017-02-02 15:03:34 +08:00
|
|
|
generateSections(item: passwordEntities!)
|
2017-02-02 16:09:54 +08:00
|
|
|
tableView.tableHeaderView = searchController.searchBar
|
2017-02-02 15:03:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
|
|
|
return sections.count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func generateSections(item: [PasswordEntity]) {
|
|
|
|
|
sections.removeAll()
|
|
|
|
|
if item.count == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var index = 0
|
|
|
|
|
for i in 0 ..< item.count {
|
|
|
|
|
let name = item[index].name!.uppercased()
|
|
|
|
|
let commonPrefix = item[i].name!.commonPrefix(with: name, options: .caseInsensitive)
|
|
|
|
|
if commonPrefix.characters.count == 0 {
|
|
|
|
|
let firstCharacter = name[name.startIndex]
|
|
|
|
|
let newSection = (index: index, length: i - index, title: "\(firstCharacter)")
|
|
|
|
|
print("index: \(index), length: \(newSection.length), title: \(newSection.title)")
|
|
|
|
|
sections.append(newSection)
|
|
|
|
|
index = i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let name = item[index].name!.uppercased()
|
|
|
|
|
let firstCharacter = name[name.startIndex]
|
|
|
|
|
let newSection = (index: index, length: item.count - index, title: "\(firstCharacter)")
|
|
|
|
|
sections.append(newSection)
|
2017-01-23 12:48:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func filterContentForSearchText(searchText: String, scope: String = "All") {
|
|
|
|
|
filteredPasswordEntities = passwordEntities!.filter { password in
|
|
|
|
|
return password.name!.lowercased().contains(searchText.lowercased())
|
|
|
|
|
}
|
2017-02-02 15:03:34 +08:00
|
|
|
if searchController.isActive && searchController.searchBar.text != "" {
|
|
|
|
|
generateSections(item: filteredPasswordEntities)
|
|
|
|
|
} else {
|
|
|
|
|
generateSections(item: passwordEntities!)
|
|
|
|
|
}
|
2017-01-23 12:48:20 +08:00
|
|
|
tableView.reloadData()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
|
|
|
super.viewWillAppear(animated)
|
2017-01-19 21:15:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func actOnPasswordUpdatedNotification() {
|
|
|
|
|
passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData()
|
|
|
|
|
self.tableView.reloadData()
|
|
|
|
|
print("actOnPasswordUpdatedNotification")
|
|
|
|
|
}
|
2017-01-23 13:43:06 +08:00
|
|
|
|
2017-01-19 21:15:47 +08:00
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
2017-02-02 15:03:34 +08:00
|
|
|
// if searchController.isActive && searchController.searchBar.text != "" {
|
|
|
|
|
// return filteredPasswordEntities.count
|
|
|
|
|
// }
|
|
|
|
|
// return passwordEntities!.count
|
|
|
|
|
return sections[section].length
|
2017-01-19 21:15:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath)
|
2017-02-02 15:03:34 +08:00
|
|
|
var password: PasswordEntity
|
|
|
|
|
let index = sections[indexPath.section].index + indexPath.row
|
2017-01-23 12:48:20 +08:00
|
|
|
if searchController.isActive && searchController.searchBar.text != "" {
|
2017-02-02 15:03:34 +08:00
|
|
|
password = filteredPasswordEntities[index]
|
2017-01-23 12:48:20 +08:00
|
|
|
} else {
|
2017-02-02 15:03:34 +08:00
|
|
|
password = passwordEntities![index]
|
2017-01-23 12:48:20 +08:00
|
|
|
}
|
|
|
|
|
cell.textLabel?.text = password.name
|
2017-01-19 21:15:47 +08:00
|
|
|
return cell
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-02 15:03:34 +08:00
|
|
|
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
|
|
|
return sections[section].title
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
|
|
|
|
|
return sections.map { $0.title }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
|
|
|
|
|
return index
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-22 01:42:36 +08:00
|
|
|
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
|
|
|
if segue.identifier == "showPasswordDetail" {
|
|
|
|
|
if let viewController = segue.destination as? PasswordDetailViewController {
|
2017-02-02 15:03:34 +08:00
|
|
|
let selectedIndexPath = self.tableView.indexPath(for: sender as! UITableViewCell)!
|
|
|
|
|
let index = sections[selectedIndexPath.section].index + selectedIndexPath.row
|
2017-01-23 12:48:20 +08:00
|
|
|
let password: PasswordEntity
|
|
|
|
|
if searchController.isActive && searchController.searchBar.text != "" {
|
2017-02-02 15:03:34 +08:00
|
|
|
password = filteredPasswordEntities[index]
|
2017-01-23 12:48:20 +08:00
|
|
|
} else {
|
2017-02-02 15:03:34 +08:00
|
|
|
password = passwordEntities![index]
|
2017-01-23 12:48:20 +08:00
|
|
|
}
|
|
|
|
|
viewController.passwordEntity = password
|
2017-01-23 13:12:22 +08:00
|
|
|
viewController.navigationItem.title = password.name
|
2017-01-22 01:42:36 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-19 21:15:47 +08:00
|
|
|
}
|
2017-01-23 16:29:36 +08:00
|
|
|
|
|
|
|
|
extension PasswordsTableViewController: UISearchResultsUpdating {
|
|
|
|
|
func updateSearchResults(for searchController: UISearchController) {
|
|
|
|
|
filterContentForSearchText(searchText: searchController.searchBar.text!)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|