Fix key copying animation
This commit is contained in:
parent
13d4ce0ab7
commit
94c39fb5c5
|
@ -12,6 +12,7 @@ struct KeyView: View {
|
|||
let key: TOTPKey
|
||||
let currentCode: TOTPCode
|
||||
@State private var copying = false
|
||||
@State private var copiedLabelWidth: CGFloat = 0
|
||||
|
||||
private var formattedCode: String {
|
||||
let code = currentCode.code
|
||||
|
@ -27,36 +28,48 @@ struct KeyView: View {
|
|||
var body: some View {
|
||||
Button(action: self.copy) {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Text(key.issuer)
|
||||
.font(.title3)
|
||||
ZStack {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Text(key.issuer)
|
||||
.font(.title3)
|
||||
|
||||
if let label = key.label, !label.isEmpty {
|
||||
Text(label)
|
||||
.font(.footnote)
|
||||
if let label = key.label, !label.isEmpty {
|
||||
Text(label)
|
||||
.font(.footnote)
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
Text(formattedCode)
|
||||
.font(.system(.title2, design: .monospaced))
|
||||
.opacity(copying ? 0 : 1)
|
||||
|
||||
Text("Copied!")
|
||||
.font(.title2)
|
||||
.opacity(copying ? 1 : 0)
|
||||
// this nonsense shouldn't be necessary, but the transition only works the first time a code is copied, for some indiscernible reason
|
||||
.background(GeometryReader { proxy in
|
||||
Color.clear
|
||||
.preference(key: CopiedLabelWidth.self, value: proxy.size.width)
|
||||
.onPreferenceChange(CopiedLabelWidth.self) { newValue in
|
||||
copiedLabelWidth = newValue
|
||||
}
|
||||
})
|
||||
}
|
||||
.offset(x: copying ? 0 : copiedLabelWidth)
|
||||
.clipped()
|
||||
}
|
||||
|
||||
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())
|
||||
.padding(.trailing, 8)
|
||||
|
||||
// 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))
|
||||
CircularProgressView(progress: progress(at: ctx.date), colorChangeThreshold: 5.0 / Double(key.period))
|
||||
|
||||
Text(Int(round(currentCode.validUntil.timeIntervalSinceNow)).description)
|
||||
.font(.caption.monospacedDigit())
|
||||
|
@ -79,12 +92,22 @@ struct KeyView: View {
|
|||
withAnimation(.easeInOut(duration: 0.5)) {
|
||||
copying = true
|
||||
}
|
||||
withAnimation(.easeInOut(duration: 0.5).delay(0.65)) {
|
||||
copying = false
|
||||
// .easeInOut(duration: 0.5).delay(0.65) does not work any more
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(650)) {
|
||||
withAnimation(.easeInOut(duration: 0.5)) {
|
||||
copying = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct CopiedLabelWidth: PreferenceKey {
|
||||
static var defaultValue: CGFloat = 0
|
||||
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
||||
value = nextValue()
|
||||
}
|
||||
}
|
||||
|
||||
struct KeyView_Previews: PreviewProvider {
|
||||
static var key: TOTPKey {
|
||||
TOTPKey(urlComponents: URLComponents(string: "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example")!)!
|
||||
|
|
Loading…
Reference in New Issue