diff --git a/Mlem/Views/Shared/Accounts/Accounts Page.swift b/Mlem/Views/Shared/Accounts/Accounts Page.swift index 5b27a50ac..68686bf92 100644 --- a/Mlem/Views/Shared/Accounts/Accounts Page.swift +++ b/Mlem/Views/Shared/Accounts/Accounts Page.swift @@ -36,6 +36,7 @@ struct AccountsPage: View { dismiss() setFlow(using: account) } + .disabled(isActiveAccount(account)) .swipeActions { Button("Remove", role: .destructive) { dismiss() @@ -93,6 +94,11 @@ struct AccountsPage: View { return account == currentAccount ? .secondary : .primary } + private func isActiveAccount(_ account: SavedAccount) -> Bool { + guard let currentAccount = appState.currentActiveAccount else { return false } + return account == currentAccount + } + private func setFlow(using account: SavedAccount?) { // this tiny delay prevents the modal dismiss animation from being cancelled DispatchQueue.main.asyncAfter(deadline: .now() + 0.03) { diff --git a/Mlem/Window.swift b/Mlem/Window.swift index dbf3461ff..3c67437f4 100644 --- a/Mlem/Window.swift +++ b/Mlem/Window.swift @@ -74,6 +74,61 @@ struct Window: View { } private func setFlow(_ flow: AppFlow) { - self.flow = flow + transition(flow) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + self.flow = flow + } + } + + /// This method changes the current application flow and places a _transition_ view across the active window while + /// - Parameter newFlow: The `AppFlow` that the application should transition into + private func transition(_ newFlow: AppFlow) { + struct TransitionView: View { + let text: String + + var body: some View { + VStack(spacing: 24) { + ProgressView() + .controlSize(.large) + Text(text) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + } + + let transitionText: String + switch newFlow { + case .onboarding: + transitionText = "See you soon 👋" + case let .account(account): + transitionText = "Welcome \(account.nickname) 🚀" + } + + Task { @MainActor in + + let transition = TransitionView(text: transitionText) + guard let transitionView = UIHostingController(rootView: transition).view, + let window = UIApplication.shared.firstKeyWindow else { + return + } + + transitionView.alpha = 0 + window.addSubview(transitionView) + UIView.animate(withDuration: 0.15) { + transitionView.alpha = 1 + } + + transitionView.translatesAutoresizingMaskIntoConstraints = false + transitionView.heightAnchor.constraint(equalTo: window.heightAnchor).isActive = true + transitionView.widthAnchor.constraint(equalTo: window.widthAnchor).isActive = true + + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + UIView.animate(withDuration: 0.3) { + transitionView.alpha = 0 + } completion: { _ in + transitionView.removeFromSuperview() + } + } + } } }