Something went wrong. Try again.
A slopfork of Sam Henri Gold's Twitter client, reskinned like Tweetie 2 / Twitter for iPhone circa 2012. Personal use.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135import ComposableArchitectureimport Modelsimport SwiftUIimport TwitterClientimport TwitterUIimport WebKit
package struct SignInView: View { let store: StoreOf<SignInFeature>
package init(store: StoreOf<SignInFeature>) { self.store = store }
package var body: some View { NavigationStack { SignInWebView( pageLoadingChanged: { store.send(.pageLoadingChanged($0)) }, sessionCaptured: { store.send(.sessionCaptured($0)) } ) .id(store.attempt) .ignoresSafeArea(edges: .bottom) .overlay { if let errorMessage = store.errorMessage { ContentUnavailableView { Label("Couldn't sign in", twitterIcon: .warningStroke) } description: { Text(errorMessage) } actions: { Button("Try Again") { store.send(.retryButtonTapped) } .buttonStyle(.classicProminent) } .background(.background) } else if store.isSigningIn { ProgressView("Signing in…") .padding() .glassEffect(.regular, in: .rect(cornerRadius: 20)) } } .navigationTitle("Sign in to Twitter") .navigationBarTitleDisplayMode(.inline) .toolbar { if store.isPageLoading { ToolbarItem(placement: .topBarTrailing) { ProgressView() } } } } }}
private struct SignInWebView: UIViewRepresentable { let pageLoadingChanged: (Bool) -> Void let sessionCaptured: ([String: String]) -> Void
func makeCoordinator() -> Coordinator { Coordinator(pageLoadingChanged: pageLoadingChanged, sessionCaptured: sessionCaptured) }
func makeUIView(context: Context) -> WKWebView { let configuration = WKWebViewConfiguration() configuration.websiteDataStore = .nonPersistent() let webView = WKWebView(frame: .zero, configuration: configuration) webView.navigationDelegate = context.coordinator webView.uiDelegate = context.coordinator configuration.websiteDataStore.httpCookieStore.add(context.coordinator) webView.load(URLRequest(url: URL(string: "https://x.com/i/flow/login")!)) return webView }
func updateUIView(_ webView: WKWebView, context: Context) {}
static func dismantleUIView(_ webView: WKWebView, coordinator: Coordinator) { webView.configuration.websiteDataStore.httpCookieStore.remove(coordinator) webView.stopLoading() }
@MainActor final class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate, WKHTTPCookieStoreObserver { private var didCapture = false private let pageLoadingChanged: (Bool) -> Void private let sessionCaptured: ([String: String]) -> Void
package init( pageLoadingChanged: @escaping (Bool) -> Void, sessionCaptured: @escaping ([String: String]) -> Void ) { self.pageLoadingChanged = pageLoadingChanged self.sessionCaptured = sessionCaptured }
func cookiesDidChange(in cookieStore: WKHTTPCookieStore) { // Checks `didCapture` again after the await: another change can capture while this one reads the jar. Task.immediate { guard !didCapture else { return } var jar: [String: String] = [:] for cookie in await cookieStore.allCookies() where cookie.domain.hasSuffix("x.com") { jar[cookie.name] = cookie.value } guard jar["auth_token"] != nil, jar["ct0"] != nil, jar["twid"] != nil, !didCapture else { return } didCapture = true sessionCaptured(jar) } }
func webView( _ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures ) -> WKWebView? { webView.load(navigationAction.request) return nil }
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { pageLoadingChanged(true) }
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { pageLoadingChanged(false) }
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: any Error) { pageLoadingChanged(false) }
func webView( _ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: any Error ) { // The page never started (offline, say): the spinner stops. pageLoadingChanged(false) } }}