summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceView.swift
blob: 5f7723fdd81a0a79e6eacc42c8016c17cfbc2fb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//
//  RevokedDeviceView.swift
//  MullvadVPN
//
//  Created by Jon Petersson on 2025-10-02.
//  Copyright © 2025 Mullvad VPN AB. All rights reserved.
//

import SwiftUI

struct RevokedDeviceView: View {
    @StateObject var viewModel: RevokedDeviceViewModel
    var onLogout: (() -> Void)?

    var body: some View {
        VStack(spacing: 0) {
            ScrollView {
                VStack(alignment: .leading, spacing: 0) {
                    HStack {
                        Spacer()
                        Image.mullvadIconFail
                        Spacer()
                    }

                    Text("Device is inactive")
                        .font(.mullvadLarge)
                        .foregroundStyle(Color.MullvadText.onBackgroundEmphasis100)
                        .padding(.top, 16)

                    Text("You have removed this device. To connect again, you will need to log back in.")
                        .font(.mullvadSmall)
                        .foregroundStyle(Color.MullvadText.onBackground)
                        .padding(.top, 8)

                    Text("Going to login will unblock the Internet on this device.")
                        .font(.mullvadSmall)
                        .foregroundStyle(Color.MullvadText.onBackground)
                        .padding(.top, 16)
                        .showIf(viewModel.tunnelState.isSecured)
                }
                .padding(.top, 24)
            }
            .apply {
                if #available(iOS 16.4, *) {
                    $0.scrollBounceBehavior(.automatic)
                } else {
                    $0
                }
            }

            MainButton(text: "Go to login", style: viewModel.tunnelState.isSecured ? .danger : .default) {
                onLogout?()
            }
            .accessibilityIdentifier(.revokedDeviceLoginButton)
        }
        .padding(.horizontal, 16)
        .padding(.bottom, 16)
        .background(Color.mullvadBackground)
    }
}

#Preview("Secured") {
    RevokedDeviceView(
        viewModel: RevokedDeviceViewModel(
            interactor: MockRevokedDeviceInteractor(
                tunnelStatus: TunnelStatus(
                    observedState: .error(.init(reason: .deviceRevoked)),
                    state: .error(.deviceRevoked)
                )
            )
        )
    )
}

#Preview("Not secured") {
    RevokedDeviceView(
        viewModel: RevokedDeviceViewModel(
            interactor: MockRevokedDeviceInteractor(
                tunnelStatus: TunnelStatus(
                    observedState: .disconnected,
                    state: .disconnected
                )
            )
        )
    )
}