Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion DuckDuckGo/Common/View/SwiftUI/FaviconView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct FaviconView: View {
ZStack {
let eTLDplus1 = ContentBlocking.shared.tld.eTLDplus1(domain) ?? domain
Rectangle()
.foregroundColor(Color.forString(eTLDplus1))
.foregroundColor(Color.forDomain(eTLDplus1))
Text(String(eTLDplus1.capitalized.first ?? "?"))
.font(.title)
.foregroundColor(Color.white)
Expand Down
29 changes: 14 additions & 15 deletions DuckDuckGo/Common/View/SwiftUI/LoginFaviconView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,29 @@
//

import SwiftUI
import BrowserServicesKit
import SwiftUIExtensions

struct LoginFaviconView: View {
let domain: String
let generatedIconLetters: String

let domain: String?

let faviconManagement: FaviconManagement = FaviconManager.shared

var body: some View {
Group {
if let image = faviconManagement.getCachedFavicon(for: domain, sizeCategory: .small)?.image {
Image(nsImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 32)
.cornerRadius(4.0)
.padding(.leading, 6)
} else {
LetterIconView(title: generatedIconLetters)
}

if let image = favicon {
Image(nsImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 32)
.cornerRadius(4.0)
}

}

var favicon: NSImage? {
guard let domain else {
return NSImage(named: "Login")
}
return faviconManagement.getCachedFavicon(for: domain, sizeCategory: .small)?.image ?? NSImage(named: "Login")
}

Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/PinnedTabs/View/PinnedTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ struct PinnedTabInnerView: View {
} else if let domain = model.content.url?.host, let eTLDplus1 = ContentBlocking.shared.tld.eTLDplus1(domain), let firstLetter = eTLDplus1.capitalized.first.flatMap(String.init) {
ZStack {
Rectangle()
.foregroundColor(.forString(eTLDplus1))
.foregroundColor(.forDomain(eTLDplus1))
Text(firstLetter)
.font(.caption)
.foregroundColor(.white)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,18 +274,11 @@ final class PasswordManagementItemListModel: ObservableObject {
@Published var canChangeCategory: Bool = true

private var onItemSelected: (_ old: SecureVaultItem?, _ new: SecureVaultItem?) -> Void
private let tld: TLD
private let urlMatcher: AutofillDomainNameUrlMatcher
private static let randomColorsCount = 15

init(passwordManagerCoordinator: PasswordManagerCoordinating,
onItemSelected: @escaping (_ old: SecureVaultItem?, _ new: SecureVaultItem?) -> Void,
urlMatcher: AutofillDomainNameUrlMatcher = AutofillDomainNameUrlMatcher(),
tld: TLD = ContentBlocking.shared.tld) {
onItemSelected: @escaping (_ old: SecureVaultItem?, _ new: SecureVaultItem?) -> Void) {
self.onItemSelected = onItemSelected
self.passwordManagerCoordinator = passwordManagerCoordinator
self.urlMatcher = urlMatcher
self.tld = tld
}

func update(items: [SecureVaultItem]) {
Expand Down Expand Up @@ -458,10 +451,4 @@ final class PasswordManagementItemListModel: ObservableObject {
}
}

func tldForAccount(_ account: SecureVaultModels.WebsiteAccount) -> String {
let name = account.name(tld: tld, autofillDomainNameUrlMatcher: urlMatcher)
let title = (account.title?.isEmpty == false) ? account.title! : "#"
return tld.eTLDplus1(name) ?? title
}

}
19 changes: 4 additions & 15 deletions DuckDuckGo/SecureVault/Model/PasswordManagementLoginModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import Combine
import BrowserServicesKit
import Common

final class PasswordManagementLoginModel: ObservableObject, PasswordManagementItemModel {

Expand All @@ -33,7 +32,7 @@ final class PasswordManagementLoginModel: ObservableObject, PasswordManagementIt

var onSaveRequested: (SecureVaultModels.WebsiteCredentials) -> Void
var onDeleteRequested: (SecureVaultModels.WebsiteCredentials) -> Void
var urlMatcher: AutofillDomainNameUrlMatcher
var urlMatcher: AutofillUrlMatcher
var emailManager: EmailManager

var isEditingPublisher: Published<Bool>.Publisher {
Expand All @@ -53,7 +52,6 @@ final class PasswordManagementLoginModel: ObservableObject, PasswordManagementIt
@Published var notes: String = ""
@Published var isEditing = false
@Published var isNew = false
@Published var domainTLD = ""

var isDirty: Bool {
title != "" || username != "" || password != "" || domain != "" || notes != ""
Expand Down Expand Up @@ -123,23 +121,16 @@ final class PasswordManagementLoginModel: ObservableObject, PasswordManagementIt
usernameIsPrivateEmail && privateEmailMessage != ""
}

private let tld: TLD
private let urlSort: AutofillDomainNameUrlSort
private static let randomColorsCount = 15

init(onSaveRequested: @escaping (SecureVaultModels.WebsiteCredentials) -> Void,
onDeleteRequested: @escaping (SecureVaultModels.WebsiteCredentials) -> Void,
urlMatcher: AutofillDomainNameUrlMatcher,
emailManager: EmailManager,
tld: TLD = ContentBlocking.shared.tld,
urlSort: AutofillDomainNameUrlSort) {
urlMatcher: AutofillUrlMatcher = AutofillDomainNameUrlMatcher(),
emailManager: EmailManager = EmailManager()) {
self.onSaveRequested = onSaveRequested
self.onDeleteRequested = onDeleteRequested
self.urlMatcher = urlMatcher
self.emailManager = emailManager
self.tld = tld
self.urlSort = urlSort
self.emailManager.requestDelegate = self

}

func setSecureVaultModel<Model>(_ modelObject: Model) {
Expand Down Expand Up @@ -210,8 +201,6 @@ final class PasswordManagementLoginModel: ObservableObject, PasswordManagementIt
domain = urlMatcher.normalizeUrlForWeb(credentials?.account.domain ?? "")
notes = credentials?.account.notes ?? ""
isNew = credentials?.account.id == nil
let name = credentials?.account.name(tld: tld, autofillDomainNameUrlMatcher: urlMatcher)
domainTLD = tld.eTLDplus1(name) ?? credentials?.account.title ?? "#"

// Determine Private Email Status when required
usernameIsPrivateEmail = emailManager.isPrivateEmail(email: username)
Expand Down
17 changes: 3 additions & 14 deletions DuckDuckGo/SecureVault/View/PasswordManagementItemList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Foundation
import SwiftUI
import BrowserServicesKit
import Combine
import SwiftUIExtensions

struct ScrollOffsetKey: PreferenceKey {
typealias Value = CGFloat
Expand Down Expand Up @@ -268,13 +267,6 @@ private struct ItemView: View {
let item: SecureVaultItem
let action: () -> Void

func getIconLetters(account: SecureVaultModels.WebsiteAccount) -> String {
if let title = account.title, !title.isEmpty {
return title
}
return model.tldForAccount(account)
}

var body: some View {

let selected = model.selected == item
Expand All @@ -285,12 +277,9 @@ private struct ItemView: View {
HStack(spacing: 2) {

switch item {
case .account:
if let account = item.websiteAccount, let domain = account.domain {
LoginFaviconView(domain: domain, generatedIconLetters: getIconLetters(account: account))
} else {
LetterIconView(title: "#")
}
case .account(let account):
LoginFaviconView(domain: account.domain)
.padding(.leading, 6)
case .card:
Image("Card")
.frame(width: 32)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,18 +588,12 @@ private struct HeaderView: View {

@EnvironmentObject var model: PasswordManagementLoginModel

private func getIconLetters() -> String {
return !model.title.isEmpty ? model.title :
!model.domainTLD.isEmpty ? model.domainTLD :
"#"
}

var body: some View {

HStack(alignment: .center, spacing: 0) {
LoginFaviconView(domain: model.domain,
generatedIconLetters: getIconLetters())
.padding(.trailing, 10)

LoginFaviconView(domain: model.domain)
.padding(.trailing, 10)

if model.isNew || model.isEditing {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,6 @@ final class PasswordManagementViewController: NSViewController {

private let passwordManagerCoordinator: PasswordManagerCoordinating = PasswordManagerCoordinator.shared

private let emailManager = EmailManager()
private let urlMatcher = AutofillDomainNameUrlMatcher()
private let tld = ContentBlocking.shared.tld
private let urlSort = AutofillDomainNameUrlSort()

override func viewDidLoad() {
super.viewDidLoad()
createListView()
Expand Down Expand Up @@ -400,10 +395,7 @@ final class PasswordManagementViewController: NSViewController {
self?.doSaveCredentials(credentials)
}, onDeleteRequested: { [weak self] credentials in
self?.promptToDelete(credentials: credentials)
},
urlMatcher: urlMatcher,
emailManager: emailManager,
urlSort: urlSort)
})

self.itemModel = itemModel

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public extension Color {
)
}

static func forString(_ string: String) -> Color {
static func forDomain(_ domain: String) -> Color {
var consistentHash: Int {
return string.utf8
return domain.utf8
.map { return $0 }
.reduce(5381) { ($0 << 5) &+ $0 &+ Int($1) }
}
Expand Down

This file was deleted.

24 changes: 4 additions & 20 deletions UnitTests/SecureVault/PasswordManagementItemModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,10 @@ final class PasswordManagementItemModelTests: XCTestCase {
var isDirty = false
var savedCredentials: SecureVaultModels.WebsiteCredentials?
var deletedCredentials: SecureVaultModels.WebsiteCredentials?
var urlMatcher = AutofillDomainNameUrlMatcher()
var emailManager = EmailManager()
var tld = ContentBlocking.shared.tld
var urlSort = AutofillDomainNameUrlSort()

func testWhenCredentialsAreSavedThenSaveIsRequested() {
let model = PasswordManagementLoginModel(onSaveRequested: onSaveRequested,
onDeleteRequested: onDeleteRequested,
urlMatcher: urlMatcher,
emailManager: emailManager,
urlSort: urlSort)
onDeleteRequested: onDeleteRequested)

model.credentials = makeCredentials(id: "1")
model.save()
Expand All @@ -46,10 +39,7 @@ final class PasswordManagementItemModelTests: XCTestCase {

func testWhenCredentialsAreDeletedThenDeleteIsRequested() {
let model = PasswordManagementLoginModel(onSaveRequested: onSaveRequested,
onDeleteRequested: onDeleteRequested,
urlMatcher: urlMatcher,
emailManager: emailManager,
urlSort: urlSort)
onDeleteRequested: onDeleteRequested)

model.credentials = makeCredentials(id: "1")
model.requestDelete()
Expand All @@ -60,10 +50,7 @@ final class PasswordManagementItemModelTests: XCTestCase {

func testWhenCredentialsHasNoIdThenModelStateIsNew() {
let model = PasswordManagementLoginModel(onSaveRequested: onSaveRequested,
onDeleteRequested: onDeleteRequested,
urlMatcher: urlMatcher,
emailManager: emailManager,
urlSort: urlSort)
onDeleteRequested: onDeleteRequested)

model.createNew()

Expand All @@ -75,10 +62,7 @@ final class PasswordManagementItemModelTests: XCTestCase {

func testWhenModelIsEditedThenStateIsUpdated() {
let model = PasswordManagementLoginModel(onSaveRequested: onSaveRequested,
onDeleteRequested: onDeleteRequested,
urlMatcher: urlMatcher,
emailManager: emailManager,
urlSort: urlSort)
onDeleteRequested: onDeleteRequested)

model.credentials = makeCredentials(id: "1")
XCTAssertEqual(model.domain, "domain")
Expand Down