Skip to content

Commit 61e0621

Browse files
jacobsimeonJacob Morris
authored and
Jacob Morris
committed
Replace SwiftUI Navigation view with UISplitViewController
1 parent c828685 commit 61e0621

15 files changed

+399
-238
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Combine
2+
3+
4+
class AuthorizationState: ObservableObject {
5+
@Published
6+
var authToken: AuthorizeResponse?
7+
}

PocketKit/Sources/PocketKit/Item/ItemDestinationView.swift

+26-113
Original file line numberDiff line numberDiff line change
@@ -5,129 +5,42 @@
55
import SwiftUI
66
import Sync
77

8+
89
struct ItemDestinationView: View {
9-
private let item: Item
10+
@ObservedObject
11+
var selection: ItemSelection
12+
13+
@ObservedObject
14+
private var settings: ReaderSettings
15+
16+
init(
17+
selection: ItemSelection,
18+
readerSettings: ReaderSettings
19+
) {
20+
self.selection = selection
21+
self.settings = readerSettings
22+
}
23+
24+
private var item: Item? {
25+
selection.selectedItem
26+
}
1027

1128
private var article: Article? {
12-
item.particle
29+
item?.particle
30+
}
31+
32+
var characterDirection: LayoutDirection {
33+
item?.characterDirection ?? LayoutDirection.leftToRight
1334
}
1435

15-
@Environment(\.presentationMode) @Binding
16-
private var presentationMode: PresentationMode
17-
18-
@State
19-
private var isPresentingWebView = false
20-
21-
@State
22-
private var isPresentingOverflow = false
23-
24-
@StateObject
25-
private var settings = ReaderSettings()
26-
27-
@ViewBuilder
28-
private var destinationView: some View {
36+
var body: some View {
2937
if let article = article {
3038
ArticleView(article: article)
31-
.navigationBarHidden(true)
32-
.environment(\.characterDirection, item.characterDirection)
39+
.environmentObject(settings)
40+
.environment(\.characterDirection, characterDirection)
3341
} else {
3442
// TODO: Implement a view for when an article for the item doesn't exist.
3543
EmptyView()
3644
}
3745
}
38-
39-
init(item: Item) {
40-
self.item = item
41-
}
42-
43-
var body: some View {
44-
destinationView
45-
.toolbar(
46-
item: item,
47-
presentationMode: _presentationMode.wrappedValue,
48-
isPresentingWebView: $isPresentingWebView,
49-
isPresentingOverflow: $isPresentingOverflow
50-
).environmentObject(settings)
51-
}
52-
}
53-
54-
private struct ItemToolbar: ViewModifier {
55-
private let item: Item
56-
57-
@Binding
58-
private var presentationMode: PresentationMode
59-
60-
@Binding
61-
private var isPresentingWebView: Bool
62-
63-
@Binding
64-
private var isPresentingOverflow: Bool
65-
66-
init(
67-
item: Item, presentationMode: Binding<PresentationMode>,
68-
isPresentingWebView: Binding<Bool>,
69-
isPresentingOverflow: Binding<Bool>
70-
) {
71-
self.item = item
72-
_presentationMode = presentationMode
73-
_isPresentingWebView = isPresentingWebView
74-
_isPresentingOverflow = isPresentingOverflow
75-
}
76-
77-
func body(content: Content) -> some View {
78-
content
79-
.toolbar {
80-
ToolbarItemGroup(placement: .bottomBar) {
81-
Button(action: {
82-
presentationMode.dismiss()
83-
}) {
84-
Image(systemName: "chevron.backward")
85-
}
86-
87-
Spacer()
88-
89-
Button(action: {
90-
guard item.url != nil else {
91-
return
92-
}
93-
94-
isPresentingWebView = true
95-
}) {
96-
Image(systemName: "safari")
97-
}
98-
.disabled(item.url == nil)
99-
.accessibility(identifier: "web-reader-button")
100-
101-
Button(action: {
102-
isPresentingOverflow = true
103-
}) {
104-
Image(systemName: "ellipsis")
105-
}
106-
}
107-
}
108-
.sheet(isPresented: $isPresentingWebView) {
109-
SafariView(url: item.url!).ignoresSafeArea()
110-
}
111-
.popover(isPresented: $isPresentingOverflow) {
112-
ReaderSettingsView()
113-
}
114-
}
115-
}
116-
117-
private extension View {
118-
func toolbar(
119-
item: Item,
120-
presentationMode: Binding<PresentationMode>,
121-
isPresentingWebView: Binding<Bool>,
122-
isPresentingOverflow: Binding<Bool>
123-
) -> some View {
124-
self.modifier(
125-
ItemToolbar(
126-
item: item,
127-
presentationMode: presentationMode,
128-
isPresentingWebView: isPresentingWebView,
129-
isPresentingOverflow: isPresentingOverflow
130-
)
131-
)
132-
}
13346
}

PocketKit/Sources/PocketKit/Item/ItemListView.swift

+39-13
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,59 @@
55
import SwiftUI
66
import Sync
77
import Textile
8+
import CoreData
9+
810

911
struct ItemListView: View {
12+
private let context: NSManagedObjectContext
13+
private let selection: ItemSelection
14+
15+
init(
16+
context: NSManagedObjectContext,
17+
selection: ItemSelection
18+
) {
19+
self.context = context
20+
self.selection = selection
21+
}
22+
23+
var body: some View {
24+
_ItemListView(selection: selection)
25+
.environment(\.managedObjectContext, context)
26+
}
27+
}
28+
29+
private struct _ItemListView: View {
1030
@Environment(\.source)
1131
private var source: Source
1232

13-
private let token: String
14-
1533
@FetchRequest(fetchRequest: Requests.fetchItems())
1634
var items: FetchedResults<Item>
1735

18-
init(token: String) {
19-
self.token = token
20-
source.refresh(token: token)
36+
@ObservedObject
37+
private var selection: ItemSelection
38+
39+
init(selection: ItemSelection) {
40+
self.selection = selection
41+
}
42+
43+
func background(item: Item) -> Color {
44+
if item.url == selection.selectedItem?.url {
45+
return Color(ColorAsset.ui.grey6)
46+
} else {
47+
return Color.clear
48+
}
2149
}
2250

2351
var body: some View {
24-
List(items) { item in
25-
ZStack(alignment: .leading) {
26-
NavigationLink(
27-
destination: ItemDestinationView(item: item)
28-
) { EmptyView() }
29-
.opacity(0)
30-
31-
ItemRowView(model: ItemPresenter(item: item))
52+
List {
53+
ForEach(items) { item in
54+
Button(action: { selection.selectedItem = item }) {
55+
ItemRowView(model: ItemPresenter(item: item))
56+
}.listRowBackground(background(item: item))
3257
}
3358
}
3459
.listStyle(.plain)
3560
.accessibility(identifier: "user-list")
61+
.navigationTitle(Text("My List"))
3662
}
3763
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Combine
2+
import Sync
3+
4+
5+
class ItemSelection: ObservableObject {
6+
@Published
7+
var selectedItem: Item?
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import UIKit
2+
import SwiftUI
3+
4+
5+
protocol ItemViewControllerDelegate: AnyObject {
6+
func itemViewControllerDidTapOverflowButton(_ itemViewController: ItemViewController)
7+
func itemViewControllerDidTapWebViewButton(_ itemViewController: ItemViewController)
8+
}
9+
10+
class ItemViewController: UIViewController {
11+
private let itemView: ItemDestinationView
12+
private let itemHost: UIHostingController<ItemDestinationView>
13+
weak var delegate: ItemViewControllerDelegate?
14+
15+
init(
16+
selection: ItemSelection,
17+
readerSettings: ReaderSettings
18+
) {
19+
itemView = ItemDestinationView(
20+
selection: selection,
21+
readerSettings: readerSettings
22+
)
23+
itemHost = UIHostingController(rootView: itemView)
24+
25+
super.init(nibName: nil, bundle: nil)
26+
27+
navigationItem.rightBarButtonItems = [
28+
UIBarButtonItem(
29+
image: UIImage(systemName: "ellipsis"),
30+
style: .plain,
31+
target: self,
32+
action: #selector(showOverflow)
33+
),
34+
UIBarButtonItem(
35+
image: UIImage(systemName: "safari"),
36+
style: .plain,
37+
target: self,
38+
action: #selector(showWebView)
39+
)
40+
]
41+
}
42+
43+
override func loadView() {
44+
view = UIView()
45+
view.addSubview(itemHost.view)
46+
addChild(itemHost)
47+
itemHost.didMove(toParent: self)
48+
49+
itemHost.view.translatesAutoresizingMaskIntoConstraints = false
50+
NSLayoutConstraint.activate([
51+
itemHost.view.topAnchor.constraint(equalTo: view.topAnchor),
52+
itemHost.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
53+
itemHost.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
54+
itemHost.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
55+
])
56+
}
57+
58+
required init?(coder: NSCoder) {
59+
fatalError("\(Self.self) cannot be instantiated from a xib/storyboard")
60+
}
61+
62+
@objc
63+
private func showWebView() {
64+
delegate?.itemViewControllerDidTapWebViewButton(self)
65+
}
66+
67+
@objc
68+
private func showOverflow() {
69+
delegate?.itemViewControllerDidTapOverflowButton(self)
70+
}
71+
}

0 commit comments

Comments
 (0)