Localize strings in code
This commit is contained in:
parent
2d5ca58bd9
commit
1b4040135e
36 changed files with 626 additions and 334 deletions
|
|
@ -140,7 +140,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
* The store could not be migrated to the current model version.
|
||||
Check the error message to determine what the actual problem was.
|
||||
*/
|
||||
fatalError("Unresolved error \(error), \(error.userInfo)")
|
||||
fatalError("UnresolvedError".localize("\(error), \(error.userInfo)"))
|
||||
}
|
||||
})
|
||||
return container
|
||||
|
|
@ -157,7 +157,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// Replace this implementation with code to handle the error appropriately.
|
||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
let nserror = error as NSError
|
||||
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
|
||||
fatalError("UnresolvedError".localize("\(nserror), \(nserror.userInfo)"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import passKit
|
|||
|
||||
class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
||||
|
||||
private static let VALUE_NOT_AVAILABLE = "Value not available"
|
||||
private static let VALUE_NOT_AVAILABLE = "ValueNotAvailable".localize()
|
||||
|
||||
private var needRefresh = false
|
||||
private var indicator: UIActivityIndicatorView = {
|
||||
|
|
@ -62,12 +62,12 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
|||
let type = UITableViewCellAccessoryType.none
|
||||
strongSelf.tableData = [
|
||||
// section 0
|
||||
[[.style: CellDataStyle.value1, .accessoryType: type, .title: "Passwords", .detailText: passwords],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Size", .detailText: size],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Local Commits", .detailText: localCommits],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Last Synced", .detailText: lastSynced],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Commits", .detailText: commits],
|
||||
[.title: "Commit Logs", .action: "segue", .link: "showCommitLogsSegue"],
|
||||
[[.style: CellDataStyle.value1, .accessoryType: type, .title: "Passwords".localize(), .detailText: passwords],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Size".localize(), .detailText: size],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "LocalCommits".localize(), .detailText: localCommits],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "LastSynced".localize(), .detailText: lastSynced],
|
||||
[.style: CellDataStyle.value1, .accessoryType: type, .title: "Commits".localize(), .detailText: commits],
|
||||
[.title: "CommitLogs".localize(), .action: "segue", .link: "showCommitLogsSegue"],
|
||||
],
|
||||
]
|
||||
strongSelf.indicator.stopAnimating()
|
||||
|
|
@ -95,7 +95,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
|||
|
||||
private func lastSyncedTimeString() -> String {
|
||||
guard let date = self.passwordStore.lastSyncedTime else {
|
||||
return "Oops! Sync again?"
|
||||
return "SyncAgain?".localize()
|
||||
}
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = .medium
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ class AboutTableViewController: BasicStaticTableViewController {
|
|||
override func viewDidLoad() {
|
||||
tableData = [
|
||||
// section 0
|
||||
[[.title: "Website", .action: "link", .link: "https://github.com/mssun/pass-ios.git"],
|
||||
[.title: "Help", .action: "link", .link: "https://github.com/mssun/passforios/wiki"],
|
||||
[.title: "Contact Developer", .action: "link", .link: "mailto:developer@passforios.mssun.me?subject=Pass%20for%20iOS"],],
|
||||
[[.title: "Website".localize(), .action: "link", .link: "https://github.com/mssun/pass-ios.git"],
|
||||
[.title: "Help".localize(), .action: "link", .link: "https://github.com/mssun/passforios/wiki"],
|
||||
[.title: "ContactDeveloper".localize(), .action: "link", .link: "mailto:developer@passforios.mssun.me?subject=Pass%20for%20iOS"],],
|
||||
|
||||
// section 1,
|
||||
[[.title: "Open Source Components", .action: "segue", .link: "showOpenSourceComponentsSegue"],
|
||||
[.title: "Special Thanks", .action: "segue", .link: "showSpecialThanksSegue"],],
|
||||
[[.title: "OpenSourceComponents".localize(), .action: "segue", .link: "showOpenSourceComponentsSegue"],
|
||||
[.title: "SpecialThanks".localize(), .action: "segue", .link: "showSpecialThanksSegue"],],
|
||||
]
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ class AboutTableViewController: BasicStaticTableViewController {
|
|||
let view = UIView()
|
||||
let footerLabel = UILabel(frame: CGRect(x: 8, y: 15, width: tableView.frame.width, height: 60))
|
||||
footerLabel.numberOfLines = 0
|
||||
footerLabel.text = "Pass for iOS \(Bundle.main.releaseVersionNumber!) (\(Bundle.main.buildVersionNumber!))"
|
||||
footerLabel.text = "PassForIos".localize() + " \(Bundle.main.releaseVersionNumber!) (\(Bundle.main.buildVersionNumber!))"
|
||||
footerLabel.font = UIFont.preferredFont(forTextStyle: .footnote)
|
||||
footerLabel.textColor = UIColor.lightGray
|
||||
footerLabel.textAlignment = .center
|
||||
|
|
@ -41,7 +41,7 @@ class AboutTableViewController: BasicStaticTableViewController {
|
|||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
if section == 1 {
|
||||
return "Acknowledgements".uppercased()
|
||||
return "Acknowledgements".localize().uppercased()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
|
|||
if identifier == "saveAddPasswordSegue" {
|
||||
// check PGP key
|
||||
guard passwordStore.privateKey != nil else {
|
||||
let alertTitle = "Cannot Add Password"
|
||||
let alertMessage = "PGP Key is not set. Please set your PGP Key first."
|
||||
let alertTitle = "CannotAddPassword".localize()
|
||||
let alertMessage = "PgpKeyNotSet.".localize()
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,45 +41,38 @@ class AdvancedSettingsTableViewController: UITableViewController {
|
|||
self.gitSignatureTableViewCell.detailTextLabel?.text = "\(gitSignatureName) <\(gitSignatureEmail)>"
|
||||
if SharedDefaults[.gitSignatureName] == nil && SharedDefaults[.gitSignatureEmail] == nil {
|
||||
self.gitSignatureTableViewCell.detailTextLabel?.font = UIFont.systemFont(ofSize: 17)
|
||||
gitSignatureTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
gitSignatureTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
if tableView.cellForRow(at: indexPath) == eraseDataTableViewCell {
|
||||
let alert = UIAlertController(title: "Erase Password Store Data?", message: "This will delete all local data and settings. Password store data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Erase Password Data", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
SVProgressHUD.show(withStatus: "Erasing ...")
|
||||
let alert = UIAlertController(title: "ErasePasswordStoreData?".localize(), message: "EraseExplanation.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "ErasePasswordStoreData".localize(), style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
SVProgressHUD.show(withStatus: "Erasing...".localize())
|
||||
self.passwordStore.erase()
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||
SVProgressHUD.showSuccess(withStatus: "Done".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.cancel, handler:nil))
|
||||
alert.addAction(UIAlertAction(title: "Dismiss".localize(), style: UIAlertActionStyle.cancel, handler:nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
} else if tableView.cellForRow(at: indexPath) == discardChangesTableViewCell {
|
||||
let alert = UIAlertController(title: "Discard All Changes?", message: "Do you want to permanently discard all changes to the local copy of your password data? You cannot undo this action.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Discard All Changes", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
SVProgressHUD.show(withStatus: "Resetting ...")
|
||||
let alert = UIAlertController(title: "DiscardAllLocalChanges?".localize(), message: "DiscardExplanation.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "DiscardAllLocalChanges".localize(), style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
SVProgressHUD.show(withStatus: "Resetting...".localize())
|
||||
do {
|
||||
let numberDiscarded = try self.passwordStore.reset()
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
switch numberDiscarded {
|
||||
case 0:
|
||||
SVProgressHUD.showSuccess(withStatus: "No local commits")
|
||||
case 1:
|
||||
SVProgressHUD.showSuccess(withStatus: "Discarded 1 commit")
|
||||
default:
|
||||
SVProgressHUD.showSuccess(withStatus: "Discarded \(numberDiscarded) commits")
|
||||
}
|
||||
SVProgressHUD.showSuccess(withStatus: "DiscardedCommits(%d)".localize(numberDiscarded))
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.cancel, handler:nil))
|
||||
alert.addAction(UIAlertAction(title: "Dismiss".localize(), style: UIAlertActionStyle.cancel, handler:nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
|
|||
sendEmail(toRecipients: [urlComponents.path], subject: subject)
|
||||
} else {
|
||||
let email = urlComponents.path
|
||||
let alertTitle = "Cannot open Mail App"
|
||||
let alertMessage = "Email copied: \(email)"
|
||||
let alertTitle = "CannotOpenMail".localize()
|
||||
let alertMessage = "CopiedEmail".localize(email)
|
||||
Utils.copyToPasteboard(textToCopy: email)
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class CommitLogsTableViewController: UITableViewController {
|
|||
do {
|
||||
return try passwordStore.getRecentCommits(count: 20)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,22 +58,22 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
override func viewDidLoad() {
|
||||
tableData = [
|
||||
// section 0
|
||||
[[.title: "About Repository", .action: "segue", .link: "showAboutRepositorySegue"],],
|
||||
[[.title: "AboutRepository".localize(), .action: "segue", .link: "showAboutRepositorySegue"],],
|
||||
|
||||
// section 1
|
||||
[
|
||||
[.title: "Password Generator Flavor", .action: "none", .style: CellDataStyle.value1],
|
||||
[.title: "PasswordGeneratorFlavor".localize(), .action: "none", .style: CellDataStyle.value1],
|
||||
],
|
||||
|
||||
// section 2
|
||||
[
|
||||
[.title: "Remember PGP Key Passphrase", .action: "none",],
|
||||
[.title: "Remember Git Credential Passphrase", .action: "none",],
|
||||
[.title: "RememberPgpKeyPassphrase".localize(), .action: "none",],
|
||||
[.title: "RememberGitCredentialPassphrase".localize(), .action: "none",],
|
||||
],
|
||||
[
|
||||
[.title: "Show Folders", .action: "none",],
|
||||
[.title: "Hide Unknown Fields", .action: "none",],
|
||||
[.title: "Hide OTP Fields", .action: "none",],
|
||||
[.title: "ShowFolders".localize(), .action: "none",],
|
||||
[.title: "HideUnknownFields".localize(), .action: "none",],
|
||||
[.title: "HideOtpFields".localize(), .action: "none",],
|
||||
],
|
||||
|
||||
]
|
||||
|
|
@ -84,7 +84,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = super.tableView(tableView, cellForRowAt: indexPath)
|
||||
switch cell.textLabel!.text! {
|
||||
case "Hide Unknown Fields":
|
||||
case "HideUnknownFields".localize():
|
||||
cell.accessoryType = .none
|
||||
let detailButton = UIButton(type: .detailDisclosure)
|
||||
hideUnknownSwitch.frame = CGRect(x: detailButton.bounds.width+10, y: 0, width: hideUnknownSwitch.bounds.width, height: hideUnknownSwitch.bounds.height)
|
||||
|
|
@ -96,7 +96,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
cell.accessoryView = accessoryView
|
||||
cell.selectionStyle = .none
|
||||
hideUnknownSwitch.isOn = SharedDefaults[.isHideUnknownOn]
|
||||
case "Hide OTP Fields":
|
||||
case "HideOtpFields".localize():
|
||||
cell.accessoryType = .none
|
||||
let detailButton = UIButton(type: .detailDisclosure)
|
||||
hideOTPSwitch.frame = CGRect(x: detailButton.bounds.width+10, y: 0, width: hideOTPSwitch.bounds.width, height: hideOTPSwitch.bounds.height)
|
||||
|
|
@ -108,19 +108,19 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
cell.accessoryView = accessoryView
|
||||
cell.selectionStyle = .none
|
||||
hideOTPSwitch.isOn = SharedDefaults[.isHideOTPOn]
|
||||
case "Remember PGP Key Passphrase":
|
||||
case "RememberPgpKeyPassphrase".localize():
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = rememberPGPPassphraseSwitch
|
||||
case "Remember Git Credential Passphrase":
|
||||
case "RememberGitCredentialPassphrase".localize():
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = rememberGitCredentialPassphraseSwitch
|
||||
case "Show Folders":
|
||||
case "ShowFolders".localize():
|
||||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = showFolderSwitch
|
||||
case "Password Generator Flavor":
|
||||
case "PasswordGeneratorFlavor".localize():
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.detailTextLabel?.text = PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]).name
|
||||
default: break
|
||||
|
|
@ -131,7 +131,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
super.tableView(tableView, didSelectRowAt: indexPath)
|
||||
let cell = tableView.cellForRow(at: indexPath)!
|
||||
if cell.textLabel!.text! == "Password Generator Flavor" {
|
||||
if cell.textLabel!.text! == "PasswordGeneratorFlavor".localize() {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
showPasswordGeneratorFlavorActionSheet(sourceCell: cell)
|
||||
}
|
||||
|
|
@ -141,12 +141,12 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
var randomFlavorActionTitle = ""
|
||||
var appleFlavorActionTitle = ""
|
||||
randomFlavorActionTitle = "✓ Random String"
|
||||
appleFlavorActionTitle = "Apple's Keychain Style"
|
||||
if SharedDefaults[.passwordGeneratorFlavor] == PasswordGeneratorFlavour.RANDOM.rawValue {
|
||||
randomFlavorActionTitle = "✓ " + "RandomString".localize()
|
||||
appleFlavorActionTitle = "ApplesKeychainStyle".localize()
|
||||
} else {
|
||||
randomFlavorActionTitle = "Random String"
|
||||
appleFlavorActionTitle = "✓ Apple's Keychain Style"
|
||||
randomFlavorActionTitle = "RandomString".localize()
|
||||
appleFlavorActionTitle = "✓ " + "ApplesKeychainStyle".localize()
|
||||
}
|
||||
let randomFlavorAction = UIAlertAction(title: randomFlavorActionTitle, style: .default) { _ in
|
||||
SharedDefaults[.passwordGeneratorFlavor] = PasswordGeneratorFlavour.RANDOM.rawValue
|
||||
|
|
@ -158,7 +158,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
sourceCell.detailTextLabel?.text = PasswordGeneratorFlavour.APPLE.name
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
optionMenu.addAction(randomFlavorAction)
|
||||
optionMenu.addAction(appleFlavorAction)
|
||||
optionMenu.addAction(cancelAction)
|
||||
|
|
@ -168,15 +168,15 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
}
|
||||
|
||||
@objc func tapHideUnknownSwitchDetailButton(_ sender: Any?) {
|
||||
let alertMessage = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unknown\" keys. Turn on this switch to hide unsupported fields."
|
||||
let alertTitle = "Hide Unknown Fields"
|
||||
let alertMessage = "HideUnknownFieldsExplanation.".localize()
|
||||
let alertTitle = "HideUnknownFields".localize()
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
}
|
||||
|
||||
@objc func tapHideOTPSwitchDetailButton(_ sender: Any?) {
|
||||
let keywordsString = Constants.OTP_KEYWORDS.joined(separator: ",")
|
||||
let alertMessage = "Turn on this switch to hide the fields related to one time passwords (i.e., \(keywordsString))."
|
||||
let alertTitle = "Hide One Time Password Fields"
|
||||
let keywordsString = Constants.OTP_KEYWORDS.joined(separator: ", ")
|
||||
let alertMessage = "HideOtpFieldsExplanation.".localize(keywordsString)
|
||||
let alertTitle = "HideOtpFields".localize()
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class GitConfigSettingTableViewController: UITableViewController {
|
|||
let name = nameTextField.text!.isEmpty ? Globals.gitSignatureDefaultName : nameTextField.text!
|
||||
let email = emailTextField.text!.isEmpty ? Globals.gitSignatureDefaultEmail : nameTextField.text!
|
||||
guard GTSignature(name: name, email: email, time: nil) != nil else {
|
||||
Utils.alert(title: "Error", message: "Invalid name or email.", controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: "InvalidNameOrEmail".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
numberOfSegments = 0
|
||||
previousSegment = ""
|
||||
key = ""
|
||||
message = "Looking for the starting frame."
|
||||
message = "LookingForStartingFrame.".localize()
|
||||
hasStarted = false
|
||||
isDone = false
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
// check the number of segments
|
||||
numberOfSegments = numberOfSegments + 1
|
||||
guard numberOfSegments <= ScannedSSHKey.maxNumberOfGif else {
|
||||
key = "Too many QR codes"
|
||||
key = "TooManyQrCodes".localize()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
}
|
||||
|
||||
// update message
|
||||
message = "\(numberOfSegments) scanned QR codes."
|
||||
message = "ScannedQrCodes(%d)".localize(numberOfSegments)
|
||||
}
|
||||
}
|
||||
var scanned = ScannedSSHKey()
|
||||
|
|
@ -74,7 +74,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
armorPrivateKeyTextView.text = SharedDefaults[.gitSSHPrivateKeyArmor]
|
||||
armorPrivateKeyTextView.delegate = self
|
||||
|
||||
scanPrivateKeyCell?.textLabel?.text = "Scan Private Key QR Codes"
|
||||
scanPrivateKeyCell?.textLabel?.text = "ScanPrivateKeyQrCodes".localize()
|
||||
scanPrivateKeyCell?.textLabel?.textColor = Globals.blue
|
||||
scanPrivateKeyCell?.selectionStyle = .default
|
||||
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
||||
|
|
@ -85,7 +85,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
do {
|
||||
try passwordStore.initGitSSHKey(with: armorPrivateKeyTextView.text)
|
||||
} catch {
|
||||
Utils.alert(title: "Cannot Save", message: "Cannot Save SSH Key", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "CannotSaveSshKey".localize(), controller: self, completion: nil)
|
||||
}
|
||||
SharedDefaults[.gitSSHKeySource] = "armor"
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
|
|
@ -113,7 +113,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
|
|||
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
|
||||
scanned.addSegment(segment: line)
|
||||
if scanned.isDone {
|
||||
return (accept: true, message: "Done")
|
||||
return (accept: true, message: "Done".localize())
|
||||
} else {
|
||||
return (accept: false, message: scanned.message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Prepare Repository")
|
||||
SVProgressHUD.show(withStatus: "PrepareRepository".localize())
|
||||
var gitCredential: GitCredential
|
||||
if auth == "Password" {
|
||||
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username))
|
||||
|
|
@ -112,7 +112,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
},
|
||||
checkoutProgressBlock: { (path, completedSteps, totalSteps) in
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.showProgress(Float(completedSteps)/Float(totalSteps), status: "Checkout Master Branch")
|
||||
SVProgressHUD.showProgress(Float(completedSteps)/Float(totalSteps), status: "CheckingOutBranch".localize(branchName))
|
||||
}
|
||||
})
|
||||
DispatchQueue.main.async {
|
||||
|
|
@ -121,16 +121,16 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
SharedDefaults[.gitBranchName] = branchName
|
||||
SharedDefaults[.gitAuthenticationMethod] = auth
|
||||
SVProgressHUD.dismiss()
|
||||
let savePassphraseAlert = UIAlertController(title: "Done", message: "Do you want to save the Git credential password/passphrase?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let savePassphraseAlert = UIAlertController(title: "Done".localize(), message: "WantToSaveGitCredential?".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertActionStyle.default) { _ in
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = false
|
||||
self.passwordStore.gitPassword = nil
|
||||
self.passwordStore.gitSSHPrivateKeyPassphrase = nil
|
||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertActionStyle.destructive) {_ in
|
||||
SharedDefaults[.isRememberGitCredentialPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self)
|
||||
})
|
||||
|
|
@ -141,9 +141,9 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
let error = error as NSError
|
||||
var message = error.localizedDescription
|
||||
if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError {
|
||||
message = "\(message)\nUnderlying error: \(underlyingError.localizedDescription)"
|
||||
message = "\(message)\n\("UnderlyingError".localize()): \(underlyingError.localizedDescription)"
|
||||
}
|
||||
Utils.alert(title: "Error", message: message, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: message, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
} else if cell == authSSHKeyCell {
|
||||
|
||||
if !passwordStore.gitSSHKeyExists() {
|
||||
Utils.alert(title: "Cannot Select SSH Key", message: "Please setup SSH key first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSelectSshKey".localize(), message: "PleaseSetupSshKeyFirst.".localize(), controller: self, completion: nil)
|
||||
authenticationMethod = "Password"
|
||||
} else {
|
||||
authenticationMethod = "SSH Key"
|
||||
|
|
@ -170,7 +170,7 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
|
||||
// some sanity checks
|
||||
guard let gitURL = URL(string: gitURLTextField.text!) else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please set the Git repository URL.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetGitRepositoryUrl".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -179,28 +179,28 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
break
|
||||
case let val where val == "ssh":
|
||||
guard let sshUsername = gitURL.user, sshUsername.isEmpty == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Cannot find the username in the Git repository URL. Example URL: ssh://git@server/path/to/repo.git.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "CannotFindUsername.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
guard let username = usernameTextField.text, username == sshUsername else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please check the entered username and the username in the Git repository URL. They should match.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "CheckEnteredUsername.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
case let val where val == "http":
|
||||
Utils.alert(title: "Cannot Save", message: "Please use https instead of http.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "UseHttps.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
default:
|
||||
Utils.alert(title: "Cannot Save", message: "Please specify the scheme of the Git repository URL (https or ssh).", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SpecifySchema.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
|
||||
if passwordStore.repositoryExisted() {
|
||||
let alert = UIAlertController(title: "Overwrite?", message: "This operation will overwrite your current password store data (repository). Data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Overwrite", style: UIAlertActionStyle.destructive, handler: { _ in
|
||||
let alert = UIAlertController(title: "Overwrite?".localize(), message: "OperationWillOverwriteData.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Overwrite".localize(), style: UIAlertActionStyle.destructive, handler: { _ in
|
||||
// perform segue only after a successful clone
|
||||
self.cloneAndSegueIfSuccess()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: UIAlertActionStyle.cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
} else {
|
||||
// perform segue only after a successful clone
|
||||
|
|
@ -210,9 +210,9 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
|
||||
func showSSHKeyActionSheet() {
|
||||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
var urlActionTitle = "Download from URL"
|
||||
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
||||
var fileActionTitle = "iTunes File Sharing"
|
||||
var urlActionTitle = "DownloadFromUrl".localize()
|
||||
var armorActionTitle = "AsciiArmorEncryptedKey".localize()
|
||||
var fileActionTitle = "ITunesFileSharing".localize()
|
||||
|
||||
if SharedDefaults[.gitSSHKeySource] == "url" {
|
||||
urlActionTitle = "✓ \(urlActionTitle)"
|
||||
|
|
@ -227,41 +227,41 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
let armorAction = UIAlertAction(title: armorActionTitle, style: .default) { _ in
|
||||
self.performSegue(withIdentifier: "setGitSSHKeyByArmorSegue", sender: self)
|
||||
}
|
||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
optionMenu.addAction(urlAction)
|
||||
optionMenu.addAction(armorAction)
|
||||
|
||||
if passwordStore.gitSSHKeyExists(inFileSharing: true) {
|
||||
// might keys updated via iTunes, or downloaded/pasted inside the app
|
||||
fileActionTitle.append(" (Import)")
|
||||
fileActionTitle.append(" (\("Import".localize()))")
|
||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
do {
|
||||
try self.passwordStore.gitSSHKeyImportFromFileSharing()
|
||||
SharedDefaults[.gitSSHKeySource] = "file"
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported")
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
optionMenu.addAction(fileAction)
|
||||
} else {
|
||||
fileActionTitle.append(" (Tips)")
|
||||
fileActionTitle.append(" (\("Tips".localize()))")
|
||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
let title = "Tips"
|
||||
let message = "Copy your ASCII-armored private key to Pass with the name \"ssh_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish."
|
||||
let title = "Tips".localize()
|
||||
let message = "CopyPrivateKeyToPass.".localize()
|
||||
Utils.alert(title: title, message: message, controller: self)
|
||||
}
|
||||
optionMenu.addAction(fileAction)
|
||||
}
|
||||
|
||||
if SharedDefaults[.gitSSHKeySource] != nil {
|
||||
let deleteAction = UIAlertAction(title: "Remove Git SSH Keys", style: .destructive) { _ in
|
||||
let deleteAction = UIAlertAction(title: "RemoveSShKeys".localize(), style: .destructive) { _ in
|
||||
self.passwordStore.removeGitSSHKeys()
|
||||
SharedDefaults[.gitSSHKeySource] = nil
|
||||
if let sshLabel = self.sshLabel {
|
||||
sshLabel.isEnabled = false
|
||||
self.checkAuthenticationMethod(method: "Password")
|
||||
self.checkAuthenticationMethod(method: "Password".localize())
|
||||
}
|
||||
}
|
||||
optionMenu.addAction(deleteAction)
|
||||
|
|
@ -278,23 +278,23 @@ class GitServerSettingTableViewController: UITableViewController {
|
|||
var message = ""
|
||||
switch credential {
|
||||
case .http:
|
||||
message = "Please fill in the password of your Git account."
|
||||
message = "FillInGitAccountPassword.".localize()
|
||||
case .ssh:
|
||||
message = "Please fill in the passphrase of your SSH key."
|
||||
message = "FillInSshKeyPassphrase.".localize()
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.dismiss()
|
||||
let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
let alert = UIAlertController(title: "Password".localize(), message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||
textField.text = lastPassword ?? ""
|
||||
textField.isSecureTextEntry = true
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
password = alert.textFields!.first!.text
|
||||
sem.signal()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: .cancel) { _ in
|
||||
password = nil
|
||||
sem.signal()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
numberOfSegments = 0
|
||||
previousSegment = ""
|
||||
key = ""
|
||||
message = "Looking for the starting frame."
|
||||
message = "LookingForStartingFrame.".localize()
|
||||
hasStarted = false
|
||||
isDone = false
|
||||
}
|
||||
|
|
@ -55,12 +55,12 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
switch keyType {
|
||||
case .publicKey:
|
||||
if findPrivate {
|
||||
message = "Please scan public key."
|
||||
message = "ScanPrivateKey.".localize()
|
||||
}
|
||||
hasStarted = findPublic
|
||||
case .privateKey:
|
||||
if findPublic {
|
||||
message = "Please scan private key."
|
||||
message = "ScanPrivateKey.".localize()
|
||||
}
|
||||
hasStarted = findPrivate
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
// check the number of segments
|
||||
numberOfSegments = numberOfSegments + 1
|
||||
guard numberOfSegments <= ScannedPGPKey.maxNumberOfGif else {
|
||||
key = "Too many QR codes"
|
||||
key = "TooManyQrCodes"
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
}
|
||||
|
||||
// update message
|
||||
message = "\(numberOfSegments) scanned QR codes."
|
||||
message = "ScannedQrCodes(%d)".localize(numberOfSegments)
|
||||
}
|
||||
}
|
||||
var scanned = ScannedPGPKey()
|
||||
|
|
@ -94,12 +94,12 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
armorPrivateKeyTextView.text = SharedDefaults[.pgpPrivateKeyArmor]
|
||||
pgpPassphrase = passwordStore.pgpKeyPassphrase
|
||||
|
||||
scanPublicKeyCell?.textLabel?.text = "Scan Public Key QR Codes"
|
||||
scanPublicKeyCell?.textLabel?.text = "ScanPublicKeyQrCodes".localize()
|
||||
scanPublicKeyCell?.textLabel?.textColor = Globals.blue
|
||||
scanPublicKeyCell?.selectionStyle = .default
|
||||
scanPublicKeyCell?.accessoryType = .disclosureIndicator
|
||||
|
||||
scanPrivateKeyCell?.textLabel?.text = "Scan Private Key QR Codes"
|
||||
scanPrivateKeyCell?.textLabel?.text = "ScanPrivateKeyQrCodes".localize()
|
||||
scanPrivateKeyCell?.textLabel?.textColor = Globals.blue
|
||||
scanPrivateKeyCell?.selectionStyle = .default
|
||||
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
||||
|
|
@ -107,25 +107,25 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
|
||||
@IBAction func save(_ sender: Any) {
|
||||
guard armorPublicKeyTextView.text.isEmpty == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please set public key first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPublicKey.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
guard armorPrivateKeyTextView.text.isEmpty == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please set private key first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKey.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertActionStyle.default) { _ in
|
||||
self.pgpPassphrase = nil
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertActionStyle.destructive) {_ in
|
||||
// ask for the passphrase
|
||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.pgpPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
|
|
@ -163,7 +163,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
|
||||
scanned.addSegment(segment: line)
|
||||
if scanned.isDone {
|
||||
return (accept: true, message: "Done")
|
||||
return (accept: true, message: "Done".localize())
|
||||
} else {
|
||||
return (accept: false, message: scanned.message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ class PGPKeySettingTableViewController: UITableViewController {
|
|||
|
||||
private func validatePGPKeyURL(input: String?) -> Bool {
|
||||
guard let path = input, let url = URL(string: path) else {
|
||||
Utils.alert(title: "Cannot Save PGP Key", message: "Please set PGP Key URL first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSavePgpKey".localize(), message: "SetPgpKeyUrlFirst.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
guard let scheme = url.scheme, scheme == "https", scheme == "https" else {
|
||||
Utils.alert(title: "Cannot Save PGP Key", message: "HTTP connection is not supported.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSavePgpKey".localize(), message: "HttpNotSupported.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
@ -41,18 +41,18 @@ class PGPKeySettingTableViewController: UITableViewController {
|
|||
validatePGPKeyURL(input: pgpPrivateKeyURLTextField.text) == true else {
|
||||
return
|
||||
}
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertActionStyle.default) { _ in
|
||||
self.pgpPassphrase = nil
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
})
|
||||
// yes
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertActionStyle.destructive) {_ in
|
||||
// ask for the passphrase
|
||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.pgpPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
if self.shouldPopCurrentView {
|
||||
let alert = UIAlertController(title: "Notice", message: "All previous local changes have been discarded. Your current Password Store will be shown.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Notice".localize(), message: "PreviousChangesDiscarded.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
_ = self.navigationController?.popViewController(animated: true)
|
||||
}))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
|
@ -93,8 +93,8 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
let sem = DispatchSemaphore(value: 0)
|
||||
var passphrase = ""
|
||||
DispatchQueue.main.async {
|
||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
passphrase = alert.textFields!.first!.text!
|
||||
sem.signal()
|
||||
}))
|
||||
|
|
@ -113,7 +113,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
@objc private func decryptThenShowPassword() {
|
||||
guard let passwordEntity = passwordEntity else {
|
||||
Utils.alert(title: "Cannot Show Password", message: "The password does not exist.", controller: self, handler: {(UIAlertAction) -> Void in
|
||||
Utils.alert(title: "CannotShowPassword".localize(), message: "PasswordDoesNotExist".localize(), controller: self, handler: {(UIAlertAction) -> Void in
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
})
|
||||
return
|
||||
|
|
@ -127,11 +127,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
// remove the wrong passphrase so that users could enter it next time
|
||||
self.passwordStore.pgpKeyPassphrase = nil
|
||||
// alert: cancel or try again
|
||||
let alert = UIAlertController(title: "Cannot Show Password", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) { _ in
|
||||
let alert = UIAlertController(title: "CannotShowPassword".localize(), message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: UIAlertActionStyle.default) { _ in
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Try again", style: UIAlertActionStyle.destructive) {_ in
|
||||
alert.addAction(UIAlertAction(title: "TryAgain".localize(), style: UIAlertActionStyle.destructive) {_ in
|
||||
self.decryptThenShowPassword()
|
||||
})
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
|
@ -194,15 +194,15 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
@IBAction private func saveEditPassword(segue: UIStoryboardSegue) {
|
||||
if self.password!.changed != 0 {
|
||||
SVProgressHUD.show(withStatus: "Saving")
|
||||
SVProgressHUD.show(withStatus: "Saving".localize())
|
||||
do {
|
||||
self.passwordEntity = try self.passwordStore.edit(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
self.setTableData()
|
||||
self.tableView.reloadData()
|
||||
SVProgressHUD.showSuccess(withStatus: "Success")
|
||||
SVProgressHUD.showSuccess(withStatus: "Success".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
}
|
||||
|
|
@ -211,7 +211,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
do {
|
||||
try passwordStore.delete(passwordEntity: passwordEntity!)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
let _ = navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
// show one time password
|
||||
if password.otpType != .none {
|
||||
if let (title, otp) = self.password?.getOtpStrings() {
|
||||
section = TableSection(type: .addition, header: "One Time Password")
|
||||
section = TableSection(type: .addition, header: "OneTimePassword".localize())
|
||||
section.item.append(title => otp)
|
||||
tableData.append(section)
|
||||
oneTimePasswordIndexPath = IndexPath(row: 0, section: tableData.count - 1)
|
||||
|
|
@ -259,7 +259,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
// misc section
|
||||
section = TableSection(type: .misc)
|
||||
section.item.append(AdditionField(title: "Show Raw"))
|
||||
section.item.append(AdditionField(title: "ShowRaw".localize()))
|
||||
tableData.append(section)
|
||||
|
||||
}
|
||||
|
|
@ -315,10 +315,10 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? LabelTableViewCell {
|
||||
tappedCell.becomeFirstResponder()
|
||||
let menuController = UIMenuController.shared
|
||||
let revealItem = UIMenuItem(title: "Reveal", action: #selector(LabelTableViewCell.revealPassword(_:)))
|
||||
let concealItem = UIMenuItem(title: "Conceal", action: #selector(LabelTableViewCell.concealPassword(_:)))
|
||||
let nextHOTPItem = UIMenuItem(title: "Next Password", action: #selector(LabelTableViewCell.getNextHOTP(_:)))
|
||||
let openURLItem = UIMenuItem(title: "Copy Password & Open Link", action: #selector(LabelTableViewCell.openLink(_:)))
|
||||
let revealItem = UIMenuItem(title: "Reveal".localize(), action: #selector(LabelTableViewCell.revealPassword(_:)))
|
||||
let concealItem = UIMenuItem(title: "Conceal".localize(), action: #selector(LabelTableViewCell.concealPassword(_:)))
|
||||
let nextHOTPItem = UIMenuItem(title: "NextPassword".localize(), action: #selector(LabelTableViewCell.getNextHOTP(_:)))
|
||||
let openURLItem = UIMenuItem(title: "CopyAndOpen".localize(), action: #selector(LabelTableViewCell.openLink(_:)))
|
||||
menuController.menuItems = [revealItem, concealItem, nextHOTPItem, openURLItem]
|
||||
menuController.setTargetRect(tappedCell.contentLabel.frame, in: tappedCell.contentLabel.superview!)
|
||||
menuController.setMenuVisible(true, animated: true)
|
||||
|
|
@ -340,7 +340,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
func getNextHOTP() {
|
||||
guard password != nil, passwordEntity != nil, password?.otpType == .hotp else {
|
||||
DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: "Get next password of a non-HOTP entry.", controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: "GetNextPasswordOfNonHotp.".localize(), controller: self, completion: nil)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -355,9 +355,9 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
do {
|
||||
self.passwordEntity = try self.passwordStore.edit(passwordEntity: self.passwordEntity!, password: self.password!)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
SVProgressHUD.showSuccess(withStatus: "Password Copied\nCounter Updated")
|
||||
SVProgressHUD.showSuccess(withStatus: "PasswordCopied".localize() + "\n" + "CounterUpdated".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
}
|
||||
|
|
@ -365,7 +365,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
func openLink(to address: String?) {
|
||||
guard address != nil, let url = URL(string: formActualWebAddress(from: address!)) else {
|
||||
return DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: "Cannot find a valid URL", controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: "CannotFindValidUrl".localize(), controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
SecurePasteboard.shared.copy(textToCopy: password?.password)
|
||||
|
|
@ -436,7 +436,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
detailTextLabel.textAlignment = .center
|
||||
detailTextLabel.textColor = .gray
|
||||
detailTextLabel.text = "\(numberOfHiddenFields) hidden field\(numberOfHiddenFields > 1 ? "s" : "")"
|
||||
detailTextLabel.text = "HiddenFields(%d)".localize(numberOfHiddenFields)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
|
|
@ -451,7 +451,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
footerLabel.font = UIFont.preferredFont(forTextStyle: .footnote)
|
||||
footerLabel.textColor = UIColor.gray
|
||||
let dateString = self.passwordStore.getLatestUpdateInfo(filename: password!.url.path)
|
||||
footerLabel.text = "Last Updated: \(dateString)"
|
||||
footerLabel.text = "LastUpdated".localize(dateString)
|
||||
view.addSubview(footerLabel)
|
||||
return view
|
||||
}
|
||||
|
|
@ -481,7 +481,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let section = tableData[indexPath.section]
|
||||
if section.type == .misc {
|
||||
if section.item[indexPath.row].title == "Show Raw" {
|
||||
if section.item[indexPath.row].title == "ShowRaw".localize() {
|
||||
performSegue(withIdentifier: "showRawPasswordSegue", sender: self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
private var navigationItemTitle: String?
|
||||
|
||||
private var sectionHeaderTitles = ["name", "password", "additions",""].map {$0.uppercased()}
|
||||
private var sectionFooterTitles = ["", "", "Use \"key: value\" format for additional fields.", ""]
|
||||
private var sectionFooterTitles = ["", "", "UseKeyValueFormat.".localize(), ""]
|
||||
private let nameSection = 0
|
||||
private let passwordSection = 1
|
||||
private let additionsSection = 2
|
||||
|
|
@ -47,23 +47,24 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
super.loadView()
|
||||
|
||||
deletePasswordCell = UITableViewCell(style: .default, reuseIdentifier: "default")
|
||||
deletePasswordCell!.textLabel?.text = "Delete Password"
|
||||
deletePasswordCell!.textLabel?.text = "DeletePassword".localize()
|
||||
deletePasswordCell!.textLabel?.textColor = Globals.red
|
||||
deletePasswordCell?.selectionStyle = .default
|
||||
|
||||
scanQRCodeCell = UITableViewCell(style: .default, reuseIdentifier: "default")
|
||||
scanQRCodeCell?.textLabel?.text = "Add One-Time Password"
|
||||
scanQRCodeCell?.textLabel?.text = "AddOneTimePassword".localize()
|
||||
scanQRCodeCell?.textLabel?.textColor = Globals.blue
|
||||
scanQRCodeCell?.selectionStyle = .default
|
||||
scanQRCodeCell?.accessoryType = .disclosureIndicator
|
||||
|
||||
memorablePasswordGeneratorCell = UITableViewCell(style: .default, reuseIdentifier: "default")
|
||||
memorablePasswordGeneratorCell?.textLabel?.text = "Get a Memorable One: xkpasswd"
|
||||
memorablePasswordGeneratorCell?.textLabel?.text = "GetMemorableOne".localize()
|
||||
memorablePasswordGeneratorCell?.textLabel?.textColor = Globals.blue
|
||||
memorablePasswordGeneratorCell?.selectionStyle = .default
|
||||
memorablePasswordGeneratorCell?.accessoryType = .disclosureIndicator
|
||||
}
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
if navigationItemTitle != nil {
|
||||
|
|
@ -113,7 +114,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
currentPasswordLength <= maximumLength {
|
||||
defaultLength = currentPasswordLength
|
||||
}
|
||||
passwordLengthCell?.reset(title: "Length",
|
||||
passwordLengthCell?.reset(title: "Length".localize(),
|
||||
minimumValue: minimumLength,
|
||||
maximumValue: maximumLength,
|
||||
defaultValue: defaultLength)
|
||||
|
|
@ -161,11 +162,11 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let selectedCell = tableView.cellForRow(at: indexPath)
|
||||
if selectedCell == deletePasswordCell {
|
||||
let alert = UIAlertController(title: "Delete Password?", message: nil, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Delete", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
let alert = UIAlertController(title: "DeletePassword?".localize(), message: nil, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Delete".localize(), style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
self.performSegue(withIdentifier: "deletePasswordSegue", sender: self)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler:nil))
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: UIAlertActionStyle.cancel, handler:nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
} else if selectedCell == scanQRCodeCell {
|
||||
self.performSegue(withIdentifier: "showQRScannerSegue", sender: self)
|
||||
|
|
@ -185,11 +186,11 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
// check whether the current password looks like an OTP field
|
||||
func generateAndCopyPassword() {
|
||||
if let currentPassword = fillPasswordCell?.getContent(), Constants.isOtpRelated(line: currentPassword) {
|
||||
let alert = UIAlertController(title: "Overwrite?", message: "Overwrite the one-time password configuration?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive, handler: {_ in
|
||||
let alert = UIAlertController(title: "Overwrite?".localize(), message: "OverwriteOtpConfiguration?".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertActionStyle.destructive, handler: {_ in
|
||||
self.generateAndCopyPasswordNoOtpCheck()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: UIAlertActionStyle.cancel, handler: nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
} else {
|
||||
self.generateAndCopyPasswordNoOtpCheck()
|
||||
|
|
@ -243,9 +244,9 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
// MARK: - QRScannerControllerDelegate Methods
|
||||
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
|
||||
if let url = URL(string: line), let _ = Token(url: url) {
|
||||
return (accept: true, message: "Valid token URL")
|
||||
return (accept: true, message: "ValidTokenUrl".localize())
|
||||
} else {
|
||||
return (accept: false, message: "Invalid token URL")
|
||||
return (accept: false, message: "InvalidTokenUrl".localize())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,20 +303,20 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
func checkName() -> Bool {
|
||||
// the name field should not be empty
|
||||
guard let name = nameCell?.getContent(), name.isEmpty == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please fill in the name.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "FillInName.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
// the name should not start with /
|
||||
guard name.hasPrefix("/") == false else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please remove the prefix \"/\" from your password name.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "RemovePrefix.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
// the name field should be a valid url
|
||||
guard let path = name.stringByAddingPercentEncodingForRFC3986(),
|
||||
var passwordURL = URL(string: path) else {
|
||||
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "PasswordNameInvalid.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +325,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
while passwordURL.path != "." {
|
||||
passwordURL = passwordURL.deletingLastPathComponent()
|
||||
if passwordURL.path != "." && passwordURL.path.count >= previousPathLength {
|
||||
Utils.alert(title: "Cannot Save", message: "Cannot parse the filename. Please check and simplify the password name.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "CannotParseFilename.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
previousPathLength = passwordURL.path.count
|
||||
|
|
@ -337,8 +338,8 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
let copiedLinesSplit = UIPasteboard.general.string?.components(separatedBy: CharacterSet.whitespacesAndNewlines).filter({ !$0.isEmpty })
|
||||
if copiedLinesSplit?.count ?? 0 > 0 {
|
||||
let generatedPassword = copiedLinesSplit![0]
|
||||
let alert = UIAlertController(title: "Wanna use it?", message: "", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let message = NSMutableAttributedString(string: "It seems like you have copied something. The first string is:\n")
|
||||
let alert = UIAlertController(title: "WannaUseIt?".localize(), message: "", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let message = NSMutableAttributedString(string: "\("SeemsLikeYouHaveCopiedSomething.".localize()) \("FirstStringIs:".localize())\n")
|
||||
message.append(Utils.attributedPassword(plainPassword: generatedPassword))
|
||||
alert.setValue(message, forKey: "attributedMessage")
|
||||
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: {[unowned self] (action) -> Void in
|
||||
|
|
@ -349,7 +350,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
|||
// make sure the clipboard gets cleared in 45s
|
||||
SecurePasteboard.shared.copy(textToCopy: generatedPassword)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler:nil))
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: UIAlertActionStyle.cancel, handler:nil))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
return nil
|
||||
}()
|
||||
private lazy var backUIBarButtonItem: UIBarButtonItem = {
|
||||
let backUIBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(self.backAction(_:)))
|
||||
let backUIBarButtonItem = UIBarButtonItem(title: "Back".localize(), style: .plain, target: self, action: #selector(self.backAction(_:)))
|
||||
return backUIBarButtonItem
|
||||
}()
|
||||
|
||||
|
|
@ -110,18 +110,18 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
if let controller = segue.source as? AddPasswordTableViewController {
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Saving")
|
||||
SVProgressHUD.show(withStatus: "Saving".localize())
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
do {
|
||||
let _ = try self.passwordStore.add(password: controller.password!)
|
||||
DispatchQueue.main.async {
|
||||
// will trigger reloadTableView() by a notification
|
||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||
SVProgressHUD.showSuccess(withStatus: "Done".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,13 +131,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
private func syncPasswords() {
|
||||
guard passwordStore.repositoryExisted() else {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800)) {
|
||||
Utils.alert(title: "Error", message: "There is no password store right now.", controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: "NoPasswordStore.".localize(), controller: self, completion: nil)
|
||||
}
|
||||
return
|
||||
}
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Sync Password Store")
|
||||
SVProgressHUD.show(withStatus: "SyncingPasswordStore".localize())
|
||||
var gitCredential: GitCredential
|
||||
if SharedDefaults[.gitAuthenticationMethod] == "Password" {
|
||||
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: SharedDefaults[.gitUsername]!))
|
||||
|
|
@ -159,13 +159,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
if self.passwordStore.numberOfLocalCommits ?? 0 > 0 {
|
||||
try self.passwordStore.pushRepository(credential: gitCredential, requestGitPassword: self.requestGitPassword(credential:lastPassword:), transferProgressBlock: {(current, total, bytes, stop) in
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.showProgress(Float(current)/Float(total), status: "Push Remote Repository")
|
||||
SVProgressHUD.showProgress(Float(current)/Float(total), status: "PushingToRemoteRepository".localize())
|
||||
}
|
||||
})
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.reloadTableView(parent: nil)
|
||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||
SVProgressHUD.showSuccess(withStatus: "Done".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
self.syncControl.endRefreshing()
|
||||
}
|
||||
|
|
@ -176,14 +176,14 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
let error = error as NSError
|
||||
var message = error.localizedDescription
|
||||
if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError {
|
||||
message = "\(message)\nUnderlying error: \(underlyingError.localizedDescription)"
|
||||
if underlyingError.localizedDescription.contains("Wrong passphrase") {
|
||||
message = "\(message)\nRecovery suggestion: Wrong credential password/passphrase has been removed, please try again."
|
||||
message = "\(message)\n\("UnderlyingError".localize(underlyingError.localizedDescription))"
|
||||
if underlyingError.localizedDescription.contains("WrongPassphrase".localize()) {
|
||||
message = "\(message)\n\("RecoverySuggestion".localize())"
|
||||
gitCredential.delete()
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800)) {
|
||||
Utils.alert(title: "Error", message: message, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: message, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
super.viewDidAppear(animated)
|
||||
|
||||
if SharedDefaults[.isShowFolderOn] {
|
||||
searchController.searchBar.scopeButtonTitles = ["Current", "All"]
|
||||
searchController.searchBar.scopeButtonTitles = ["Current".localize(), "All".localize()]
|
||||
} else {
|
||||
searchController.searchBar.scopeButtonTitles = nil
|
||||
}
|
||||
|
|
@ -365,8 +365,8 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
let sem = DispatchSemaphore(value: 0)
|
||||
var passphrase = ""
|
||||
DispatchQueue.main.async {
|
||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
passphrase = alert.textFields!.first!.text!
|
||||
sem.signal()
|
||||
}))
|
||||
|
|
@ -381,7 +381,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
let _ = sem.wait(timeout: DispatchTime.distantFuture)
|
||||
DispatchQueue.main.async {
|
||||
// bring back
|
||||
SVProgressHUD.show(withStatus: "Decrypting")
|
||||
SVProgressHUD.show(withStatus: "Decrypting".localize())
|
||||
}
|
||||
if SharedDefaults[.isRememberPGPPassphraseOn] {
|
||||
self.passwordStore.pgpKeyPassphrase = passphrase
|
||||
|
|
@ -391,28 +391,28 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
|
||||
private func decryptThenCopyPassword(from indexPath: IndexPath) {
|
||||
guard self.passwordStore.privateKey != nil else {
|
||||
Utils.alert(title: "Cannot Copy Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotCopyPassword".localize(), message: "SetPgpKey.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
let passwordEntity = getPasswordEntry(by: indexPath).passwordEntity!
|
||||
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.dark)
|
||||
SVProgressHUD.show(withStatus: "Decrypting")
|
||||
SVProgressHUD.show(withStatus: "Decrypting".localize())
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
var decryptedPassword: Password?
|
||||
do {
|
||||
decryptedPassword = try self.passwordStore.decrypt(passwordEntity: passwordEntity, requestPGPKeyPassphrase: self.requestPGPKeyPassphrase)
|
||||
DispatchQueue.main.async {
|
||||
SecurePasteboard.shared.copy(textToCopy: decryptedPassword?.password)
|
||||
SVProgressHUD.showSuccess(withStatus: "Password copied. We will clear the pasteboard in 45 seconds.")
|
||||
SVProgressHUD.showSuccess(withStatus: "PasswordCopiedToPasteboard.".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 0.6)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
// remove the wrong passphrase so that users could enter it next time
|
||||
self.passwordStore.pgpKeyPassphrase = nil
|
||||
Utils.alert(title: "Cannot Copy Password", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotCopyPassword".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -453,7 +453,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
|
||||
if identifier == "showPasswordDetail" {
|
||||
guard self.passwordStore.privateKey != nil else {
|
||||
Utils.alert(title: "Cannot Show Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotShowPassword".localize(), message: "SetPgpKey.".localize(), controller: self, completion: nil)
|
||||
if let s = sender as? UITableViewCell {
|
||||
let selectedIndexPath = tableView.indexPath(for: s)!
|
||||
tableView.deselectRow(at: selectedIndexPath, animated: true)
|
||||
|
|
@ -462,7 +462,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
}
|
||||
} else if identifier == "addPasswordSegue" {
|
||||
guard self.passwordStore.publicKey != nil, self.passwordStore.storeRepository != nil else {
|
||||
Utils.alert(title: "Cannot Add Password", message: "Please make sure PGP Key and Git Server are properly set.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotAddPassword".localize(), message: "MakeSurePgpAndGitProperlySet.".localize(), controller: self, completion: nil)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -537,13 +537,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
self.tableView.layer.removeAnimation(forKey: "UITableViewReloadDataAnimationKey")
|
||||
|
||||
// set the sync control title
|
||||
let atribbutedTitle = "Last Synced: \(lastSyncedTimeString())"
|
||||
let atribbutedTitle = "LastSynced".localize() + ": \(lastSyncedTimeString())"
|
||||
syncControl.attributedTitle = NSAttributedString(string: atribbutedTitle)
|
||||
}
|
||||
|
||||
private func lastSyncedTimeString() -> String {
|
||||
guard let date = self.passwordStore.lastSyncedTime else {
|
||||
return "Oops! Sync again?"
|
||||
return "SyncAgain?".localize()
|
||||
}
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = .medium
|
||||
|
|
@ -615,23 +615,23 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
var message = ""
|
||||
switch credential {
|
||||
case .http:
|
||||
message = "Please fill in the password of your Git account."
|
||||
message = "FillInGitAccountPassword.".localize()
|
||||
case .ssh:
|
||||
message = "Please fill in the password of your SSH key."
|
||||
message = "FillInSshKeyPassphrase.".localize()
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.dismiss()
|
||||
let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
let alert = UIAlertController(title: "Password".localize(), message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||
textField.text = lastPassword ?? ""
|
||||
textField.isSecureTextEntry = true
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
password = alert.textFields!.first!.text
|
||||
sem.signal()
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Cancel".localize(), style: .cancel) { _ in
|
||||
password = nil
|
||||
sem.signal()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
|||
|
||||
// Move the message label to the front
|
||||
scannerOutput.layer.cornerRadius = 10
|
||||
scannerOutput.text = "No QR code detected"
|
||||
scannerOutput.text = "NoQrCodeDetected.".localize()
|
||||
view.bringSubview(toFront: scannerOutput)
|
||||
|
||||
// Initialize QR Code Frame to highlight the QR code
|
||||
|
|
@ -109,7 +109,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
|||
captureSession?.stopRunning()
|
||||
delegate?.handleScannedOutput(line: scanned)
|
||||
DispatchQueue.main.async {
|
||||
SVProgressHUD.showSuccess(withStatus: "Done")
|
||||
SVProgressHUD.showSuccess(withStatus: "Done".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
|
@ -119,21 +119,21 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
|||
scannerOutput.text = scanned
|
||||
}
|
||||
} else {
|
||||
scannerOutput.text = "No string value"
|
||||
scannerOutput.text = "NoStringValue".localize()
|
||||
}
|
||||
|
||||
} else {
|
||||
qrCodeFrameView?.frame = CGRect.zero
|
||||
scannerOutput.text = "No QR code detected"
|
||||
scannerOutput.text = "NoQrCodeDetected.".localize()
|
||||
}
|
||||
}
|
||||
|
||||
func presentCameraSettings() {
|
||||
let alertController = UIAlertController(title: "Error",
|
||||
message: "Camera access denied.\nWARNING: Toggle the camera permission resets the app! Save your changes.",
|
||||
let alertController = UIAlertController(title: "Error".localize(),
|
||||
message: "CameraAccessDenied.".localize() + "\n" + "WarningToggleCameraPermissionsResetsApp.".localize(),
|
||||
preferredStyle: .alert)
|
||||
alertController.addAction(UIAlertAction(title: "Cancel", style: .default))
|
||||
alertController.addAction(UIAlertAction(title: "Settings", style: .cancel) { _ in
|
||||
alertController.addAction(UIAlertAction(title: "Cancel".localize(), style: .default))
|
||||
alertController.addAction(UIAlertAction(title: "Settings".localize(), style: .cancel) { _ in
|
||||
if let url = URL(string: UIApplicationOpenSettingsURLString) {
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: { _ in
|
||||
// Handle
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class SSHKeySettingTableViewController: UITableViewController {
|
|||
|
||||
@IBAction func doneButtonTapped(_ sender: UIButton) {
|
||||
guard let privateKeyURL = URL(string: privateKeyURLTextField.text!.trimmed) else {
|
||||
Utils.alert(title: "Cannot Save", message: "Please set Private Key URL first.", controller: self, completion: nil)
|
||||
Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKeyUrl.".localize(), controller: self, completion: nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ class SSHKeySettingTableViewController: UITableViewController {
|
|||
do {
|
||||
try Data(contentsOf: privateKeyURL).write(to: URL(fileURLWithPath: Globals.gitSSHPrivateKeyPath), options: .atomic)
|
||||
} catch {
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
SharedDefaults[.gitSSHKeySource] = "url"
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
|
|
|
|||
|
|
@ -35,21 +35,21 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Fetching PGP Key")
|
||||
SVProgressHUD.show(withStatus: "FetchingPgpKey".localize())
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
do {
|
||||
try self.passwordStore.initPGPKey(from: SharedDefaults[.pgpPublicKeyURL]!, keyType: .public)
|
||||
try self.passwordStore.initPGPKey(from: SharedDefaults[.pgpPrivateKeyURL]!, keyType: .secret)
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
|
||||
SVProgressHUD.showSuccess(withStatus: "Success")
|
||||
SVProgressHUD.showSuccess(withStatus: "Success".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
Utils.alert(title: "Remember to Remove the Key", message: "Remember to remove the key from the server.", controller: self, completion: nil)
|
||||
Utils.alert(title: "RememberToRemoveKey".localize(), message: "RememberToRemoveKeyFromServer.".localize(), controller: self, completion: nil)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,20 +65,20 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Fetching PGP Key")
|
||||
SVProgressHUD.show(withStatus: "FetchingPgpKey".localize())
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
do {
|
||||
try self.passwordStore.initPGPKey(with: SharedDefaults[.pgpPublicKeyArmor] ?? "", keyType: .public)
|
||||
try self.passwordStore.initPGPKey(with: SharedDefaults[.pgpPrivateKeyArmor] ?? "", keyType: .secret)
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
|
||||
SVProgressHUD.showSuccess(withStatus: "Success")
|
||||
SVProgressHUD.showSuccess(withStatus: "Success".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,20 +90,20 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
SharedDefaults[.pgpKeySource] = "file"
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
SVProgressHUD.setDefaultStyle(.light)
|
||||
SVProgressHUD.show(withStatus: "Fetching PGP Key")
|
||||
SVProgressHUD.show(withStatus: "FetchingPgpKey".localize())
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
do {
|
||||
try self.passwordStore.pgpKeyImportFromFileSharing()
|
||||
try self.passwordStore.initPGPKeys()
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported")
|
||||
SVProgressHUD.showSuccess(withStatus: "Imported".localize())
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,9 +133,9 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
private func setPasscodeLockCell() {
|
||||
if passcodeLock.hasPasscode {
|
||||
self.passcodeTableViewCell.detailTextLabel?.text = "On"
|
||||
self.passcodeTableViewCell.detailTextLabel?.text = "On".localize()
|
||||
} else {
|
||||
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
|
||||
self.passcodeTableViewCell.detailTextLabel?.text = "Off".localize()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,13 +143,13 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
if let pgpKeyID = self.passwordStore.pgpKeyID {
|
||||
pgpKeyTableViewCell.detailTextLabel?.text = pgpKeyID
|
||||
} else {
|
||||
pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
}
|
||||
}
|
||||
|
||||
private func setPasswordRepositoryTableViewCellDetailText() {
|
||||
if SharedDefaults[.gitURL] == nil {
|
||||
passwordRepositoryTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
passwordRepositoryTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
} else {
|
||||
passwordRepositoryTableViewCell.detailTextLabel?.text = SharedDefaults[.gitURL]!.host
|
||||
}
|
||||
|
|
@ -176,9 +176,9 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
func showPGPKeyActionSheet() {
|
||||
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
var urlActionTitle = "Download from URL"
|
||||
var armorActionTitle = "ASCII-Armor Encrypted Key"
|
||||
var fileActionTitle = "iTunes File Sharing"
|
||||
var urlActionTitle = "DownloadFromUrl".localize()
|
||||
var armorActionTitle = "AsciiArmorEncryptedKey".localize()
|
||||
var fileActionTitle = "ITunesFileSharing".localize()
|
||||
|
||||
if SharedDefaults[.pgpKeySource] == "url" {
|
||||
urlActionTitle = "✓ \(urlActionTitle)"
|
||||
|
|
@ -193,26 +193,26 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
let armorAction = UIAlertAction(title: armorActionTitle, style: .default) { _ in
|
||||
self.performSegue(withIdentifier: "setPGPKeyByASCIISegue", sender: self)
|
||||
}
|
||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
optionMenu.addAction(urlAction)
|
||||
optionMenu.addAction(armorAction)
|
||||
|
||||
if passwordStore.pgpKeyExists(inFileSharing: true) {
|
||||
fileActionTitle.append(" (Import)")
|
||||
fileActionTitle.append(" (\("Import".localize()))")
|
||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
// passphrase related
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
|
||||
let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
// no
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertActionStyle.default) { _ in
|
||||
self.passwordStore.pgpKeyPassphrase = nil
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = false
|
||||
self.saveImportedPGPKey()
|
||||
})
|
||||
// yes
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
|
||||
savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertActionStyle.destructive) {_ in
|
||||
// ask for the passphrase
|
||||
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: {_ in
|
||||
self.passwordStore.pgpKeyPassphrase = alert.textFields?.first?.text
|
||||
SharedDefaults[.isRememberPGPPassphraseOn] = true
|
||||
self.saveImportedPGPKey()
|
||||
|
|
@ -227,10 +227,10 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
}
|
||||
optionMenu.addAction(fileAction)
|
||||
} else {
|
||||
fileActionTitle.append(" (Tips)")
|
||||
fileActionTitle.append(" (\("Tips".localize()))")
|
||||
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
|
||||
let title = "Tips"
|
||||
let message = "Copy your ASCII-armored public and private keys to Pass with names \"gpg_key.pub\" and \"gpg_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish."
|
||||
let title = "Tips".localize()
|
||||
let message = "CopyPrivateKeyToPass.".localize()
|
||||
Utils.alert(title: title, message: message, controller: self)
|
||||
}
|
||||
optionMenu.addAction(fileAction)
|
||||
|
|
@ -238,9 +238,9 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
|
||||
if SharedDefaults[.pgpKeySource] != nil {
|
||||
let deleteAction = UIAlertAction(title: "Remove PGP Keys", style: .destructive) { _ in
|
||||
let deleteAction = UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in
|
||||
self.passwordStore.removePGPKeys()
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
|
||||
self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize()
|
||||
}
|
||||
optionMenu.addAction(deleteAction)
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
let passcodeRemoveViewController = PasscodeLockViewController()
|
||||
|
||||
|
||||
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive) { [weak self] _ in
|
||||
let removePasscodeAction = UIAlertAction(title: "RemovePasscode".localize(), style: .destructive) { [weak self] _ in
|
||||
passcodeRemoveViewController.successCallback = {
|
||||
self?.passcodeLock.delete()
|
||||
self?.setPasscodeLockCell()
|
||||
|
|
@ -263,11 +263,11 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
self?.present(passcodeRemoveViewController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default) { [weak self] _ in
|
||||
let changePasscodeAction = UIAlertAction(title: "ChangePasscode".localize(), style: .default) { [weak self] _ in
|
||||
self?.setPasscodeLock()
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
optionMenu.addAction(removePasscodeAction)
|
||||
optionMenu.addAction(changePasscodeAction)
|
||||
optionMenu.addAction(cancelAction)
|
||||
|
|
@ -292,20 +292,20 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
|
||||
func setPasscodeLock() {
|
||||
// prepare the alert for setting the passcode
|
||||
setPasscodeLockAlert = UIAlertController(title: "Set passcode", message: "Fill in your passcode for Pass (at least 4 characters)", preferredStyle: .alert)
|
||||
setPasscodeLockAlert = UIAlertController(title: "SetPasscode".localize(), message: "FillInAppPasscode.".localize(), preferredStyle: .alert)
|
||||
setPasscodeLockAlert?.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in
|
||||
textField.placeholder = "Password"
|
||||
textField.placeholder = "Password".localize()
|
||||
textField.isSecureTextEntry = true
|
||||
textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
|
||||
})
|
||||
setPasscodeLockAlert?.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in
|
||||
textField.placeholder = "Password Confirmation"
|
||||
textField.placeholder = "PasswordConfirmation".localize()
|
||||
textField.isSecureTextEntry = true
|
||||
textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
|
||||
})
|
||||
|
||||
// save action
|
||||
let saveAction = UIAlertAction(title: "Save", style: .default) { (action:UIAlertAction) -> Void in
|
||||
let saveAction = UIAlertAction(title: "Save".localize(), style: .default) { (action:UIAlertAction) -> Void in
|
||||
let passcode: String = self.setPasscodeLockAlert!.textFields![0].text!
|
||||
self.passcodeLock.save(passcode: passcode)
|
||||
// refresh the passcode lock cell ("On")
|
||||
|
|
@ -314,7 +314,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
|||
saveAction.isEnabled = false // disable the Save button by default
|
||||
|
||||
// cancel action
|
||||
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)
|
||||
|
||||
// present
|
||||
setPasscodeLockAlert?.addAction(saveAction)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import UIKit
|
|||
|
||||
class SpecialThanksTableViewController: BasicStaticTableViewController {
|
||||
let openSourceComponents = [
|
||||
["Contributors",
|
||||
["Contributors".localize(),
|
||||
"https://github.com/mssun/passforios/graphs/contributors"],
|
||||
["Password Store",
|
||||
"https://passwordstore.org"],
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ extension Utils {
|
|||
static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) {
|
||||
SVProgressHUD.dismiss()
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: handler))
|
||||
alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertActionStyle.default, handler: handler))
|
||||
controller.present(alert, animated: true, completion: completion)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LabelTableViewCell: UITableViewCell {
|
|||
}
|
||||
}
|
||||
contentLabel.font = Globals.passwordFont
|
||||
} else if title.caseInsensitiveCompare("hmac-based") == .orderedSame {
|
||||
} else if title.caseInsensitiveCompare("HmacBased".localize()) == .orderedSame {
|
||||
type = .HOTP
|
||||
if isReveal {
|
||||
contentLabel.text = content
|
||||
|
|
|
|||
|
|
@ -6,5 +6,239 @@
|
|||
Copyright © 2019 Bob Sun. All rights reserved.
|
||||
*/
|
||||
|
||||
"Apple" = "Apple";
|
||||
"Random" = "Random";
|
||||
// General
|
||||
"PassForIos" = "Pass for iOS";
|
||||
"Passphrase" = "Passphrase";
|
||||
"Passwords" = "Passwords";
|
||||
"Apple" = "Apple";
|
||||
"Settings" = "Settings";
|
||||
"Contributors" = "Contributors";
|
||||
|
||||
// OTP related
|
||||
"TimeBased" = "time-based";
|
||||
"HmacBased" = "HMAC-based";
|
||||
"None" = "None";
|
||||
"ExpiresIn" = "(expires in %ds)";
|
||||
|
||||
// General (error) messages
|
||||
"Error" = "Error";
|
||||
"CannotSave" = "Cannot Save";
|
||||
"UnresolvedError" = "Unresolved error %@";
|
||||
"MigrationError" = "Migration error: %@";
|
||||
"UnderlyingError" = "Underlying Error: %@";
|
||||
"ErrorSaving" = "Error saving: %@";
|
||||
"CannotCopyPassword" = "Cannot copy password";
|
||||
"CannotAddPassword" = "Cannot add password";
|
||||
"WrongPassphrase" = "Wrong passphrase";
|
||||
"MakeSurePgpAndGitProperlySet." = "Please make sure PGP key and Git server are properly set.";
|
||||
"RecoverySuggestion" = "Recovery suggestion: Wrong credential password/passphrase has been removed, please try again.";
|
||||
"NSURLFileAllocatedSizeKeyShouldAlwaysReturnValue." = "Huh? NSURLFileAllocatedSizeKey should always return a value.";
|
||||
|
||||
// Settings
|
||||
"PasswordGeneratorFlavor" = "Password Generator Flavor";
|
||||
"RememberPgpKeyPassphrase" = "Remember PGP Key Passphrase";
|
||||
"RememberGitCredentialPassphrase" = "Remember Git Credential Passphrase";
|
||||
"ShowFolders" = "Show Folders";
|
||||
"HideUnknownFields" = "Hide Unknown Fields";
|
||||
"HideUnknownFieldsExplanation." = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unknown\" keys. Turn on this switch to hide unsupported fields.";
|
||||
"HideOtpFields" = "Hide OTP Fields";
|
||||
"HideOtpFieldsExplanation." = "Turn on this switch to hide the fields related to one time passwords (i.e., %@).";
|
||||
"Random" = "Random";
|
||||
"RandomString" = "Random String";
|
||||
"ApplesKeychainStyle" = "Apple's Keychain Style";
|
||||
|
||||
// Git
|
||||
"FailedToFetchPasswords" = "Failed to fetch passwords";
|
||||
"FailedToFetchPasswordEntities" = "Failed to fetch password entities: %@";
|
||||
"FailedToInsertPasswordEntity" = "Failed to insert password entity: %@";
|
||||
"FailedToDeletePasswordEntity" = "Failed to delete password entity: %@";
|
||||
"FailedToSavePasswordEntity" = "Failed to save password entity: %@";
|
||||
"FailureToSaveContext" = "Failure to save context: %@";
|
||||
"RepositoryRemoteMasterNotFoundError." = "Cannot find remote branch origin/master.";
|
||||
"KeyImportError." = "Cannot import the key.";
|
||||
"PasswordDuplicatedError." = "Cannot add the password; password is duplicated.";
|
||||
"GitResetError." = "Cannot identify the latest synced commit.";
|
||||
"PGPPublicKeyNotExistError." = "PGP public key doesn't exist.";
|
||||
"WrongPasswordFilename." = "Cannot write to the password file.";
|
||||
"DecryptionError." = "Cannot decrypt password.";
|
||||
"UnknownError." = "Unknown error.";
|
||||
"PrepareRepository" = "Prepare Repository";
|
||||
"CheckingOutBranch" = "Checking out branch '%@'";
|
||||
"WantToSaveGitCredential?" = "Do you want to save the Git credential password/passphrase?";
|
||||
|
||||
// Repository
|
||||
"RepositoryNotSetError." = "Git repository is not set.";
|
||||
"SetGitRepositoryUrl" = "Please set the Git repository URL.";
|
||||
"CannotFindUsername." = "Cannot find the username in the Git repository URL. Example URL: ssh://git@server/path/to/repo.git.";
|
||||
"CheckEnteredUsername." = "Please check the entered username and the username in the Git repository URL. They should match.";
|
||||
"UseHttps." = "Please use HTTPS instead of HTTP.";
|
||||
"SpecifySchema." = "Please specify the scheme of the Git repository URL (HTTPS or SSH).";
|
||||
"Overwrite?" = "Overwrite?";
|
||||
"Overwrite" = "Overwrite";
|
||||
"OperationWillOverwriteData." = "This operation will overwrite your current password store data (repository). Data on your remote server will not be affected.";
|
||||
"DownloadFromUrl" = "Download from URL";
|
||||
"AsciiArmorEncryptedKey" = "ASCII-Armor Encrypted Key";
|
||||
"ITunesFileSharing" = "iTunes File Sharing";
|
||||
"Import" = "Import";
|
||||
"Imported" = "Imported";
|
||||
"Tips" = "Tips";
|
||||
"CopyPrivateKeyToPass." = "Copy your ASCII-armored private key to Pass with the name \"ssh_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish.";
|
||||
"FillInGitAccountPassword." = "Please fill in the password of your Git account.";
|
||||
"NoPasswordStore." = "There is no password store right now.";
|
||||
"SyncingPasswordStore" = "Syncing Password Store";
|
||||
"PushingToRemoteRepository" = "Pushing to Remote Repository";
|
||||
|
||||
// SSH
|
||||
"FillInSshKeyPassphrase." = "Please fill in the passphrase of your SSH key.";
|
||||
"CannotSelectSshKey" = "Cannot Select SSH Key";
|
||||
"PleaseSetupSshKeyFirst." = "Please setup SSH key first.";
|
||||
"RemoveSShKeys" = "Remove Git SSH Keys";
|
||||
"SetPrivateKeyUrl." = "Please set private key URL first.";
|
||||
|
||||
// QR code scanning
|
||||
"LookingForStartingFrame." = "Looking for the starting frame.";
|
||||
"TooManyQrCodes" = "Too many QR codes";
|
||||
"ScanPrivateKeyQrCodes" = "Scan Private Key QR Codes";
|
||||
"CannotSaveSshKey" = "Cannot Save SSH Key";
|
||||
"ScanPublicKey." = "Please scan public key.";
|
||||
"ScanPrivateKey." = "Please scan private key.";
|
||||
"ScanPrivateKeyQrCodes" = "Scan Private Key QR codes";
|
||||
"ScanPublicKeyQrCodes" = "Scan Public Key QR codes";
|
||||
"SetPrivateKey." = "Please set private key first.";
|
||||
"SetPublicKey." = "Please set public key first.";
|
||||
"NoQrCodeDetected." = "No QR code detected.";
|
||||
"NoStringValue" = "No string value";
|
||||
"CameraAccessDenied." = "Camera access denied.";
|
||||
"WarningToggleCameraPermissionsResetsApp." = "WARNING: Toggle the camera permission resets the app! Save your changes.";
|
||||
|
||||
// PGP
|
||||
"Decrypting" = "Decrypting";
|
||||
"PgpKeyNotSet." = "PGP Key is not set. Please set your PGP Key first.";
|
||||
"FillInPgpPassphrase." = "Please fill in the passphrase of your PGP secret key.";
|
||||
"SetPgpKey." = "PGP Key is not set. Please set your PGP Key first.";
|
||||
"WantToSavePassphrase?" = "Do you want to save the passphrase for later decryption?";
|
||||
"CannotSavePgpKey" = "Cannot Save PGP Key";
|
||||
"SetPgpKeyUrlFirst." = "Please set PGP key URL first.";
|
||||
"FetchingPgpKey" = "Fetching PGP Key";
|
||||
"RememberToRemoveKey" = "Remember to Remove the Key";
|
||||
"RememberToRemoveKeyFromServer." = "Remember to remove the key from the server.";
|
||||
"RemovePgpKeys" = "Remove PGP Keys";
|
||||
|
||||
// App passcode
|
||||
"RemovePasscode" = "Remove Passcode";
|
||||
"ChangePasscode" = "Change Passcode";
|
||||
"SetPasscode" = "Set Passcode";
|
||||
"PasswordConfirmation" = "Password Confirmation";
|
||||
"FillInAppPasscode." = "Fill in your passcode for Pass (at least 4 characters).";
|
||||
|
||||
// Git signature
|
||||
"NotSet" = "Not Set";
|
||||
"InvalidNameOrEmail" = "Invalid name or e-mail";
|
||||
|
||||
// Erase password store
|
||||
"ErasePasswordStoreData?" = "Erase password store data?";
|
||||
"ErasePasswordStoreData" = "Erase Password Store Data";
|
||||
"EraseExplanation." = "This will delete all local data and settings. Password store data on your remote server will not be affected.";
|
||||
"Erasing..." = "Erasing ...";
|
||||
|
||||
// Discard local changes
|
||||
"DiscardAllLocalChanges?" = "Discard all local changes?";
|
||||
"DiscardAllLocalChanges" = "Discard All Local Changes";
|
||||
"DiscardExplanation." = "Do you want to permanently discard all changes to the local copy of your password data? You cannot undo this action.";
|
||||
"Resetting..." = "Resetting ...";
|
||||
|
||||
// Time related
|
||||
"Unknown" = "Unknown";
|
||||
"JustNow" = "Just now";
|
||||
"TimeAgo" = "%@ ago";
|
||||
|
||||
// Commit messages
|
||||
"AddPassword." = "Add password for %@ to store using Pass for iOS.";
|
||||
"RemovePassword." = "Remove %@ from store using Pass for iOS.";
|
||||
"EditPassword." = "Edit password for %@ using Pass for iOS.";
|
||||
"RenamePassword." = "Rename %@ to %@ using Pass for iOS.";
|
||||
|
||||
// Menu buttons
|
||||
"Ok" = "OK";
|
||||
"Cancel" = "Cancel";
|
||||
"Dismiss" = "Dismiss";
|
||||
"Done" = "Done";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
"TryAgain" = "Try Again";
|
||||
"Delete" = "Delete";
|
||||
"Back" = "Back";
|
||||
"Current" = "Current";
|
||||
"All" = "All";
|
||||
"On" = "On";
|
||||
"Off" = "Off";
|
||||
"Save" = "Save";
|
||||
|
||||
// Lock screen
|
||||
"EnterPasscode" = "Enter passcode for Pass";
|
||||
"Passcode" = "Passcode";
|
||||
"TouchId" = "Touch ID";
|
||||
"FaceId" = "Face ID";
|
||||
"AuthenticationNeeded." = "Authentication is needed to access Pass.";
|
||||
|
||||
// About repository
|
||||
"AboutRepository" = "About Repository";
|
||||
"ValueNotAvailable" = "Value not available";
|
||||
"Size" = "Size";
|
||||
"LocalCommits" = "Local Commits";
|
||||
"LastSynced" = "Last Synced";
|
||||
"Commits" = "Commits";
|
||||
"CommitLogs" = "Commit Logs";
|
||||
"SyncAgain?" = "Oops! Sync again?";
|
||||
|
||||
// About app
|
||||
"Website" = "Website";
|
||||
"Help" = "Help";
|
||||
"ContactDeveloper" = "Contact Developer";
|
||||
"OpenSourceComponents" = "Open Source Components";
|
||||
"SpecialThanks" = "Special Thanks";
|
||||
"Acknowledgements" = "Acknowledgements";
|
||||
"ValueNotAvailable" = "Value not available";
|
||||
|
||||
// External applications
|
||||
"CannotOpenMail" = "Cannot open Mail app";
|
||||
"CopiedEmail" = "Copied email %@";
|
||||
"HttpNotSupported." = "HTTP connection is not supported.";
|
||||
|
||||
// Password view
|
||||
"Notice" = "Notice";
|
||||
"PreviousChangesDiscarded." = "All previous local changes have been discarded. Your current Password Store will be shown.";
|
||||
"CannotShowPassword" = "Cannot show password";
|
||||
"PasswordDoesNotExist" = "The password does not exist.";
|
||||
"Saving" = "Saving";
|
||||
"Success" = "Success";
|
||||
"OneTimePassword" = "One-Time Password";
|
||||
"ShowRaw" = "Show Raw";
|
||||
"Reveal" = "Reveal";
|
||||
"Conceal" = "Conceal";
|
||||
"NextPassword" = "Next Password";
|
||||
"CopyAndOpen" = "Copy Password & Open Link";
|
||||
"GetNextPasswordOfNonHotp." = "Get next password of a non-HOTP entry.";
|
||||
"PasswordCopied" = "Password Copied";
|
||||
"CounterUpdated" = "Counter Updated";
|
||||
"CannotFindValidUrl" = "Cannot find a valid URL";
|
||||
"LastUpdated" = "Last Updated: %@";
|
||||
"PasswordCopiedToPasteboard." = "Password copied. We will clear the pasteboard in 45 seconds.";
|
||||
|
||||
// Password editor
|
||||
"UseKeyValueFormat." = "Use \"key: value\" format for additional fields.";
|
||||
"DeletePassword" = "Delete Password";
|
||||
"AddOneTimePassword" = "Add One-Time Password";
|
||||
"GetMemorableOne" = "Get a Memorable One: xkpasswd";
|
||||
"Length" = "Length";
|
||||
"DeletePassword?" = "Delete Password?";
|
||||
"OverwriteOtpConfiguration?" = "Overwrite the one-time password configuration?";
|
||||
"ValidTokenUrl" = "Valid token URL";
|
||||
"InvalidTokenUrl" = "Invalid token URL";
|
||||
"FillInName." = "Please fill in the name.";
|
||||
"RemovePrefix." = "Please remove the prefix \"/\" from your password name.";
|
||||
"PasswordNameInvalid." = "Password name is invalid.";
|
||||
"CannotParseFilename." = "Cannot parse the filename. Please check and simplify the password name.";
|
||||
"WannaUseIt?" = "Wanna use it?";
|
||||
"SeemsLikeYouHaveCopiedSomething." = "It seems like you have copied something.";
|
||||
"FirstStringIs:" = "The first string is:";
|
||||
|
|
|
|||
76
pass/en.lproj/Localizable.stringsdict
Normal file
76
pass/en.lproj/Localizable.stringsdict
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ScannedQrCodes(%d)</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@code@</string>
|
||||
<key>codes</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>zero</key>
|
||||
<string>No scanned QR code</string>
|
||||
<key>one</key>
|
||||
<string>One scanned QR code</string>
|
||||
<key>other</key>
|
||||
<string>%d scanned QR codes</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>DiscardedCommits(%d)</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@commits@</string>
|
||||
<key>commits</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>d</string>
|
||||
<key>zero</key>
|
||||
<string>No local commits</string>
|
||||
<key>one</key>
|
||||
<string>Discarded one commit</string>
|
||||
<key>other</key>
|
||||
<string>Discarded %d commits</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>HiddenFields(%d)</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@fields@</string>
|
||||
<key>fields</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>d</string>
|
||||
<key>zero</key>
|
||||
<string>No hidden field</string>
|
||||
<key>one</key>
|
||||
<string>One hidden field</string>
|
||||
<key>other</key>
|
||||
<string>%d hidden fields</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>WrongAttempts(%d)</key>
|
||||
<dict>
|
||||
<key>NSStringLocalizedFormatKey</key>
|
||||
<string>%#@attempts@</string>
|
||||
<key>attempts</key>
|
||||
<dict>
|
||||
<key>NSStringFormatSpecTypeKey</key>
|
||||
<string>NSStringPluralRuleType</string>
|
||||
<key>NSStringFormatValueTypeKey</key>
|
||||
<string>d</string>
|
||||
<key>zero</key>
|
||||
<string>No wrong attempt</string>
|
||||
<key>one</key>
|
||||
<string>One wrong attempt</string>
|
||||
<key>other</key>
|
||||
<string>%d wrong attempts</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
Loading…
Add table
Add a link
Reference in a new issue