Add copying
This commit is contained in:
parent
b006293896
commit
643452459b
|
@ -11,8 +11,9 @@ import OTPKit
|
||||||
struct KeyView: View {
|
struct KeyView: View {
|
||||||
let key: TOTPKey
|
let key: TOTPKey
|
||||||
let currentCode: TOTPCode
|
let currentCode: TOTPCode
|
||||||
|
@State private var copying = false
|
||||||
|
|
||||||
var formattedCode: String {
|
private var formattedCode: String {
|
||||||
let code = currentCode.code
|
let code = currentCode.code
|
||||||
let mid = code.index(code.startIndex, offsetBy: code.count / 2)
|
let mid = code.index(code.startIndex, offsetBy: code.count / 2)
|
||||||
return "\(code[code.startIndex..<mid]) \(code[mid...])"
|
return "\(code[code.startIndex..<mid]) \(code[mid...])"
|
||||||
|
@ -24,37 +25,47 @@ struct KeyView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
Button(action: self.copy) {
|
||||||
VStack(alignment: .leading) {
|
HStack {
|
||||||
Text(key.issuer)
|
VStack(alignment: .leading) {
|
||||||
.font(.title3)
|
Text(key.issuer)
|
||||||
|
.font(.title3)
|
||||||
|
|
||||||
if let label = key.label, !label.isEmpty {
|
if let label = key.label, !label.isEmpty {
|
||||||
Text(label)
|
Text(label)
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
|
||||||
|
if copying {
|
||||||
|
Text("Copied!")
|
||||||
|
.font(.title2)
|
||||||
|
.transition(.move(edge: .trailing).combined(with: .opacity))
|
||||||
|
} else {
|
||||||
|
Text(formattedCode)
|
||||||
|
.font(.system(.title2, design: .monospaced))
|
||||||
|
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)).combined(with: .opacity))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text("\(currentCode.validUntil, style: .relative)")
|
||||||
|
// .font(.body.monospacedDigit())
|
||||||
|
|
||||||
|
// I don't think this TimelineView should be necessary since the CodeHolder timer fires every .5 seconds
|
||||||
|
TimelineView(.animation) { (ctx) in
|
||||||
|
ZStack {
|
||||||
|
CircularProgressView(progress: progress(at: Date()), colorChangeThreshold: 5.0 / Double(key.period))
|
||||||
|
|
||||||
|
Text(Int(round(currentCode.validUntil.timeIntervalSinceNow)).description)
|
||||||
|
.font(.caption.monospacedDigit())
|
||||||
|
}
|
||||||
|
.frame(width: 30)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Text(formattedCode)
|
|
||||||
.font(.system(.title2, design: .monospaced))
|
|
||||||
|
|
||||||
// Text("\(currentCode.validUntil, style: .relative)")
|
|
||||||
// .font(.body.monospacedDigit())
|
|
||||||
|
|
||||||
// I don't think this TimelineView should be necessary since the CodeHolder timer fires every .5 seconds
|
|
||||||
TimelineView(.animation) { (ctx) in
|
|
||||||
ZStack {
|
|
||||||
CircularProgressView(progress: progress(at: Date()), colorChangeThreshold: 5.0 / Double(key.period))
|
|
||||||
|
|
||||||
Text(Int(round(currentCode.validUntil.timeIntervalSinceNow)).description)
|
|
||||||
.font(.caption.monospacedDigit())
|
|
||||||
}
|
|
||||||
.frame(width: 30)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.tint(.black)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func progress(at date: Date) -> Double {
|
private func progress(at date: Date) -> Double {
|
||||||
|
@ -62,6 +73,16 @@ struct KeyView: View {
|
||||||
let progress = 1 - seconds / Double(key.period)
|
let progress = 1 - seconds / Double(key.period)
|
||||||
return progress
|
return progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func copy() {
|
||||||
|
UIPasteboard.general.string = currentCode.code
|
||||||
|
withAnimation(.easeInOut(duration: 0.5)) {
|
||||||
|
copying = true
|
||||||
|
}
|
||||||
|
withAnimation(.easeInOut(duration: 0.5).delay(0.65)) {
|
||||||
|
copying = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KeyView_Previews: PreviewProvider {
|
struct KeyView_Previews: PreviewProvider {
|
||||||
|
|
Loading…
Reference in New Issue