Merge pull request #653 from omnivore-app/fix/web-reader-deep-link-ui

Use nav link to present deep link
This commit is contained in:
Satindar Dhillon 2022-05-18 13:23:09 -07:00 committed by GitHub
commit a6bdf119a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 51 additions and 68 deletions

View file

@ -22,7 +22,7 @@ public extension PlatformViewController {
final class ShareExtensionViewModel: ObservableObject {
@Published var title: String?
@Published var status = ShareExtensionStatus.processing
@Published var status: ShareExtensionStatus = FeatureFlag.enableReadNow ? .processing : .success
@Published var debugText: String?
var subscriptions = Set<AnyCancellable>()

View file

@ -18,7 +18,16 @@ private let enableGrid = UIDevice.isIPad || FeatureFlag.enableGridCardsOnPhone
}
var body: some View {
Group {
ZStack {
if let linkRequest = viewModel.linkRequest {
NavigationLink(
destination: WebReaderLoadingContainer(requestID: linkRequest.serverID),
tag: linkRequest,
selection: $viewModel.linkRequest
) {
EmptyView()
}
}
HomeFeedView(
prefersListLayout: $prefersListLayout,
viewModel: viewModel
@ -86,7 +95,7 @@ private let enableGrid = UIDevice.isIPad || FeatureFlag.enableGridCardsOnPhone
.navigationBarTitleDisplayMode(.inline)
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
// Don't refresh the list if the user is currently reading an article
if viewModel.selectedLinkItem == nil {
if viewModel.selectedLinkItem == nil || viewModel.linkRequest == nil {
loadItems(isRefresh: true)
}
}
@ -97,6 +106,16 @@ private let enableGrid = UIDevice.isIPad || FeatureFlag.enableGridCardsOnPhone
viewModel.pushFeedItem(item: linkedItem)
viewModel.selectedLinkItem = linkedItem
}
.onOpenURL { url in
withoutAnimation {
viewModel.linkRequest = nil
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
if let linkRequestID = DeepLink.make(from: url)?.linkRequestID {
viewModel.linkRequest = LinkRequest(id: UUID(), serverID: linkRequestID)
}
}
}
}
.formSheet(isPresented: $viewModel.snoozePresented) {
SnoozeView(
snoozePresented: $viewModel.snoozePresented,
@ -376,3 +395,17 @@ struct ScrollViewOffsetPreferenceKey: PreferenceKey {
value += nextValue()
}
}
#if os(iOS)
// Allows us to present a sheet without animation
// Used to configure full screen modal view coming from share extension read now button action
private extension View {
func withoutAnimation(_ completion: @escaping () -> Void) {
UIView.setAnimationsEnabled(false)
completion()
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) {
UIView.setAnimationsEnabled(true)
}
}
}
#endif

View file

@ -20,6 +20,7 @@ import Views
@Published var snoozePresented = false
@Published var itemToSnoozeID: String?
@Published var selectedLinkItem: LinkedItem?
@Published var linkRequest: LinkRequest?
@Published var showLoadingBar = false
@AppStorage(UserDefaultKey.lastSelectedLinkedItemFilter.rawValue)

View file

@ -147,7 +147,7 @@ struct LinkItemDetailView: View {
viewModel.trackReadEvent()
}
} else {
WebReaderContainerView(item: viewModel.item, isPresentedModally: false)
WebReaderContainerView(item: viewModel.item)
.navigationBarHidden(hideNavBar)
.task {
hideNavBar = true

View file

@ -4,11 +4,6 @@ import SwiftUI
import Utils
import Views
struct LinkRequest: Identifiable {
let id: UUID
let serverID: String
}
public struct RootView: View {
let pdfViewerProvider: ((URL, PDFViewerViewModel) -> AnyView)?
@StateObject private var viewModel = RootViewModel()
@ -51,17 +46,7 @@ struct InnerRootView: View {
.onAppear {
viewModel.triggerPushNotificationRequestIfNeeded()
}
#if os(iOS)
.fullScreenCover(item: $viewModel.linkRequest) { _ in
NavigationView {
WebReaderLoadingContainer(
requestID: viewModel.linkRequest?.serverID ?? "",
handleClose: { viewModel.linkRequest = nil }
)
}
}
#endif
.snackBar(isShowing: $viewModel.showSnackbar, message: viewModel.snackbarMessage)
.snackBar(isShowing: $viewModel.showSnackbar, message: viewModel.snackbarMessage)
// Schedule the dismissal every time we present the snackbar.
.onChange(of: viewModel.showSnackbar) { newValue in
if newValue {
@ -95,18 +80,6 @@ struct InnerRootView: View {
#endif
}
#if os(iOS)
.onOpenURL { url in
withoutAnimation {
if viewModel.linkRequest != nil {
viewModel.linkRequest = nil
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
Task { await viewModel.onOpenURL(url: url) }
}
} else {
Task { await viewModel.onOpenURL(url: url) }
}
}
}
.onReceive(NSNotification.operationSuccessPublisher) { notification in
if let message = notification.userInfo?["message"] as? String {
viewModel.showSnackbar = true
@ -134,17 +107,3 @@ struct InnerRootView: View {
}
#endif
}
#if os(iOS)
// Allows us to present a sheet without animation
// Used to configure full screen modal view coming from share extension read now button action
private extension View {
func withoutAnimation(_ completion: @escaping () -> Void) {
UIView.setAnimationsEnabled(false)
completion()
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) {
UIView.setAnimationsEnabled(true)
}
}
}
#endif

View file

@ -15,7 +15,6 @@ public final class RootViewModel: ObservableObject {
let services = Services()
@Published public var showPushNotificationPrimer = false
@Published var linkRequest: LinkRequest?
@Published var snackbarMessage: String?
@Published var showSnackbar = false
@ -58,12 +57,6 @@ public final class RootViewModel: ObservableObject {
)
}
@MainActor func onOpenURL(url: URL) async {
if let linkRequestID = DeepLink.make(from: url)?.linkRequestID {
linkRequest = LinkRequest(id: UUID(), serverID: linkRequestID)
}
}
func triggerPushNotificationRequestIfNeeded() {
guard FeatureFlag.enablePushNotifications else { return }

View file

@ -7,7 +7,6 @@ import WebKit
#if os(iOS)
struct WebReaderContainerView: View {
let item: LinkedItem
let isPresentedModally: Bool
@State private var showFontSizePopover = false
@State private var showLabelsModal = false
@ -67,7 +66,7 @@ import WebKit
Button(
action: { self.presentationMode.wrappedValue.dismiss() },
label: {
Image(systemName: isPresentedModally ? "xmark" : "chevron.backward")
Image(systemName: "chevron.backward")
.font(.appTitleTwo)
.foregroundColor(.appGrayTextContrast)
.padding(.horizontal)

View file

@ -77,14 +77,13 @@ import Utils
public struct WebReaderLoadingContainer: View {
let requestID: String
let handleClose: () -> Void
@EnvironmentObject var dataService: DataService
@StateObject var viewModel = WebReaderLoadingContainerViewModel()
public var body: some View {
if let item = viewModel.item {
WebReaderContainerView(item: item, isPresentedModally: true)
WebReaderContainerView(item: item)
.navigationBarHidden(true)
.navigationViewStyle(.stack)
.accentColor(.appGrayTextContrast)
@ -93,17 +92,6 @@ import Utils
Text(errorMessage)
} else {
ProgressView()
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(
action: handleClose,
label: {
Image(systemName: "xmark")
.foregroundColor(.appGrayTextContrast)
}
)
}
}
.task { await viewModel.loadItem(dataService: dataService, requestID: requestID) }
}
}

View file

@ -1,5 +1,15 @@
import Foundation
public struct LinkRequest: Identifiable, Hashable {
public let id: UUID
public let serverID: String
public init(id: UUID, serverID: String) {
self.id = id
self.serverID = serverID
}
}
public enum DeepLink {
case webAppLinkRequest(requestID: String)
}