Skip to content

Commit

Permalink
Updated TokenTab (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldavidw authored Jun 15, 2024
1 parent c8f8ac9 commit a5c1bfd
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 57 deletions.
89 changes: 39 additions & 50 deletions Chronos/App/Tabs/Tokens/Row/TokenRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,6 @@ import AlertKit
import Factory
import SwiftUI

@Observable
class TokenRowViewModel {
var encryptedToken: EncryptedToken
var token: Token?
let cryptoService = Container.shared.cryptoService()

init(encyptedToken: EncryptedToken) {
encryptedToken = encyptedToken
decryptToken()
}

private func decryptToken() {
token = cryptoService.decryptToken(encryptedToken: encryptedToken)
}
}

struct TokenRowView: View {
@Environment(\.modelContext) private var modelContext

Expand All @@ -27,51 +11,56 @@ struct TokenRowView: View {
@State private var selectedTokenForDeletion: Token?
@State private var selectedTokenForUpdate: Token?

let tokenRowViewModel: TokenRowViewModel
let tokenPair: TokenPair

var token: Token {
return tokenPair.token
}

var encryptedToken: EncryptedToken {
return tokenPair.encToken
}

let otpService = Container.shared.otpService()

var body: some View {
VStack(alignment: .leading, spacing: 8) {
if let token = tokenRowViewModel.token {
HStack(spacing: 4) {
Text(!token.issuer.isEmpty ? token.issuer : token.account)
.fontWeight(.semibold)
HStack(spacing: 4) {
Text(!token.issuer.isEmpty ? token.issuer : token.account)
.fontWeight(.semibold)

if !token.issuer.isEmpty && !token.account.isEmpty {
Text("- \(token.account)")
.foregroundStyle(.gray)
}
if !token.issuer.isEmpty && !token.account.isEmpty {
Text("- \(token.account)")
.foregroundStyle(.gray)
}
}

HStack {
switch token.type {
case TokenTypeEnum.TOTP:
TOTPRowView(token: token)
case TokenTypeEnum.HOTP:
HOTPRowView(token: token, encryptedToken: tokenRowViewModel.encryptedToken)
}
HStack {
switch token.type {
case TokenTypeEnum.TOTP:
TOTPRowView(token: token)
case TokenTypeEnum.HOTP:
HOTPRowView(token: token, encryptedToken: encryptedToken)
}
}
}
.contentShape(Rectangle())
.padding(CGFloat(4))
.listRowBackground(Color(red: 0.04, green: 0, blue: 0.11))
.onTapGesture {
if let token = tokenRowViewModel.token {
switch token.type {
case TokenTypeEnum.TOTP:
UIPasteboard.general.string = otpService.generateTOTP(token: token)
case TokenTypeEnum.HOTP:
UIPasteboard.general.string = otpService.generateHOTP(token: token)
}

AlertKitAPI.present(
title: "Copied",
icon: .done,
style: .iOS17AppleMusic,
haptic: .success
)
switch token.type {
case TokenTypeEnum.TOTP:
UIPasteboard.general.string = otpService.generateTOTP(token: token)
case TokenTypeEnum.HOTP:
UIPasteboard.general.string = otpService.generateHOTP(token: token)
}

AlertKitAPI.present(
title: "Copied",
icon: .done,
style: .iOS17AppleMusic,
haptic: .success
)
}
.swipeActions(edge: .leading) {
TokenRowLeftToRightSwipeView()
Expand All @@ -81,14 +70,14 @@ struct TokenRowView: View {
}
.sheet(item: $selectedTokenForUpdate) { tokenToUpdate in
NavigationView {
UpdateTokenView(token: tokenToUpdate, encryptedToken: tokenRowViewModel.encryptedToken)
UpdateTokenView(token: tokenToUpdate, encryptedToken: encryptedToken)
.interactiveDismissDisabled(true)
}
}
.confirmationDialog("Delete?", isPresented: $showTokenDeleteSheet, titleVisibility: .visible) {
Button("Delete", role: .destructive, action: {
do {
modelContext.delete(tokenRowViewModel.encryptedToken)
modelContext.delete(encryptedToken)
try modelContext.save()
} catch {
print(error.localizedDescription)
Expand All @@ -109,7 +98,7 @@ struct TokenRowView: View {
func TokenRowLeftToRightSwipeView() -> some View {
return Group {
Button {
self.selectedTokenForDeletion = tokenRowViewModel.token
self.selectedTokenForDeletion = token
self.showTokenDeleteSheet.toggle()
} label: {
VStack(alignment: .center) {
Expand All @@ -124,7 +113,7 @@ struct TokenRowView: View {
func TokenRowRightToLeftSwipeView() -> some View {
return Group {
Button {
self.selectedTokenForUpdate = tokenRowViewModel.token
self.selectedTokenForUpdate = token
self.showTokenUpdateSheet.toggle()
} label: {
VStack(alignment: .center) {
Expand Down
28 changes: 21 additions & 7 deletions Chronos/App/Tabs/Tokens/TokensTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ import Factory
import SwiftData
import SwiftUI

struct TokenPair: Identifiable {
var id: ObjectIdentifier

var token: Token
var encToken: EncryptedToken
}

struct TokensTab: View {
@Query(sort: \EncryptedToken.createdAt) private var encyptedTokens: [EncryptedToken]
@Query(sort: \EncryptedToken.createdAt) private var encryptedTokens: [EncryptedToken]

@State private var showTokenAddSheet = false
@State private var showTokenUpdateSheet = false
Expand All @@ -13,20 +20,27 @@ struct TokensTab: View {
@State private var selectedTokenForUpdate: Token? = nil
@State var detentHeight: CGFloat = 0

let cryptoService = Container.shared.cryptoService()
let stateService = Container.shared.stateService()

private var filteredEncyptedTokens: [EncryptedToken] {
return encyptedTokens.compactMap { encToken in
encToken.vault?.vaultId == stateService.getVaultId() ? encToken : nil
}
private var tokenPairs: [TokenPair] {
let vaultId = stateService.getVaultId()

return encryptedTokens.filter { $0.vault?.vaultId == vaultId }
.compactMap { encToken in
guard let decryptedToken = cryptoService.decryptToken(encryptedToken: encToken) else {
return nil
}
return TokenPair(id: encToken.id, token: decryptedToken, encToken: encToken)
}
}

var body: some View {
ZStack {
NavigationStack {
ScrollViewReader { _ in
List(filteredEncyptedTokens) { encyptedToken in
TokenRowView(tokenRowViewModel: TokenRowViewModel(encyptedToken: encyptedToken))
List(tokenPairs) { tokenPair in
TokenRowView(tokenPair: tokenPair)
}
.listStyle(.plain)
}
Expand Down

0 comments on commit a5c1bfd

Please sign in to comment.