import SwiftUI /// Helper class for making our SwiftUI view available to ObjectiveC @objcMembers class WelcomeExperienceViewController: NSObject { class func makeViewController(completion: (() -> Void)?) -> UIViewController { let welcomeExperienceView = WelcomeExperienceView(completion: completion) return UIHostingController(rootView: welcomeExperienceView) } } struct WelcomeExperienceView: View { @State var completion: (() -> Void)? var body: some View { TabView { Page(image: "welcome_experience_1", title: BWIL10n.welcomeExperienceTitle1, description: BWIL10n.welcomeExperienceDescription1) Page(image: "welcome_experience_2", title: BWIL10n.welcomeExperienceTitle2, description: BWIL10n.welcomeExperienceDescription2) Page(image: "welcome_experience_3", title: BWIL10n.welcomeExperienceTitle3, description: BWIL10n.welcomeExperienceDescription3) Page(image: "welcome_experience_4", title: BWIL10n.welcomeExperienceTitle4, description: BWIL10n.welcomeExperienceDescription4) Page(image: "welcome_experience_5", title: BWIL10n.welcomeExperienceTitle5, description: BWIL10n.welcomeExperienceDescription5, doneButton: BWIL10n.welcomeExperienceStart, buttonCallback: completion) } .tabViewStyle(.page) .indexViewStyle(.page(backgroundDisplayMode: .always)) .background(Color.white.ignoresSafeArea()) } } fileprivate struct Page: View { var image: String var title: String var description: String var doneButton: String? @State var buttonCallback: (() -> Void)? private let service = ServerDowntimeDefaultService() @State private var isFetchingDowntime = false @State private var showAlert = false @State private var activeAlert: ServerMaintenanceAlertType = .showInvalidAppVersionAlert var body: some View { GeometryReader { geometry in VStack(alignment: .center, spacing: 40) { Image(image) .resizable() .aspectRatio(contentMode: .fit) .frame(width: geometry.size.height * 0.25) Text(title) .foregroundColor(.black) .font(.largeTitle.weight(.bold)) .multilineTextAlignment(.center) Text(description) .foregroundColor(.black) .font(.body) .multilineTextAlignment(.center) Spacer() // bwi #3811: check for maintenance when the server selection is skipped if let doneButton = doneButton, let buttonCallback = buttonCallback { Button(action: startButtonAction) { Text(doneButton) .foregroundColor(.white) .padding(.vertical, 10) .padding(.horizontal, 50) .background(Color(ThemeService.shared().theme.tintColor)) .clipShape(RoundedRectangle(cornerRadius: 10)) } .padding(.bottom, 100) .alert(isPresented: $showAlert, content: { service.alert(alertType: activeAlert) { buttonCallback() } }) } } .padding(.top, 100) .padding(.horizontal, 20) .frame(maxWidth: .infinity, maxHeight: .infinity) } } private func startButtonAction() { guard let buttonCallback = buttonCallback else { return } if BWIBuildSettings.shared.enableMaintenanceInfoOnLogin && BWIBuildSettings.shared.avoidServerSelectionOnAppConfig && AppConfigService.shared.isAppConfig { isFetchingDowntime = true // show progresview if BWIBuildSettings.shared.useTestDataForDowntime { service.fetchDowntimes { self.isFetchingDowntime = false // hide progressview self.showAlertIfNeeded() } } else { service.fetchDowntimesWithDirectRequest { success in DispatchQueue.main.async { self.isFetchingDowntime = false // hide progressview if success { self.showAlertIfNeeded() } else { } } } } } else { buttonCallback() } } private func showAlertIfNeeded() { guard let buttonCallback = buttonCallback else { return } if service.showAlert() { activeAlert = service.alertType() showAlert = true } else { buttonCallback() } } } struct WelcomeExperienceView_Previews: PreviewProvider { static var previews: some View { WelcomeExperienceView() } }