Merge, fix conflict
|
|
@ -1,8 +1,12 @@
|
||||||
language: objective-c
|
language: objective-c
|
||||||
|
<<<<<<< HEAD
|
||||||
osx_image: xcode8.3
|
osx_image: xcode8.3
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- develop
|
- develop
|
||||||
|
=======
|
||||||
|
osx_image: xcode8.2
|
||||||
|
>>>>>>> uiimprovement
|
||||||
before_install:
|
before_install:
|
||||||
- echo -e "machine github.com\n login $GITHUB_ACCESS_TOKEN" >> ~/.netrc
|
- echo -e "machine github.com\n login $GITHUB_ACCESS_TOKEN" >> ~/.netrc
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,22 @@ platform :ios do
|
||||||
keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
|
keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
|
||||||
readonly: true
|
readonly: true
|
||||||
)
|
)
|
||||||
|
<<<<<<< HEAD
|
||||||
# ensure_git_status_clean
|
# ensure_git_status_clean
|
||||||
|
=======
|
||||||
|
ensure_git_status_clean
|
||||||
|
>>>>>>> uiimprovement
|
||||||
increment_build_number(
|
increment_build_number(
|
||||||
build_number: latest_testflight_build_number + 1,
|
build_number: latest_testflight_build_number + 1,
|
||||||
xcodeproj: "pass.xcodeproj"
|
xcodeproj: "pass.xcodeproj"
|
||||||
)
|
)
|
||||||
|
<<<<<<< HEAD
|
||||||
# commit_version_bump(xcodeproj: "pass.xcodeproj")
|
# commit_version_bump(xcodeproj: "pass.xcodeproj")
|
||||||
# push_to_git_remote
|
# push_to_git_remote
|
||||||
|
=======
|
||||||
|
commit_version_bump(xcodeproj: "pass.xcodeproj")
|
||||||
|
push_to_git_remote(local_branch: "develop")
|
||||||
|
>>>>>>> uiimprovement
|
||||||
gym(scheme: "pass")
|
gym(scheme: "pass")
|
||||||
pilot(skip_waiting_for_build_processing: true)
|
pilot(skip_waiting_for_build_processing: true)
|
||||||
mailgun(
|
mailgun(
|
||||||
|
|
|
||||||
22
pass/Assets.xcassets/Camera.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Screenshot-50.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Screenshot-100.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/Camera.imageset/Screenshot-100.png
vendored
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
pass/Assets.xcassets/Camera.imageset/Screenshot-50.png
vendored
Normal file
|
After Width: | Height: | Size: 841 B |
22
pass/Assets.xcassets/Copy.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Copy-50.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Copy-100.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/Copy.imageset/Copy-100.png
vendored
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
pass/Assets.xcassets/Copy.imageset/Copy-50.png
vendored
Normal file
|
After Width: | Height: | Size: 420 B |
22
pass/Assets.xcassets/HorizontalSettings.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Horizontal Settings Mixer-50.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Horizontal Settings Mixer-75.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/HorizontalSettings.imageset/Horizontal Settings Mixer-50.png
vendored
Normal file
|
After Width: | Height: | Size: 444 B |
BIN
pass/Assets.xcassets/HorizontalSettings.imageset/Horizontal Settings Mixer-75.png
vendored
Normal file
|
After Width: | Height: | Size: 946 B |
22
pass/Assets.xcassets/Invisible.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Invisible-64.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Invisible-75.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/Invisible.imageset/Invisible-64.png
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
pass/Assets.xcassets/Invisible.imageset/Invisible-75.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
22
pass/Assets.xcassets/Refresh.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Refresh-64.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Refresh-75.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/Refresh.imageset/Refresh-64.png
vendored
Normal file
|
After Width: | Height: | Size: 939 B |
BIN
pass/Assets.xcassets/Refresh.imageset/Refresh-75.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
22
pass/Assets.xcassets/Visible.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Visible-64.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "Visible-75.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
pass/Assets.xcassets/Visible.imageset/Visible-64.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
pass/Assets.xcassets/Visible.imageset/Visible-75.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -56,11 +56,6 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
||||||
tableView.estimatedRowHeight = 48
|
tableView.estimatedRowHeight = 48
|
||||||
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
|
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
|
||||||
self.tableView.estimatedSectionFooterHeight = 0;
|
self.tableView.estimatedSectionFooterHeight = 0;
|
||||||
|
|
||||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tableTapped))
|
|
||||||
tapGesture.delegate = self
|
|
||||||
tapGesture.cancelsTouchesInView = false
|
|
||||||
tableView.addGestureRecognizer(tapGesture)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
|
@ -166,35 +161,8 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
|
||||||
fillPasswordCell?.setContent(content: plainPassword)
|
fillPasswordCell?.setContent(content: plainPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableTapped(recognizer: UITapGestureRecognizer) {
|
func showHidePasswordSettings() {
|
||||||
if recognizer.state == UIGestureRecognizerState.ended {
|
hidePasswordSettings = !hidePasswordSettings
|
||||||
let tapLocation = recognizer.location(in: self.tableView)
|
tableView.reloadSections([passwordSection], with: .fade)
|
||||||
let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation)
|
|
||||||
|
|
||||||
// do nothing, if delete is tapped (a temporary solution)
|
|
||||||
if tapIndexPath != nil, deletePasswordCell != nil,
|
|
||||||
tableView.cellForRow(at: tapIndexPath!) == deletePasswordCell {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// hide password settings (e.g., the length slider)
|
|
||||||
if tapIndexPath?.section != passwordSection, hidePasswordSettings == false {
|
|
||||||
hidePasswordSettings = true
|
|
||||||
tableView.reloadSections([passwordSection], with: .fade)
|
|
||||||
// select the row at tapIndexPath manually
|
|
||||||
if tapIndexPath != nil {
|
|
||||||
self.tableView(self.tableView, didSelectRowAt: tapIndexPath!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
|
||||||
if gestureRecognizer is UITapGestureRecognizer {
|
|
||||||
// so that the tap gesture could be passed by
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,17 @@ class Globals {
|
||||||
static let repositoryPath = "\(libraryPath)/password-store"
|
static let repositoryPath = "\(libraryPath)/password-store"
|
||||||
static var passcodeConfiguration = PasscodeLockConfiguration()
|
static var passcodeConfiguration = PasscodeLockConfiguration()
|
||||||
|
|
||||||
static let red = UIColor(red:1.00, green:0.23, blue:0.19, alpha:1.0)
|
|
||||||
static let blue = UIColor(red:0.00, green:0.48, blue:1.00, alpha:1.0)
|
|
||||||
|
|
||||||
static let passwordDefaultLength = ["Random": (min: 6, max: 24, def: 16),
|
static let passwordDefaultLength = ["Random": (min: 6, max: 24, def: 16),
|
||||||
"Apple": (min: 15, max: 15, def: 15)]
|
"Apple": (min: 15, max: 15, def: 15)]
|
||||||
|
|
||||||
static let passwordDots = "••••••••••••"
|
static let passwordDots = "••••••••••••"
|
||||||
static let passwordFonts = "Menlo"
|
static let passwordFonts = "Menlo"
|
||||||
|
|
||||||
|
// UI related
|
||||||
|
static let red = UIColor(red:1.00, green:0.23, blue:0.19, alpha:1.0)
|
||||||
|
static let blue = UIColor(red:0.00, green:0.48, blue:1.00, alpha:1.0)
|
||||||
|
static let tableCellButtonSize = CGFloat(20.0)
|
||||||
|
|
||||||
private init() { }
|
private init() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import UIKit
|
||||||
|
|
||||||
protocol FillPasswordTableViewCellDelegate {
|
protocol FillPasswordTableViewCellDelegate {
|
||||||
func generateAndCopyPassword()
|
func generateAndCopyPassword()
|
||||||
|
func showHidePasswordSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
class FillPasswordTableViewCell: ContentTableViewCell {
|
class FillPasswordTableViewCell: ContentTableViewCell {
|
||||||
|
|
@ -17,10 +18,17 @@ class FillPasswordTableViewCell: ContentTableViewCell {
|
||||||
@IBOutlet weak var contentTextField: UITextField!
|
@IBOutlet weak var contentTextField: UITextField!
|
||||||
var delegate: FillPasswordTableViewCellDelegate?
|
var delegate: FillPasswordTableViewCellDelegate?
|
||||||
|
|
||||||
|
@IBOutlet weak var settingButton: UIButton!
|
||||||
|
@IBOutlet weak var generateButton: UIButton!
|
||||||
|
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
// Initialization code
|
// Initialization code
|
||||||
contentTextField.font = UIFont(name: Globals.passwordFonts, size: (contentTextField.font?.pointSize)!)
|
contentTextField.font = UIFont(name: Globals.passwordFonts, size: (contentTextField.font?.pointSize)!)
|
||||||
|
|
||||||
|
// Force aspect ratio of button images
|
||||||
|
settingButton.imageView?.contentMode = .scaleAspectFit
|
||||||
|
generateButton.imageView?.contentMode = .scaleAspectFit
|
||||||
}
|
}
|
||||||
|
|
||||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||||
|
|
@ -33,6 +41,10 @@ class FillPasswordTableViewCell: ContentTableViewCell {
|
||||||
self.delegate?.generateAndCopyPassword()
|
self.delegate?.generateAndCopyPassword()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func showHidePasswordSettings() {
|
||||||
|
self.delegate?.showHidePasswordSettings()
|
||||||
|
}
|
||||||
|
|
||||||
// re-color
|
// re-color
|
||||||
@IBAction func textFieldDidChange(_ sender: UITextField) {
|
@IBAction func textFieldDidChange(_ sender: UITextField) {
|
||||||
contentTextField.attributedText = Utils.attributedPassword(plainPassword: sender.text ?? "")
|
contentTextField.attributedText = Utils.attributedPassword(plainPassword: sender.text ?? "")
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="89"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX">
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX" userLabel="Password">
|
||||||
<rect key="frame" x="15" y="8" width="220" height="74"/>
|
<rect key="frame" x="15" y="8" width="78" height="73.5"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="qVX-ui-dIn"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="9gX-VT-F9P"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
|
@ -31,31 +31,49 @@
|
||||||
<action selector="textFieldDidChange:" destination="KGk-i7-Jjw" eventType="editingChanged" id="U0t-2B-JxY"/>
|
<action selector="textFieldDidChange:" destination="KGk-i7-Jjw" eventType="editingChanged" id="U0t-2B-JxY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" reversesTitleShadowWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam">
|
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SZJ-aY-45Y" userLabel="Setting">
|
||||||
<rect key="frame" x="243" y="-0.5" width="64" height="89.5"/>
|
<rect key="frame" x="285" y="8" width="20" height="73.5"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="64" id="X1A-kc-qJy"/>
|
<constraint firstAttribute="width" constant="20" id="D9D-FC-ANz"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<state key="normal" title="Generate"/>
|
<state key="normal" image="HorizontalSettings"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="showHidePasswordSettings" destination="KGk-i7-Jjw" eventType="touchUpInside" id="3I8-S0-qlo"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam" userLabel="Generate">
|
||||||
|
<rect key="frame" x="255" y="8" width="20" height="73.5"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="20" id="l0l-7B-Tws"/>
|
||||||
|
</constraints>
|
||||||
|
<state key="normal" image="Refresh"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="generatePassword:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="M61-hs-PCP"/>
|
<action selector="generatePassword:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="M61-hs-PCP"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="77" id="3S1-gj-XVP" userLabel="trailingMargin = Content Text Field.trailing + 71"/>
|
<constraint firstItem="SZJ-aY-45Y" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="5XP-xZ-YWY"/>
|
||||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="centerY" secondItem="k0U-2N-YaX" secondAttribute="centerY" id="Fls-do-khd"/>
|
<constraint firstAttribute="trailingMargin" secondItem="SZJ-aY-45Y" secondAttribute="trailing" constant="7" id="5bp-bm-9vv"/>
|
||||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="height" secondItem="H2p-sc-9uM" secondAttribute="height" id="Gok-dX-tQ5"/>
|
<constraint firstAttribute="bottomMargin" secondItem="SZJ-aY-45Y" secondAttribute="bottom" id="CMF-1f-MdG"/>
|
||||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="leading" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="8" id="hsy-gb-ero" userLabel="Generate.leading = Content Text Field.trailing"/>
|
<constraint firstItem="hTh-ek-Xam" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="OjQ-mD-CWV"/>
|
||||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="jKd-Xa-tr5"/>
|
<constraint firstItem="SZJ-aY-45Y" firstAttribute="leading" secondItem="hTh-ek-Xam" secondAttribute="trailing" constant="10" id="UlR-NB-9So"/>
|
||||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="7" id="lAm-D6-pir"/>
|
<constraint firstAttribute="bottomMargin" secondItem="hTh-ek-Xam" secondAttribute="bottom" id="bvu-Q0-QAG"/>
|
||||||
<constraint firstAttribute="bottomMargin" secondItem="k0U-2N-YaX" secondAttribute="bottom" constant="-1" id="pLC-H7-JTU" userLabel="bottomMargin = Content Text Field.bottom"/>
|
<constraint firstAttribute="bottomMargin" secondItem="k0U-2N-YaX" secondAttribute="bottom" id="lRv-MC-Cru"/>
|
||||||
|
<constraint firstItem="k0U-2N-YaX" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="sUk-sk-JLT"/>
|
||||||
|
<constraint firstItem="k0U-2N-YaX" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="7" id="zGn-an-SlK"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="contentTextField" destination="k0U-2N-YaX" id="kQO-tR-Epp"/>
|
<outlet property="contentTextField" destination="k0U-2N-YaX" id="kQO-tR-Epp"/>
|
||||||
|
<outlet property="generateButton" destination="hTh-ek-Xam" id="MUa-qs-uw4"/>
|
||||||
|
<outlet property="settingButton" destination="SZJ-aY-45Y" id="G4T-04-NBD"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="34" y="77"/>
|
<point key="canvasLocation" x="34" y="77"/>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</objects>
|
</objects>
|
||||||
|
<resources>
|
||||||
|
<image name="HorizontalSettings" width="25" height="25"/>
|
||||||
|
<image name="Refresh" width="32" height="32"/>
|
||||||
|
</resources>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ class LabelTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
weak var delegatePasswordTableView : PasswordDetailTableViewController?
|
weak var delegatePasswordTableView : PasswordDetailTableViewController?
|
||||||
|
|
||||||
|
var passwordDisplayButton: UIButton?
|
||||||
|
var buttons: UIView?
|
||||||
|
|
||||||
var cellData: LabelTableViewCellData? {
|
var cellData: LabelTableViewCellData? {
|
||||||
didSet {
|
didSet {
|
||||||
titleLabel.text = cellData?.title ?? ""
|
titleLabel.text = cellData?.title ?? ""
|
||||||
|
|
@ -43,9 +46,11 @@ class LabelTableViewCell: UITableViewCell {
|
||||||
} else {
|
} else {
|
||||||
contentLabel.text = Globals.passwordDots
|
contentLabel.text = Globals.passwordDots
|
||||||
}
|
}
|
||||||
|
contentLabel.font = UIFont(name: Globals.passwordFonts, size: contentLabel.font.pointSize)
|
||||||
} else {
|
} else {
|
||||||
contentLabel.text = cellData?.content
|
contentLabel.text = cellData?.content
|
||||||
}
|
}
|
||||||
|
updateButtons()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,6 +64,13 @@ class LabelTableViewCell: UITableViewCell {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
if buttons != nil {
|
||||||
|
self.accessoryView = buttons
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||||
super.setSelected(selected, animated: animated)
|
super.setSelected(selected, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
@ -99,13 +111,26 @@ class LabelTableViewCell: UITableViewCell {
|
||||||
contentLabel.text = ""
|
contentLabel.text = ""
|
||||||
}
|
}
|
||||||
isReveal = true
|
isReveal = true
|
||||||
|
passwordDisplayButton?.setImage(#imageLiteral(resourceName: "Invisible"), for: .normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func concealPassword(_ sender: Any?) {
|
func concealPassword(_ sender: Any?) {
|
||||||
contentLabel.text = Globals.passwordDots
|
contentLabel.text = Globals.passwordDots
|
||||||
isReveal = false
|
isReveal = false
|
||||||
|
passwordDisplayButton?.setImage(#imageLiteral(resourceName: "Visible"), for: .normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reversePasswordDisplay(_ sender: Any?) {
|
||||||
|
if isReveal {
|
||||||
|
// conceal
|
||||||
|
concealPassword(sender)
|
||||||
|
} else {
|
||||||
|
// reveal
|
||||||
|
revealPassword(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func openLink(_ sender: Any?) {
|
func openLink(_ sender: Any?) {
|
||||||
// if isURLCell, passwordTableView should not be nil
|
// if isURLCell, passwordTableView should not be nil
|
||||||
delegatePasswordTableView!.openLink()
|
delegatePasswordTableView!.openLink()
|
||||||
|
|
@ -115,4 +140,41 @@ class LabelTableViewCell: UITableViewCell {
|
||||||
// if isHOTPCell, passwordTableView should not be nil
|
// if isHOTPCell, passwordTableView should not be nil
|
||||||
delegatePasswordTableView!.getNextHOTP()
|
delegatePasswordTableView!.getNextHOTP()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateButtons() {
|
||||||
|
passwordDisplayButton = nil
|
||||||
|
buttons = nil
|
||||||
|
if isPasswordCell {
|
||||||
|
// password button
|
||||||
|
passwordDisplayButton = UIButton(type: .system)
|
||||||
|
passwordDisplayButton!.frame = CGRect(x: 0, y: 0, width: Globals.tableCellButtonSize, height: Globals.tableCellButtonSize)
|
||||||
|
passwordDisplayButton!.setImage(#imageLiteral(resourceName: "Visible"), for: .normal)
|
||||||
|
passwordDisplayButton!.imageView?.contentMode = .scaleAspectFit
|
||||||
|
passwordDisplayButton!.addTarget(self, action: #selector(reversePasswordDisplay), for: UIControlEvents.touchUpInside)
|
||||||
|
buttons = passwordDisplayButton
|
||||||
|
} else if isHOTPCell {
|
||||||
|
let spacing = CGFloat(10.0)
|
||||||
|
|
||||||
|
// hotp button
|
||||||
|
let nextButton = UIButton(type: .system)
|
||||||
|
nextButton.frame = CGRect(x: 0, y: 0,
|
||||||
|
width: Globals.tableCellButtonSize, height: Globals.tableCellButtonSize)
|
||||||
|
nextButton.setImage(#imageLiteral(resourceName: "Refresh"), for: .normal)
|
||||||
|
nextButton.imageView?.contentMode = .scaleAspectFit
|
||||||
|
nextButton.addTarget(self, action: #selector(getNextHOTP), for: UIControlEvents.touchUpInside)
|
||||||
|
|
||||||
|
// password button
|
||||||
|
passwordDisplayButton = UIButton(type: .system)
|
||||||
|
passwordDisplayButton!.frame = CGRect(x: Globals.tableCellButtonSize + spacing, y: 0,
|
||||||
|
width: Globals.tableCellButtonSize, height: Globals.tableCellButtonSize)
|
||||||
|
passwordDisplayButton!.setImage(#imageLiteral(resourceName: "Visible"), for: .normal)
|
||||||
|
passwordDisplayButton!.imageView?.contentMode = .scaleAspectFit
|
||||||
|
passwordDisplayButton!.addTarget(self, action: #selector(reversePasswordDisplay), for: UIControlEvents.touchUpInside)
|
||||||
|
|
||||||
|
buttons = UIView()
|
||||||
|
buttons!.frame = CGRect(x: 0, y: 0, width: Globals.tableCellButtonSize * 2 + spacing, height: Globals.tableCellButtonSize)
|
||||||
|
buttons!.addSubview(nextButton)
|
||||||
|
buttons!.addSubview(passwordDisplayButton!)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="74"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="74"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="73.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="73"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="MwT-Jl-hhE">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="MwT-Jl-hhE">
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t7T-HC-hUd" userLabel="Title">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="t7T-HC-hUd" userLabel="Title">
|
||||||
<rect key="frame" x="15" y="8" width="30" height="57.5"/>
|
<rect key="frame" x="15" y="8" width="30" height="57.5"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="8Tz-Qo-Mkg"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="8Tz-Qo-Mkg"/>
|
||||||
|
|
|
||||||