Add history and settings to watch app
This commit is contained in:
77
Sesame-Watch Watch App/Settings/SettingsKeyInputView.swift
Normal file
77
Sesame-Watch Watch App/Settings/SettingsKeyInputView.swift
Normal file
@ -0,0 +1,77 @@
|
||||
import SwiftUI
|
||||
import CryptoKit
|
||||
|
||||
struct SettingsKeyInputView: View {
|
||||
|
||||
let type: KeyManagement.KeyType
|
||||
|
||||
@State
|
||||
private var text: String = ""
|
||||
|
||||
let footnote: String
|
||||
|
||||
@EnvironmentObject
|
||||
private var keys: KeyManagement
|
||||
|
||||
private var hasKey: Bool {
|
||||
keys.has(type)
|
||||
}
|
||||
|
||||
private var displayText: String {
|
||||
keys.get(type)?.displayString ?? "-"
|
||||
}
|
||||
|
||||
private var copyText: String {
|
||||
guard let key = keys.get(type)?.data else {
|
||||
return ""
|
||||
}
|
||||
guard type.usesHashing else {
|
||||
return key.hexEncoded
|
||||
}
|
||||
return SHA256.hash(data: key).hexEncoded
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(alignment: .leading) {
|
||||
TextField(type.displayName, text: $text)
|
||||
.onSubmit(validateText)
|
||||
.foregroundColor(.accentColor)
|
||||
Text(footnote)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.navigationTitle(type.displayName)
|
||||
.onAppear {
|
||||
if text == "" {
|
||||
text = displayText
|
||||
print("Text inserted")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func validateText() {
|
||||
let cleanText = text.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
||||
guard let keyData = Data(fromHexEncodedString: cleanText) else {
|
||||
print("Invalid key string")
|
||||
return
|
||||
}
|
||||
let keyLength = type.keyLength.bitCount
|
||||
guard keyData.count * 8 == keyLength else {
|
||||
print("Invalid key length \(keyData.count * 8) bits, expected \(keyLength) (Input: '\(text)')")
|
||||
return
|
||||
}
|
||||
keys.save(type, data: keyData)
|
||||
print("Key \(type) saved")
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsKeyInputView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsKeyInputView(
|
||||
type: .remoteKey,
|
||||
footnote: "Some text describing the purpose of the key.")
|
||||
.environmentObject(KeyManagement())
|
||||
}
|
||||
}
|
47
Sesame-Watch Watch App/Settings/SettingsKeyItemLink.swift
Normal file
47
Sesame-Watch Watch App/Settings/SettingsKeyItemLink.swift
Normal file
@ -0,0 +1,47 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsKeyItemLink: View {
|
||||
|
||||
let type: KeyManagement.KeyType
|
||||
|
||||
let footnote: String
|
||||
|
||||
@EnvironmentObject
|
||||
private var keys: KeyManagement
|
||||
|
||||
@State
|
||||
private var keyText = "..."
|
||||
|
||||
var body: some View {
|
||||
NavigationLink {
|
||||
SettingsKeyInputView(
|
||||
type: type,
|
||||
footnote: footnote)
|
||||
.environmentObject(keys)
|
||||
} label: {
|
||||
SettingsListTextItem(
|
||||
title: type.displayName,
|
||||
value: keyText)
|
||||
.onAppear(perform: updateKeyText)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
|
||||
private func updateKeyText() {
|
||||
Task {
|
||||
let key = keys.get(type)?.displayString ?? "Not set"
|
||||
DispatchQueue.main.async {
|
||||
keyText = key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsKeyItemLink_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsKeyItemLink(
|
||||
type: .deviceKey,
|
||||
footnote: "Some text describing the purpose of the key.")
|
||||
.environmentObject(KeyManagement())
|
||||
}
|
||||
}
|
31
Sesame-Watch Watch App/Settings/SettingsListTextItem.swift
Normal file
31
Sesame-Watch Watch App/Settings/SettingsListTextItem.swift
Normal file
@ -0,0 +1,31 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsListTextItem: View {
|
||||
|
||||
let title: String
|
||||
|
||||
let value: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text(title)
|
||||
.foregroundColor(.primary)
|
||||
Spacer()
|
||||
}
|
||||
Text(value)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
.lineLimit(1)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsListTextItem_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsListTextItem(
|
||||
title: "Title",
|
||||
value: "Some longer text")
|
||||
}
|
||||
}
|
28
Sesame-Watch Watch App/Settings/SettingsListToggleItem.swift
Normal file
28
Sesame-Watch Watch App/Settings/SettingsListToggleItem.swift
Normal file
@ -0,0 +1,28 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsListToggleItem: View {
|
||||
|
||||
let title: String
|
||||
|
||||
@Binding
|
||||
var value: Bool
|
||||
|
||||
let subtitle: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(title, isOn: $value)
|
||||
Text(subtitle)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.padding()
|
||||
.cornerRadius(8)
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsListToggleItem_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsListToggleItem(title: "Toggle", value: .constant(true), subtitle: "Some longer text explaining what the toggle does")
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsNumberInputView: View {
|
||||
|
||||
let title: String
|
||||
|
||||
@Binding
|
||||
var value: Int
|
||||
|
||||
@State
|
||||
private var text: String = ""
|
||||
|
||||
let footnote: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
TextField(title, text: $text)
|
||||
.onSubmit {
|
||||
guard let newValue = Int(text) else {
|
||||
return
|
||||
}
|
||||
value = newValue
|
||||
}
|
||||
.foregroundColor(.accentColor)
|
||||
Text(footnote)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
}
|
||||
.navigationTitle(title)
|
||||
.navigationBarBackButtonHidden(false)
|
||||
.onAppear {
|
||||
text = "\(value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsNumberInputView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsNumberInputView(
|
||||
title: "Title",
|
||||
value: .constant(0),
|
||||
footnote: "Some more text explaining the purpose of the text field.")
|
||||
}
|
||||
}
|
30
Sesame-Watch Watch App/Settings/SettingsNumberItemLink.swift
Normal file
30
Sesame-Watch Watch App/Settings/SettingsNumberItemLink.swift
Normal file
@ -0,0 +1,30 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsNumberItemLink: View {
|
||||
|
||||
let title: String
|
||||
|
||||
@Binding
|
||||
var value: Int
|
||||
|
||||
let footnote: String
|
||||
|
||||
var body: some View {
|
||||
NavigationLink {
|
||||
SettingsNumberInputView(
|
||||
title: title,
|
||||
value: $value,
|
||||
footnote: footnote
|
||||
)
|
||||
} label: {
|
||||
SettingsListTextItem(title: title, value: "\(value)")
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsNumberItemLink_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsNumberItemLink(title: "Title", value: .constant(0), footnote: "Some more text explaining the purpose of the text field.")
|
||||
}
|
||||
}
|
33
Sesame-Watch Watch App/Settings/SettingsTextInputView.swift
Normal file
33
Sesame-Watch Watch App/Settings/SettingsTextInputView.swift
Normal file
@ -0,0 +1,33 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsTextInputView: View {
|
||||
|
||||
let title: String
|
||||
|
||||
@Binding
|
||||
var text: String
|
||||
|
||||
let footnote: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
TextField(title, text: $text)
|
||||
.foregroundColor(.accentColor)
|
||||
Text(footnote)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
}
|
||||
.navigationTitle(title)
|
||||
.navigationBarBackButtonHidden(false)
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsTextInputView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsTextInputView(
|
||||
title: "Title",
|
||||
text: .constant("Text"),
|
||||
footnote: "Some more text explaining the purpose of the text field.")
|
||||
}
|
||||
}
|
30
Sesame-Watch Watch App/Settings/SettingsTextItemLink.swift
Normal file
30
Sesame-Watch Watch App/Settings/SettingsTextItemLink.swift
Normal file
@ -0,0 +1,30 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsTextItemLink: View {
|
||||
|
||||
let title: String
|
||||
|
||||
@Binding
|
||||
var value: String
|
||||
|
||||
let footnote: String
|
||||
|
||||
var body: some View {
|
||||
NavigationLink {
|
||||
SettingsTextInputView(
|
||||
title: title,
|
||||
text: $value,
|
||||
footnote: footnote
|
||||
)
|
||||
} label: {
|
||||
SettingsListTextItem(title: title, value: value)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
}
|
||||
|
||||
struct SettingsTextItemLink_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsTextItemLink(title: "Title", value: .constant("Some value"), footnote: "Some more text explaining the purpose of the text field.")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user