Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix passwords empty screen lock icon in dark mode #3436

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ final class PasswordManagementItemListModel: ObservableObject {
autofillPreferences.isAutoLockEnabled ? UserText.pmEmptyStateDefaultDescription : UserText.pmEmptyStateDefaultDescriptionAutolockOff
}

var emptyStateMessageViewHeight: CGFloat {
autofillPreferences.isAutoLockEnabled ? 32 : 16
}

var emptyStateMessageLinkText: String {
UserText.learnMore
}
Expand Down
75 changes: 30 additions & 45 deletions DuckDuckGo/SecureVault/View/PasswordManagementViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ final class PasswordManagementViewController: NSViewController {
@IBOutlet var emptyState: NSView!
@IBOutlet var emptyStateImageView: NSImageView!
@IBOutlet var emptyStateTitle: NSTextField!
@IBOutlet var emptyStateMessage: NSTextView!
@IBOutlet var emptyStateMessageHeight: NSLayoutConstraint!
@IBOutlet var emptyStateMessageContainer: NSView!
@IBOutlet var emptyStateButton: NSButton!
@IBOutlet weak var exportLoginItem: NSMenuItem!
@IBOutlet var lockScreen: NSView!
Expand Down Expand Up @@ -173,9 +173,7 @@ final class PasswordManagementViewController: NSViewController {

emptyStateTitle.attributedStringValue = NSAttributedString.make(emptyStateTitle.stringValue, lineHeight: 1.14, kern: -0.23)

emptyStateMessage.isSelectable = true
emptyStateMessage.delegate = self
setUpEmptyStateMessageAttributedText()
setUpEmptyStateMessageView()

addVaultItemButton.toolTip = UserText.addItemTooltip
moreButton.toolTip = UserText.moreOptionsTooltip
Expand All @@ -201,47 +199,20 @@ final class PasswordManagementViewController: NSViewController {
.store(in: &cancellables)
}

private func setUpEmptyStateMessageAttributedText() {
private func setUpEmptyStateMessageView() {
guard let listModel else { return }
emptyStateMessage.delegate = self

let linkAttributes: [NSAttributedString.Key: Any] = [
.foregroundColor: NSColor.linkBlue,
.cursor: NSCursor.pointingHand
]
let message = " \(listModel.emptyStateMessageDescription) [\(listModel.emptyStateMessageLinkText)](\(listModel.emptyStateMessageLinkURL))"

emptyStateMessage.linkTextAttributes = linkAttributes

let attachment = NSTextAttachment()
attachment.image = NSImage(resource: .lockSolid16).tinted(with: NSColor.blackWhite80)
attachment.bounds = CGRect(x: 0, y: -1, width: 12, height: 12)
let attributedTextImage = NSMutableAttributedString(attachment: attachment)

let string = NSMutableAttributedString(attributedString: attributedTextImage)

let messageString = NSMutableAttributedString(string: " " + listModel.emptyStateMessageDescription + " ")
string.append(messageString)

let linkString = NSMutableAttributedString(string: listModel.emptyStateMessageLinkText, attributes: [
.link: listModel.emptyStateMessageLinkURL
])
string.append(linkString)

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
string.addAttributes([
.cursor: NSCursor.arrow,
.paragraphStyle: paragraphStyle,
.font: NSFont.systemFont(ofSize: 13, weight: .regular),
.foregroundColor: NSColor.blackWhite80
], range: NSRange(location: 0, length: string.length))

let maxSize = NSSize(width: 280, height: 20000)
let bounds = string.boundingRect(with: maxSize, options: .usesLineFragmentOrigin)

emptyStateMessageHeight.constant = bounds.height

emptyStateMessage.textStorage?.setAttributedString(string)
let hostingView = NSHostingView(rootView: PasswordManagementEmptyStateMessage(
message: message,
image: .lockSolid16
))
hostingView.frame = emptyStateMessageContainer.bounds
hostingView.autoresizingMask = [.height, .width]
hostingView.translatesAutoresizingMaskIntoConstraints = true
emptyStateMessageContainer.addSubview(hostingView)
emptyStateMessageHeight.constant = listModel.emptyStateMessageViewHeight
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the height constant is causing some issues with other languages which have longer strings
image
image

}

private func setupStrings() {
Expand All @@ -252,7 +223,7 @@ final class PasswordManagementViewController: NSViewController {
unlockYourAutofillLabel.title = UserText.passwordManagerUnlockAutofill
autofillTitleLabel.stringValue = UserText.passwordManagementTitle
emptyStateTitle.stringValue = UserText.pmEmptyStateDefaultTitle
setUpEmptyStateMessageAttributedText()
setUpEmptyStateMessageView()
emptyStateButton.title = UserText.pmEmptyStateDefaultButtonTitle
}

Expand Down Expand Up @@ -1079,10 +1050,10 @@ final class PasswordManagementViewController: NSViewController {
emptyStateImageView.image = image
emptyStateTitle.attributedStringValue = NSAttributedString.make(title, lineHeight: 1.14, kern: -0.23)
if !hideMessage {
setUpEmptyStateMessageAttributedText()
setUpEmptyStateMessageView()
}
emptyStateMessage.isHidden = hideMessage
emptyStateButton.isHidden = hideButton
emptyStateMessageContainer.isHidden = hideMessage
}

private func requestSync() {
Expand Down Expand Up @@ -1159,3 +1130,17 @@ extension PasswordManagementViewController: NSMenuItemValidation {
return !accounts.isEmpty
}
}

struct PasswordManagementEmptyStateMessage: View {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In-line links + images are just so much easier with SwiftUI...

let message: String
let image: ImageResource

var body: some View {
(
Text(Image(image)).baselineOffset(-1.0)
+
Text(.init(message))
)
.multilineTextAlignment(.center)
}
}
44 changes: 6 additions & 38 deletions DuckDuckGo/SecureVault/View/PasswordManager.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -68,45 +68,13 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<scrollView verticalHuggingPriority="1000" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="pdt-CS-krc">
<customView translatesAutoresizingMaskIntoConstraints="NO" id="bOW-bY-YOb">
<rect key="frame" x="0.0" y="36" width="280" height="32"/>
<clipView key="contentView" drawsBackground="NO" id="Dap-gW-wWH">
<rect key="frame" x="0.0" y="0.0" width="280" height="32"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="NO" spellingCorrection="YES" smartInsertDelete="YES" id="gmL-Uq-tGd">
<rect key="frame" x="0.0" y="0.0" width="280" height="32"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" name="BlackWhite60"/>
<color key="backgroundColor" name="ClearColor"/>
<size key="minSize" width="280" height="32"/>
<size key="maxSize" width="560" height="131"/>
<attributedString key="textStorage">
<fragment content="Change in Preferences">
<attributes>
<color key="NSColor" name="BlackWhite60"/>
<font key="NSFont" metaFont="system"/>
<paragraphStyle key="NSParagraphStyle" alignment="center" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
</textView>
</subviews>
<color key="backgroundColor" name="ClearColor"/>
</clipView>
<constraints>
<constraint firstAttribute="height" constant="32" id="9Gc-gG-jLS"/>
<constraint firstAttribute="width" constant="280" id="wtP-ld-cSX"/>
<constraint firstAttribute="height" constant="32" id="FaO-01-poD"/>
<constraint firstAttribute="width" constant="280" id="OIV-J6-tFd"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="6mo-LF-gLV">
<rect key="frame" x="-100" y="-100" width="240" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="hHs-sP-BAC">
<rect key="frame" x="-100" y="-100" width="16" height="135"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</customView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="k2f-2R-tqE">
<rect key="frame" x="103" y="-7" width="74" height="32"/>
<buttonCell key="cell" type="push" title="Import" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="HLU-9T-4Gh">
Expand Down Expand Up @@ -380,8 +348,8 @@
<outlet property="emptyState" destination="hjZ-Ei-q1x" id="gSI-Jw-BtE"/>
<outlet property="emptyStateButton" destination="k2f-2R-tqE" id="Jda-DC-H4H"/>
<outlet property="emptyStateImageView" destination="ZrN-x7-2Xv" id="Ofb-1z-Wnl"/>
<outlet property="emptyStateMessage" destination="gmL-Uq-tGd" id="3ug-4J-cn6"/>
<outlet property="emptyStateMessageHeight" destination="9Gc-gG-jLS" id="f2Z-tb-ofV"/>
<outlet property="emptyStateMessageContainer" destination="bOW-bY-YOb" id="u7P-MS-tRJ"/>
<outlet property="emptyStateMessageHeight" destination="FaO-01-poD" id="iXh-Qz-IRA"/>
<outlet property="emptyStateTitle" destination="PPi-GW-baU" id="PXq-2b-bb0"/>
<outlet property="exportLoginItem" destination="RrT-yL-ePc" id="0oI-95-iPv"/>
<outlet property="importPasswordMenuItem" destination="bzJ-X6-X6D" id="xYB-fG-mF4"/>
Expand Down
Loading