Skip to content

Commit

Permalink
Navigate split view on table row selection
Browse files Browse the repository at this point in the history
Also add toggle for favicon in list views
  • Loading branch information
grgar committed Oct 13, 2023
1 parent 6884131 commit 2a94481
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 198 deletions.
145 changes: 29 additions & 116 deletions ContentView.swift
Original file line number Diff line number Diff line change
@@ -1,128 +1,41 @@
import SwiftUI

struct ContentView: View {
@State private var visibility: NavigationSplitViewVisibility = .all
enum NavigationCategory: View {
case rules, shared, change, appended

var body: some View {
NavigationSplitView(columnVisibility: $visibility) {
List {
NavigationLink {
PasswordRules()
} label: {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Password Rules")
Text("Rules to generate compatible passwords with websites' particular requirements.")
}
#else
Text("Password Rules")
#endif
} icon: {
Image(systemName: "lock.rectangle")
}
#if os(iOS)
.padding(.vertical)
#endif
}
switch self {
case .rules:
PasswordRules()
case .shared:
SharedCredentials()
case .change:
ChangePasswordURLs()
case .appended:
Appended2FA()
}
}
}

NavigationLink {
SharedCredentials()
} label: {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Shared Credentials")
Text("Groups of websites known to use the same credential backend, which can be used to enhance suggested credentials to sign in to websites.")
}
#else
Text("Shared Credentials")
#endif
} icon: {
Image(systemName: "rectangle.on.rectangle.angled")
}
#if os(iOS)
.padding(.vertical)
#endif
}
struct ContentView: View {
@State private var visibility: NavigationSplitViewVisibility = .all

NavigationLink {
ChangePasswordURLs()
} label: {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Change Password URLs")
Text("To drive the adoption of strong passwords, it's useful to be able to take users directly to websites' change password pages.")
}
#else
Text("Change Password URLs")
#endif
} icon: {
Image(systemName: "rectangle.and.pencil.and.ellipsis")
}
#if os(iOS)
.padding(.vertical)
#endif
}
@State private var navigationCategory: NavigationCategory?

NavigationLink {
Appended2FA()
} label: {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Websites Where 2FA Code is Appended to Password")
Text("Some websites use a two-factor authentication scheme where the user must append a generated code to their password when signing in.")
}
#else
Text("Appended 2FA")
#endif
} icon: {
Image(systemName: "123.rectangle")
}
#if os(iOS)
.padding(.vertical)
#endif
}
}
.scrollContentBackground(.hidden)
.background {
HomeBackground()
}
.listStyle(.sidebar)
.navigationTitle(Text("Passwords Inspector"))
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#else
.navigationSplitViewColumnWidth(min: 180, ideal: 180)
#endif
.toolbar {
#if os(iOS)
ToolbarItemGroup(placement: .principal) {
Label {
Text("Passwords Inspector")
} icon: {
Image(systemName: "key.fill")
.rotationEffect(.radians(-0.3))
}
.labelStyle(.titleAndIcon)
.foregroundStyle(.tint, .tertiary)
}
#endif
}
var body: some View {
NavigationSplitView(columnVisibility: $visibility) {
HomeSidebar(selection: $navigationCategory)
.listStyle(.sidebar)
} content: {
EmptyView()
if let navigationCategory {
navigationCategory
.navigationSplitViewColumnWidth(min: 320, ideal: 640)
}
} detail: {
EmptyView()
Text("")
.accessibilityHidden(true)
.navigationSplitViewColumnWidth(ideal: navigationCategory == .rules ? 320 : 0,
max: navigationCategory == .rules ? 480 : 0)
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions Domains/Appended2FA.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,7 @@ struct Appended2FA: View {
Text("Domains which use a two-factor authentication scheme where you must append a generated code to your password when signing in.")
}
}
.searchable(text: $searchText, prompt: Text("Search Domains"))
.refreshable {
await reload()
}
.task {
guard response.isEmpty else { return }
await reload(cache: .returnCacheDataElseLoad)
}
#if os(iOS)
.toolbar {
Button {
showHelp.toggle()
Expand All @@ -78,6 +71,7 @@ struct Appended2FA: View {
.presentationCompactAdaptation(horizontal: .sheet, vertical: .popover)
}
}
#endif
}
.searchable(text: $searchText, prompt: Text("Search Domains"))
.refreshable {
Expand Down
15 changes: 14 additions & 1 deletion Domains/ChangePasswordURLs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ struct ChangePasswordURLs: View {

static let getURL = URL(string: "https://raw.githubusercontent.com/apple/password-manager-resources/main/quirks/change-password-URLs.json")!

@AppStorage("showFavicon") private var showFavicon = true

func reload(cache: NSURLRequest.CachePolicy = .reloadIgnoringLocalCacheData) async {
switch await Self.reload(cache: cache) {
case let .success(data):
Expand Down Expand Up @@ -59,12 +61,23 @@ struct ChangePasswordURLs: View {
.foregroundStyle(.secondary)
}
} icon: {
Favicon(domain: response.key)
if showFavicon {
Favicon(domain: response.key)
}
}
}
.foregroundStyle(.foreground)
}
}
.toolbar {
ToolbarItemGroup(placement: .automatic) {
Picker("Favicon", selection: $showFavicon) {
Label("Show", systemImage: "checklist.unchecked").tag(true)
Label("Hide", systemImage: "list.bullet").tag(false)
}
.pickerStyle(.segmented)
}
}
.searchable(text: $searchText, prompt: Text("Search Domains"))
.searchSuggestions {
if !searchText.contains(".") {
Expand Down
File renamed without changes.
118 changes: 118 additions & 0 deletions Home/HomeSidebar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import SwiftUI

struct HomeSidebar: View {
@Binding var selection: NavigationCategory?

var body: some View {
List(selection: $selection) {
NavigationLink(value: NavigationCategory.rules) {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Password Rules")
Text("Rules to generate compatible passwords with websites' particular requirements.")
}
#else
Text("Password Rules")
#endif
} icon: {
Image(systemName: "lock.rectangle")
}
#if os(iOS)
.padding(.vertical)
#endif
}

NavigationLink(value: NavigationCategory.shared) {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Shared Credentials")
Text("Groups of websites known to use the same credential backend, which can be used to enhance suggested credentials to sign in to websites.")
}
#else
Text("Shared Credentials")
#endif
} icon: {
Image(systemName: "rectangle.on.rectangle.angled")
}
#if os(iOS)
.padding(.vertical)
#endif
}

NavigationLink(value: NavigationCategory.change) {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Change Password URLs")
Text("To drive the adoption of strong passwords, it's useful to be able to take users directly to websites' change password pages.")
}
#else
Text("Change Password URLs")
#endif
} icon: {
Image(systemName: "rectangle.and.pencil.and.ellipsis")
}
#if os(iOS)
.padding(.vertical)
#endif
}

NavigationLink(value: NavigationCategory.appended) {
Label {
#if os(iOS)
LabeledContent {
EmptyView()
} label: {
Text("Websites Where 2FA Code is Appended to Password")
Text("Some websites use a two-factor authentication scheme where the user must append a generated code to their password when signing in.")
}
#else
Text("Appended 2FA")
#endif
} icon: {
Image(systemName: "123.rectangle")
}
#if os(iOS)
.padding(.vertical)
#endif
}
}
.scrollContentBackground(.hidden)
.background {
HomeBackground()
}
.listStyle(.sidebar)
.navigationTitle(Text("Passwords Inspector"))
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#else
.navigationSplitViewColumnWidth(min: 180, ideal: 180)
#endif
.toolbar {
#if os(iOS)
ToolbarItemGroup(placement: .principal) {
Label {
Text("Passwords Inspector")
} icon: {
Image(systemName: "key.fill")
.rotationEffect(.radians(-0.3))
}
.labelStyle(.titleAndIcon)
.foregroundStyle(.tint, .tertiary)
}
#endif
}
}
}

#Preview {
HomeSidebar(selection: .constant(nil))
}
14 changes: 13 additions & 1 deletion Passwords Inspector.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
174820E22AD33DD8006AF2AC /* HomeBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 174820E12AD33DD8006AF2AC /* HomeBackground.swift */; };
174840992AD49A3E00EB9592 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 174840982AD49A3E00EB9592 /* Settings.bundle */; };
17618B7C2AC200C600B31C28 /* PasswordRules.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17618B7B2AC200C600B31C28 /* PasswordRules.swift */; };
1776885F2AD9D65400F68E88 /* HomeSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1776885E2AD9D65400F68E88 /* HomeSidebar.swift */; };
17882AC52AC84AAD0037E3A6 /* PasswordRuleDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17882AC42AC84AAD0037E3A6 /* PasswordRuleDetail.swift */; };
17BFF7002ABCDDC2004047AD /* SharedCredentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17BFF6FF2ABCDDC2004047AD /* SharedCredentials.swift */; };
17BFF7022ABF217D004047AD /* Favicon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17BFF7012ABF217D004047AD /* Favicon.swift */; };
Expand All @@ -35,6 +36,7 @@
174840982AD49A3E00EB9592 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
1748409A2AD4A73C00EB9592 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
17618B7B2AC200C600B31C28 /* PasswordRules.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordRules.swift; sourceTree = "<group>"; };
1776885E2AD9D65400F68E88 /* HomeSidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeSidebar.swift; sourceTree = "<group>"; };
17882AC42AC84AAD0037E3A6 /* PasswordRuleDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordRuleDetail.swift; sourceTree = "<group>"; };
17BFF6FF2ABCDDC2004047AD /* SharedCredentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedCredentials.swift; sourceTree = "<group>"; };
17BFF7012ABF217D004047AD /* Favicon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Favicon.swift; sourceTree = "<group>"; };
Expand All @@ -57,7 +59,7 @@
children = (
1717C49D2ABA44EC00AD991A /* PIApp.swift */,
1717C49F2ABA44EC00AD991A /* ContentView.swift */,
174820E12AD33DD8006AF2AC /* HomeBackground.swift */,
177688602AD9D65A00F68E88 /* Home */,
17882AC22AC848380037E3A6 /* Rule */,
17882AC32AC8483E0037E3A6 /* Domains */,
17BFF7012ABF217D004047AD /* Favicon.swift */,
Expand All @@ -77,6 +79,15 @@
name = Products;
sourceTree = "<group>";
};
177688602AD9D65A00F68E88 /* Home */ = {
isa = PBXGroup;
children = (
1776885E2AD9D65400F68E88 /* HomeSidebar.swift */,
174820E12AD33DD8006AF2AC /* HomeBackground.swift */,
);
path = Home;
sourceTree = "<group>";
};
17882AC22AC848380037E3A6 /* Rule */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -175,6 +186,7 @@
17BFF7002ABCDDC2004047AD /* SharedCredentials.swift in Sources */,
17882AC52AC84AAD0037E3A6 /* PasswordRuleDetail.swift in Sources */,
173245232AC4CE99005C3AC2 /* Rule.swift in Sources */,
1776885F2AD9D65400F68E88 /* HomeSidebar.swift in Sources */,
17BFF7042ABF7D50004047AD /* Appended2FA.swift in Sources */,
17BFF7022ABF217D004047AD /* Favicon.swift in Sources */,
173245252AC4D29D005C3AC2 /* PasswordRuleChips.swift in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions Rule/PasswordRuleDetail.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ struct PasswordRuleDetail: View {
} header: {
Text("Length")
}
#if os(macOS)
.listRowSeparator(.hidden)
#endif

Section {
Grid {
Expand Down
Loading

0 comments on commit 2a94481

Please sign in to comment.