feat(ios): polish onboarding and native sign-in flow (#15217)
## Summary - Reworks the iOS onboarding, native sign-in, and paywall flow so first-install and cold-start entry stay native, adaptive, and aligned with the current login/subscription gates. - Removes onboarding swipe paging, refines onboarding/paywall layout behavior, and keeps AI/paywall entry behavior consistent for logged-in and subscribed users. - Adds the new mobile all-docs empty states with localized copy and dialog entry points, and closes the remaining review follow-ups by removing the onboarding plan artifact and dropping the iOS AI subscription bypass. ## Test plan - Built the iOS app for simulator with `xcodebuild -workspace App.xcworkspace -scheme App -configuration Debug -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' ARCHS=arm64 ONLY_ACTIVE_ARCH=YES CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` during the native onboarding/sign-in flow work. - Let the repo pre-commit hooks run on the latest follow-up commit (`prettier` + `eslint --fix`). - Checked diagnostics for the edited TS/TSX files after the review follow-up changes. - Manually iterated on onboarding/native sign-in/paywall UI states in simulator during implementation. --------- Co-authored-by: DarkSky <darksky2048@gmail.com>
This commit is contained in:
@@ -177,6 +177,7 @@ private extension ChatManager {
|
||||
timeoutInterval: 10
|
||||
)
|
||||
request.setValue("close", forHTTPHeaderField: "Connection")
|
||||
request = QLService.shared.authorized(request)
|
||||
|
||||
let closable = ClosableTask(detachedTask: .detached(operation: {
|
||||
let eventSource = EventSource()
|
||||
|
||||
@@ -70,7 +70,10 @@ public class IntelligentContext {
|
||||
|
||||
private init() {}
|
||||
|
||||
public func preparePresent(_ completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
public func preparePresent(
|
||||
createSession shouldCreateSession: Bool = true,
|
||||
_ completion: @escaping (Result<Void, Error>) -> Void
|
||||
) {
|
||||
assert(webView != nil)
|
||||
DispatchQueue.global(qos: .userInitiated).async { [self] in
|
||||
prepareTemporaryDirectory()
|
||||
@@ -130,6 +133,10 @@ public class IntelligentContext {
|
||||
let currentDocumentId: String? = webViewMetadata[.currentDocId] as? String
|
||||
|
||||
dumpMetadataContents()
|
||||
guard shouldCreateSession else {
|
||||
completion(.success(()))
|
||||
return
|
||||
}
|
||||
|
||||
createSession(
|
||||
workspaceId: workspaceId,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Apollo
|
||||
import AffineGraphQL
|
||||
import Foundation
|
||||
|
||||
extension QLService {
|
||||
@@ -17,5 +18,36 @@ extension QLService {
|
||||
self.session.configuration.httpCookieStorage?.setCookie(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
override func sendRequest(
|
||||
_ request: URLRequest,
|
||||
taskDescription: String?,
|
||||
rawTaskCompletionHandler: RawCompletion?,
|
||||
completion: @escaping Completion
|
||||
) -> URLSessionTask {
|
||||
super.sendRequest(
|
||||
QLService.shared.authorized(request),
|
||||
taskDescription: taskDescription,
|
||||
rawTaskCompletionHandler: rawTaskCompletionHandler,
|
||||
completion: completion
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension QLService {
|
||||
func authorized(_ request: URLRequest) -> URLRequest {
|
||||
guard request.value(forHTTPHeaderField: "Authorization") == nil,
|
||||
let requestURL = request.url,
|
||||
let token = AuthAccessTokenCache.shared.token(
|
||||
for: requestURL, matching: serverBaseURL)
|
||||
else {
|
||||
return request
|
||||
}
|
||||
|
||||
var authorized = request
|
||||
authorized.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
|
||||
return authorized
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user