Skip to content

Commit

Permalink
UI fixes (#67)
Browse files Browse the repository at this point in the history
* Add UI fixes

* Update waitlist view
  • Loading branch information
ardier16 authored Jun 21, 2024
1 parent 9b73dda commit 22e2749
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 79 deletions.
4 changes: 4 additions & 0 deletions Rarime.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
5659151F2BE92B1F0050795A /* AppIconManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5659151E2BE92B1F0050795A /* AppIconManager.swift */; };
565E221C2BF7B33D00171692 /* CameraPermissionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565E221B2BF7B33D00171692 /* CameraPermissionView.swift */; };
56722F202BCD62BB00300AD0 /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56722F1F2BCD62BB00300AD0 /* ProfileView.swift */; };
567ADEC42C25CF32007070A7 /* JSONDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567ADEC32C25CF32007070A7 /* JSONDocument.swift */; };
567AEC9B2BBD9B8100A20E83 /* Passport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567AEC9A2BBD9B8100A20E83 /* Passport.swift */; };
568350AC2BEA304B00B70E3D /* PassportIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568350AB2BEA304B00B70E3D /* PassportIdentifier.swift */; };
568820FA2C172C75001B729F /* ReserveTokensView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568820F92C172C75001B729F /* ReserveTokensView.swift */; };
Expand Down Expand Up @@ -265,6 +266,7 @@
5659151E2BE92B1F0050795A /* AppIconManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconManager.swift; sourceTree = "<group>"; };
565E221B2BF7B33D00171692 /* CameraPermissionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPermissionView.swift; sourceTree = "<group>"; };
56722F1F2BCD62BB00300AD0 /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = "<group>"; };
567ADEC32C25CF32007070A7 /* JSONDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONDocument.swift; sourceTree = "<group>"; };
567AEC9A2BBD9B8100A20E83 /* Passport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Passport.swift; sourceTree = "<group>"; };
568350AB2BEA304B00B70E3D /* PassportIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassportIdentifier.swift; sourceTree = "<group>"; };
568820F92C172C75001B729F /* ReserveTokensView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReserveTokensView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -611,6 +613,7 @@
CE8FEB602C1B03A70008381A /* Circtuits */,
567AEC9A2BBD9B8100A20E83 /* Passport.swift */,
5655E4272BD2C3FD00B86C5C /* Transaction.swift */,
567ADEC32C25CF32007070A7 /* JSONDocument.swift */,
CEF251392BD6E22700050507 /* User.swift */,
CE68BE3C2BD9B23D00D92EBB /* ZkProof.swift */,
CE68BE3E2BD9B4B200D92EBB /* Relayer.swift */,
Expand Down Expand Up @@ -1215,6 +1218,7 @@
CE31E54A2C11FE150039CAA5 /* ImportIdentityView.swift in Sources */,
560F0C1F2BD027EA00067054 /* WalletReceiveView.swift in Sources */,
CED314672C0483BD00DF31D5 /* MailView.swift in Sources */,
567ADEC42C25CF32007070A7 /* JSONDocument.swift in Sources */,
5655E4302BD2CA5500B86C5C /* AppColorScheme.swift in Sources */,
CED909D02BDBA9FC0065E949 /* Cosmos.swift in Sources */,
56A88FCF2C062AB200D3A64A /* AirdropCheckboxView.swift in Sources */,
Expand Down
25 changes: 25 additions & 0 deletions Rarime/Code/Models/JSONDocument.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import SwiftUI
import UniformTypeIdentifiers

class JSONDocument: FileDocument {
let json: Data

static var readableContentTypes: [UTType] = [.json]

init(_ json: Data) {
self.json = json
}

required init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
self.json = data
return
}

self.json = Data()
}

func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: json)
}
}
12 changes: 8 additions & 4 deletions Rarime/Code/Modules/Home/Views/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@ struct HomeView: View {
&& userManager.registerZkProof != nil
}

var isWalletBalanceDisplayed: Bool {
passportManager.passport != nil && passportManager.isUnsupportedForRewards
}

var displayedBalance: Double {
passportManager.isUnsupportedForRewards
isWalletBalanceDisplayed
? userManager.balance / Double(Rarimo.rarimoTokenMantis)
: Double(pointsBalance?.amount ?? 0)
}
Expand Down Expand Up @@ -159,10 +163,10 @@ struct HomeView: View {
private var header: some View {
VStack(alignment: .leading, spacing: 8) {
Button(action: {
mainViewModel.selectTab(passportManager.isUnsupportedForRewards ? .wallet : .rewards)
mainViewModel.selectTab(isWalletBalanceDisplayed ? .wallet : .rewards)
}) {
HStack(spacing: 4) {
Text(passportManager.isUnsupportedForRewards ? "Balance: RMO" : "Reserved RMO").body3()
Text(isWalletBalanceDisplayed ? "Balance: RMO" : "Reserved RMO").body3()
Image(Icons.caretRight).iconSmall()
}
}
Expand Down Expand Up @@ -266,7 +270,7 @@ struct HomeView: View {
}

do {
if passportManager.isUnsupportedForRewards {
if isWalletBalanceDisplayed {
let balance = try await userManager.fetchBalanse()
userManager.balance = Double(balance) ?? 0
return
Expand Down
16 changes: 13 additions & 3 deletions Rarime/Code/Modules/Rewards/Views/InviteFriendsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct InviteFriendsView: View {
VStack(alignment: .leading, spacing: 20) {
VStack(alignment: .leading, spacing: 4) {
if let codes = balance.referralCodes {
Text("Invited \(codes.filter { $0.status == .rewarded }.count)/\(codes.count)")
Text("Invited \(codes.filter { $0.status != .active }.count)/\(codes.count)")
.subtitle3()
.foregroundStyle(.textPrimary)
}
Expand Down Expand Up @@ -79,6 +79,16 @@ private struct InviteCodeView: View {
ConfigManager.shared.api.referralURL.appendingPathComponent("\(code)").absoluteString
}

var usedStatusText: String {
switch status {
case .awaiting: String(localized: "Scan your passport")
case .rewarded: String(localized: "Passport scanned")
case .banned: String(localized: "Unsupported country")
case .limited: String(localized: "Rewards limit reached")
default: String(localized: "Need passport scan")
}
}

var body: some View {
if status == .active {
HStack {
Expand All @@ -89,7 +99,7 @@ private struct InviteCodeView: View {
Text(invitationLink.dropFirst(8))
.body3()
.foregroundStyle(.textSecondary)
Text(status.rawValue.uppercased())
Text("Active")
.body4()
.foregroundStyle(.successDark)
}
Expand Down Expand Up @@ -117,7 +127,7 @@ private struct InviteCodeView: View {
Circle()
.fill(.componentHovered)
.frame(width: 4)
Text(status == .rewarded ? "Passport scanned" : "Need passport scan")
Text(usedStatusText)
.body4()
}
.foregroundStyle(.textSecondary)
Expand Down
77 changes: 38 additions & 39 deletions Rarime/Code/Modules/ScanPassport/Views/PassportProofView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ struct PassportProofView: View {
let onFinish: (ZkProof) -> Void
let onClose: () -> Void
let onError: () -> Void

@State private var downloadingMessage = ""

private func register() async {
do {
let zkProof = try await passportViewModel.register() { message in
do {
let zkProof = try await passportViewModel.register { message in
downloadingMessage = message
}

if passportViewModel.processingStatus != .success { return }

try await Task.sleep(nanoseconds: NSEC_PER_SEC)
Expand Down Expand Up @@ -170,44 +170,43 @@ private struct RevocationNFCScan: View {
@EnvironmentObject var passportViewModel: PassportViewModel

var body: some View {
ZStack {
VStack(spacing: 16) {
Spacer()
Image(Icons.swap)
.square(80)
.foregroundStyle(.textPrimary)
Text("Please scan your NFC card")
.h6()
.foregroundStyle(.textPrimary)
Text("This is required to revoke your passport")
.body3()
.foregroundStyle(.textSecondary)
.multilineTextAlignment(.center)
Spacer()
AppButton(text: "Revoke with NFC") {
NFCScanner.scanPassport(
mrzViewModel.mrzKey,
passportViewModel.revocationChallenge,
onCompletion: { result in
switch result {
case .success(let passport):
passportViewModel.revocationPassportPublisher.send(passport)
passportViewModel.isUserRevoking = false
case .failure(let error):
LoggerUtil.passport.error("failed to read passport data: \(error.localizedDescription, privacy: .public)")

passportViewModel.revocationPassportPublisher.send(completion: .failure(error))

passportViewModel.isUserRevoking = false
}
VStack(spacing: 16) {
Spacer()
Image(Icons.warning)
.iconLarge()
.frame(width: 72, height: 72)
.background(.warningLighter, in: Circle())
.foregroundStyle(.warningMain)
Text("Passport is already registered")
.h6()
.foregroundStyle(.textPrimary)
Text("Please, scan your passport one more time to revoke your previous registration")
.body3()
.foregroundStyle(.textSecondary)
.multilineTextAlignment(.center)
Spacer()
AppButton(text: "Scan passport") {
NFCScanner.scanPassport(
mrzViewModel.mrzKey,
passportViewModel.revocationChallenge,
onCompletion: { result in
switch result {
case .success(let passport):
passportViewModel.revocationPassportPublisher.send(passport)
passportViewModel.isUserRevoking = false
case .failure(let error):
LoggerUtil.passport.error("failed to read passport data: \(error.localizedDescription, privacy: .public)")

passportViewModel.revocationPassportPublisher.send(completion: .failure(error))

passportViewModel.isUserRevoking = false
}
)
}
.controlSize(.large)
}
)
}
.padding(20)
.background(.backgroundOpacity, in: RoundedRectangle(cornerRadius: 24))
.controlSize(.large)
}
.padding(20)
}
}

Expand Down
109 changes: 102 additions & 7 deletions Rarime/Code/Modules/ScanPassport/Views/WaitlistPassportView.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Identity
import MessageUI
import SwiftUI

struct WaitlistPassportView: View {
Expand All @@ -10,10 +11,16 @@ struct WaitlistPassportView: View {
let onCancel: () -> Void

@State private var isSending = false
@State private var isExporting = false
@State private var isCopied = false

var country: Country {
passportViewModel.passportCountry
}

var serializedPassport: Data {
return (try? passportViewModel.passport?.serialize()) ?? Data()
}

var body: some View {
HomeIntroLayout(
Expand Down Expand Up @@ -61,13 +68,17 @@ struct WaitlistPassportView: View {
}
}
.dynamicSheet(isPresented: $isSending, fullScreen: true) {
MailView(
subject: "Passport from: \(UIDevice.modelName)",
attachment: (try? passportViewModel.passport?.serialize()) ?? Data(),
fileName: "passport.json",
isShowing: $isSending,
result: .constant(nil)
)
if MFMailComposeViewController.canSendMail() {
MailView(
subject: "Passport from: \(UIDevice.modelName)",
attachment: (try? passportViewModel.passport?.serialize()) ?? Data(),
fileName: "passport.json",
isShowing: $isSending,
result: .constant(nil)
)
} else {
savePassportDataView
}
}
}

Expand Down Expand Up @@ -122,6 +133,90 @@ struct WaitlistPassportView: View {
}
}
}

var savePassportDataView: some View {
VStack(alignment: .leading, spacing: 32) {
VStack(spacing: 16) {
Image(Icons.identificationCard)
.iconLarge()
.frame(width: 72, height: 72)
.background(.componentPrimary, in: Circle())
.foregroundStyle(.textPrimary)
Text("Save your passport data")
.h6()
.foregroundStyle(.textPrimary)
Text("Your passport data will be saved on your device. You can share it with us to expedite the support of your passport.")
.body3()
.multilineTextAlignment(.center)
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: 320)
.foregroundStyle(.textSecondary)
HorizontalDivider()
VStack(alignment: .leading, spacing: 16) {
Text("HOW TO SHARE")
.overline2()
.foregroundStyle(.textSecondary)
Text("1. Save passport data on your device")
.body3()
.foregroundStyle(.textPrimary)
Text("2. Send the saved file to the email address below")
.body3()
.foregroundStyle(.textPrimary)
HStack(spacing: 8) {
Text(ConfigManager.shared.feedback.feedbackEmail)
.body2()
.foregroundStyle(.textPrimary)
Image(isCopied ? Icons.check : Icons.copySimple).iconMedium()
}
.onTapGesture {
if isCopied { return }
UIPasteboard.general.string = ConfigManager.shared.feedback.feedbackEmail
isCopied = true
FeedbackGenerator.shared.impact(.medium)

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
isCopied = false
}
}
.frame(maxWidth: .infinity)
.padding(.horizontal, 16)
.padding(.vertical, 14)
.background(.componentPrimary)
.foregroundStyle(.textPrimary)
.cornerRadius(8)
Text("3. When we support your country, you will be notified in the app")
.body3()
.foregroundStyle(.textPrimary)
}
.frame(maxWidth: .infinity)
}
.frame(maxWidth: .infinity)
Spacer()
AppButton(
text: "Save to files",
rightIcon: Icons.arrowRight,
action: { isExporting = true }
)
.controlSize(.large)
.fileExporter(
isPresented: $isExporting,
document: JSONDocument(serializedPassport),
contentType: .json,
defaultFilename: "passport.json"
) { result in
switch result {
case .success:
LoggerUtil.common.info("Passport data saved")
onNext()
case .failure(let error):
LoggerUtil.common.error("Failed to save passport data: \(error, privacy: .public)")
}
}
}
.padding(.top, 80)
.padding(.bottom, 20)
.padding(.horizontal, 24)
}
}

#Preview {
Expand Down
4 changes: 2 additions & 2 deletions Rarime/Code/Modules/Security/Views/LockScreenView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct LockScreenView: View {

@State private var failedAttempts = 0

@State private var banTimeEnd = AppUserDefaults.shared.banTimeEnd
@State private var banTimeEnd = AppUserDefaults.shared.banTimeEnd

var body: some View {
ZStack {
Expand Down Expand Up @@ -67,7 +67,7 @@ struct LockScreenView: View {
}

func authByFaceID() {
if securityManager.faceIdState != .enabled {
if securityManager.faceIdState != .enabled || banTimeEnd != nil {
return
}

Expand Down
Loading

0 comments on commit 22e2749

Please sign in to comment.