Skip to content

Commit

Permalink
refactor navigation
Browse files Browse the repository at this point in the history
Signed-off-by: Bugen Zhao <i@bugenzhao.com>
  • Loading branch information
BugenZhao committed Sep 22, 2023
1 parent 7e6d9ff commit 27bb62f
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 146 deletions.
49 changes: 28 additions & 21 deletions app/Shared/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import BetterSafariView
import SwiftUI
import SwiftUIX

@Observable class Router {
var path = NavigationPath()
}

struct ContentView: View {
@State var router = Router()

@StateObject var viewingImage = ViewingImageModel()
@StateObject var activity = ActivityModel()
@StateObject var postReply = PostReplyModel()
Expand Down Expand Up @@ -46,33 +52,34 @@ struct ContentView: View {
TopicDetailsPlaceholderView()
}
} else {
NavigationView {
NavigationStack(path: $router.path) {
main
}
}
}
.environment(router)
#if os(iOS)
.safariView(item: $openURL.inAppURL) { url in SafariView(url: url).preferredControlAccentColor(Color("AccentColor")) }
.safariView(item: $openURL.inAppURL) { url in SafariView(url: url).preferredControlAccentColor(Color("AccentColor")) }
#endif
.onOpenURL { _ = schemes.onNavigateToURL($0) }
.overlay { ImageOverlay() }
.fullScreenCover(isPresented: $authStorage.isSigning) { LoginView() }
.onAppear { if !authStorage.signedIn { authStorage.isSigning = true } }
.sheet(isPresented: $activity.activityItems.isNotNil(), content: {
AppActivityView(activityItems: activity.activityItems ?? [])
})
.modifier(MainToastModifier())
.sheet(isPresented: $notis.showingSheet) { NotificationListNavigationView() }
.sheet(isPresented: $postReply.showEditor) { PostEditorView().environmentObject(postReply) }
.sheet(isPresented: $shortMessagePost.showEditor) { ShortMessageEditorView().environmentObject(shortMessagePost) }
.sheet(isPresented: $textSelection.text.isNotNil()) { TextSelectionView().environmentObject(textSelection) }
.environmentObject(viewingImage)
.environmentObject(activity)
.environmentObject(postReply)
.environmentObject(shortMessagePost)
.environmentObject(currentUser)
.environmentObject(textSelection)
.preferredColorScheme(prefs.colorScheme.scheme)
.onOpenURL { _ = schemes.onNavigateToURL($0) }
.overlay { ImageOverlay() }
.fullScreenCover(isPresented: $authStorage.isSigning) { LoginView() }
.onAppear { if !authStorage.signedIn { authStorage.isSigning = true } }
.sheet(isPresented: $activity.activityItems.isNotNil(), content: {
AppActivityView(activityItems: activity.activityItems ?? [])
})
.modifier(MainToastModifier())
.sheet(isPresented: $notis.showingSheet) { NotificationListNavigationView() }
.sheet(isPresented: $postReply.showEditor) { PostEditorView().environmentObject(postReply) }
.sheet(isPresented: $shortMessagePost.showEditor) { ShortMessageEditorView().environmentObject(shortMessagePost) }
.sheet(isPresented: $textSelection.text.isNotNil()) { TextSelectionView().environmentObject(textSelection) }
.environmentObject(viewingImage)
.environmentObject(activity)
.environmentObject(postReply)
.environmentObject(shortMessagePost)
.environmentObject(currentUser)
.environmentObject(textSelection)
.preferredColorScheme(prefs.colorScheme.scheme)
}
}

Expand Down
15 changes: 6 additions & 9 deletions app/Shared/Models/SchemesModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,22 +168,19 @@ struct SchemesNavigationModifier: ViewModifier {

@State var urlFromPasteboardForAlert: URL?

var navigation: some View {
let view: AnyView = switch model.navID {
@ViewBuilder
func destination(_ navID: NavigationIdentifier) -> some View {
switch navID {
case let .topicID(tid, fav):
TopicDetailsView.build(id: tid, fav: fav).eraseToAnyView()
TopicDetailsView.build(id: tid, fav: fav)
case let .forumID(forumID):
TopicListView.build(id: forumID).eraseToAnyView()
case .none:
EmptyView().eraseToAnyView()
TopicListView.build(id: forumID)
}

return NavigationLink(destination: view, isActive: $model.navID.isNotNil()) {}.hidden()
}

func body(content: Content) -> some View {
content
.background { navigation }
.navigationDestination(item: $model.navID) { self.destination($0) }
.alert(isPresented: $urlFromPasteboardForAlert.isNotNil()) {
let url = urlFromPasteboardForAlert
return Alert(title: Text("Navigate to Link from Pasteboard?"), message: Text(url?.absoluteString ?? ""), primaryButton: .default(Text("Navigate")) { if let url, model.canNavigateTo(url) { _ = model.onNavigateToURL(url) } }, secondaryButton: .cancel())
Expand Down
43 changes: 14 additions & 29 deletions app/Shared/Models/TopicDetailsActionModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,41 +77,26 @@ extension EnvironmentValues {

// MARK: TopicDetailsAction

struct TopicDetailsActionBasicNavigationView: View {
@ObservedObject var action: TopicDetailsActionModel

var body: some View {
let navTopic = Topic.with {
if let tid = action.navigateToTid { $0.id = tid }
}
let user = action.showUserProfile ?? .init()
let forum = action.navigateToForum ?? .init()
let view = action.navigateToView ?? EmptyView().eraseToAnyView()

NavigationLink(destination: TopicDetailsView.build(topic: navTopic), isActive: $action.navigateToTid.isNotNil()) {}.hidden()
NavigationLink(destination: UserProfileView.build(user: user), isActive: $action.showUserProfile.isNotNil()) {}.hidden()
NavigationLink(destination: TopicListView.build(forum: forum), isActive: $action.navigateToForum.isNotNil()) {}.hidden()
NavigationLink(destination: view, isActive: $action.navigateToView.isNotNil()) {}.hidden()

let withPidTopic = Topic.with {
if let tid = action.navigateToTidWithPidAndPage?.tid { $0.id = tid }
}
let page = action.navigateToTidWithPidAndPage?.page
let postId = PostId.with {
if let pid = action.navigateToTidWithPidAndPage?.pid { $0.pid = pid }
$0.tid = withPidTopic.id
}
NavigationLink(destination: TopicDetailsView.build(topic: withPidTopic, fromPage: page, postIdToJump: postId), isActive: $action.navigateToTidWithPidAndPage.isNotNil()) {}.hidden()
}
}

struct TopicDetailsActionModifier: ViewModifier {
@StateObject var action = TopicDetailsActionModel()

func body(content: Content) -> some View {
content
.environmentObject(action)
.background { TopicDetailsActionBasicNavigationView(action: action) }
.navigationDestination(item: $action.navigateToTid) { tid in
let navTopic = Topic.with { $0.id = tid }
TopicDetailsView.build(topic: navTopic)
}
.navigationDestination(item: $action.showUserProfile) { UserProfileView.build(user: $0) }
.navigationDestination(item: $action.navigateToForum) { TopicListView.build(forum: $0) }
.navigationDestination(isPresented: $action.navigateToView.isNotNil()) { action.navigateToView } // TODO(ng): use item
.navigationDestination(isPresented: $action.navigateToTidWithPidAndPage.isNotNil()) { // TODO(ng): use item
if let x = action.navigateToTidWithPidAndPage {
let withPidTopic = Topic.with { $0.id = x.tid }
let postId = PostId.with { $0.pid = x.pid; $0.tid = x.tid }
TopicDetailsView.build(topic: withPidTopic, fromPage: x.page, postIdToJump: postId)
}
}
}
}

Expand Down
28 changes: 7 additions & 21 deletions app/Shared/Views/PostRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,10 @@ struct PostRowView: View {
@ViewBuilder
var menuButton: some View {
#if os(iOS)
if #available(iOS 15.0, *) {
Menu(content: { menu }) {
Image(systemName: "ellipsis.circle.fill")
.symbolRenderingMode(.hierarchical)
.imageScale(.large)
}
} else {
Menu(content: { menu }) {
Image(systemName: "ellipsis")
.imageScale(.large)
}
Menu(content: { menu }) {
Image(systemName: "ellipsis.circle.fill")
.symbolRenderingMode(.hierarchical)
.imageScale(.large)
}
#endif
}
Expand Down Expand Up @@ -158,7 +151,7 @@ struct PostRowView: View {
Button(action: { textSelection.text = post.content.raw.replacingOccurrences(of: "<br/>", with: "\n") }) {
Label("Select Text", systemImage: "selection.pin.in.out")
}
if #available(iOS 15.0, *), !attachments.items.isEmpty {
if !attachments.items.isEmpty {
Button(action: { showAttachments = true }) {
Label("Attachments (\(attachments.items.count))", systemImage: "paperclip")
}
Expand Down Expand Up @@ -193,13 +186,6 @@ struct PostRowView: View {
}
}

@ViewBuilder
var navigation: some View {
if #available(iOS 15.0, *) {
NavigationLink(destination: AttachmentsView(model: attachments), isActive: $showAttachments) {}.hidden()
}
}

var body: some View {
let body = VStack(alignment: .leading, spacing: 10) {
header
Expand All @@ -215,10 +201,10 @@ struct PostRowView: View {
#if os(iOS)
.listRowBackground(action?.scrollToPid == post.id.pid ? Color.tertiarySystemBackground : nil)
#endif
.background { navigation }
.sheet(isPresented: $showAttachments) { NavigationView { AttachmentsView(model: attachments) } }
.environmentObject(attachments)

if #available(iOS 15.0, *), let model = postReply, !mock {
if let model = postReply, !mock {
body
.swipeActions(edge: pref.postRowSwipeActionLeading ? .leading : .trailing) {
Button(action: { self.doQuote(model: model) }) {
Expand Down
25 changes: 12 additions & 13 deletions app/Shared/Views/TopicDetailsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,18 +314,6 @@ struct TopicDetailsView: View {
}
}

@ViewBuilder
var navigation: some View {
let showingChain = action.showingReplyChain ?? .init()
NavigationLink(destination: PostReplyChainView(baseDataSource: dataSource, votes: votes, chain: showingChain).environmentObject(postReply), isActive: $action.showingReplyChain.isNotNil()) {}.hidden()

let authorOnlyView = TopicDetailsView.build(topic: topic, only: action.navigateToAuthorOnly ?? .init())
NavigationLink(destination: authorOnlyView, isActive: $action.navigateToAuthorOnly.isNotNil()) {}.hidden()

let localCacheView = TopicDetailsView.build(topic: topic, localMode: true)
NavigationLink(destination: localCacheView, isActive: $action.navigateToLocalMode) {}.hidden()
}

@ViewBuilder
var listMain: some View {
List {
Expand Down Expand Up @@ -457,7 +445,19 @@ struct TopicDetailsView: View {
proxy.scrollTo(item, anchor: .top)
}
}.mayGroupedListStyle()
// Action Navigation
.withTopicDetailsAction(action: action)
.navigationDestination(item: $action.showingReplyChain) {
PostReplyChainView(baseDataSource: dataSource, votes: votes, chain: $0)
.environmentObject(postReply)
}
.navigationDestination(item: $action.navigateToAuthorOnly) {
TopicDetailsView.build(topic: topic, only: $0)
}
.navigationDestination(isPresented: $action.navigateToLocalMode) {
TopicDetailsView.build(topic: topic, localMode: true)
}
// Action Navigation End
.onReceive(dataSource.$lastRefreshTime) { _ in mayScrollToJumpFloor() }
.sheet(isPresented: $showJumpSelector) { TopicJumpSelectorView(maxFloor: maxFloor, initialFloor: floorToJump ?? 0, floorToJump: $floorToJump, pageToJump: $dataSource.loadFromPage) }
}
Expand All @@ -466,7 +466,6 @@ struct TopicDetailsView: View {
main
.navigationTitleInline(string: title)
.toolbarWithFix { toolbar }
.background { navigation }
.onChange(of: postReply.sent) { reloadPageAfter(sent: $1) }
.onChange(of: dataSource.latestResponse) { onNewResponse(response: $1) }
.onChange(of: dataSource.latestError) { onError(e: $1) }
Expand Down
34 changes: 5 additions & 29 deletions app/Shared/Views/TopicListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ struct TopicListView: View {

@State var currentShowingSubforum: Forum? = nil
@State var showingSubforumsModal = false
@State var showingHotTopics = false
@State var showingRecommendedTopics = false
@State var showingToppedTopic = false
@State var order: TopicListRequest.Order? = nil

var dataSource: DataSource {
Expand Down Expand Up @@ -144,14 +141,14 @@ struct TopicListView: View {
} label: {
Label("Order by", systemImage: (order ?? .lastPost).icon)
}
Button(action: { showingHotTopics = true }) {
NavigationLink(destination: HotTopicListView.build(forum: forum)) {
Label("Hot Topics", systemImage: "flame")
}
Button(action: { showingRecommendedTopics = true }) {
NavigationLink(destination: RecommendedTopicListView.build(forum: forum)) {
Label("Recommended Topics", systemImage: "hand.thumbsup")
}
if let _ = toppedTopicID {
Button(action: { showingToppedTopic = true }) {
if let topicID = toppedTopicID {
NavigationLink(destination: TopicDetailsView.build(id: topicID)) {
Label("Topped Topic", systemImage: "arrow.up.to.line")
}
}
Expand Down Expand Up @@ -204,27 +201,6 @@ struct TopicListView: View {
}
}

@ViewBuilder
var subforum: some View {
let destination = TopicListView.build(forum: currentShowingSubforum ?? Forum())
NavigationLink(destination: destination, isActive: $currentShowingSubforum.isNotNil()) {}
.isDetailLink(false)
.hidden()
NavigationLink(destination: EmptyView()) {}.hidden() // hack: unexpected pop
}

@ViewBuilder
var navigations: some View {
NavigationLink(destination: HotTopicListView.build(forum: forum), isActive: $showingHotTopics) {}
.isDetailLink(false)
.hidden()
NavigationLink(destination: RecommendedTopicListView.build(forum: forum), isActive: $showingRecommendedTopics) {}
.isDetailLink(false)
.hidden()
NavigationLink(destination: TopicDetailsView.build(id: toppedTopicID ?? ""), isActive: $showingToppedTopic) {}
.hidden()
}

@ViewBuilder
var icon: some View {
if #available(iOS 15.0, *) {
Expand Down Expand Up @@ -282,7 +258,7 @@ struct TopicListView: View {
.navigationTitleLarge(string: forum.name.localized)
.sheet(isPresented: $showingSubforumsModal) { subforumsModal }
.onChange(of: postReply.sent) { dataSource.reload(page: 1, evenIfNotLoaded: false) }
.background { subforum; navigations }
.navigationDestination(item: $currentShowingSubforum) { TopicListView.build(forum: $0) }
.toolbarWithFix { toolbar }
.onAppear { selectedForum.inner = forum }
.onChange(of: prefs.defaultTopicListOrder) { if $1 != order { order = $1 } }
Expand Down
Loading

0 comments on commit 27bb62f

Please sign in to comment.