Skip to content

Commit 1aca406

Browse files
committed
Add site preparation screen
1 parent b8d37fd commit 1aca406

File tree

6 files changed

+392
-97
lines changed

6 files changed

+392
-97
lines changed

ios/Demo-iOS/Sources/ConfigurationItem.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import Foundation
2+
import GutenbergKit
23

34
/// Represents a configuration item for the editor
4-
enum ConfigurationItem: Codable, Identifiable, Equatable {
5+
enum ConfigurationItem: Codable, Identifiable, Equatable, Hashable {
56
case bundledEditor
67
case editorConfiguration(ConfiguredEditor)
78

@@ -24,8 +25,13 @@ enum ConfigurationItem: Codable, Identifiable, Equatable {
2425
}
2526
}
2627

28+
struct RunnableEditor: Equatable, Hashable {
29+
let configuration: EditorConfiguration
30+
let dependencies: EditorDependencies?
31+
}
32+
2733
/// Configuration for an editor with site integration
28-
struct ConfiguredEditor: Codable, Identifiable, Equatable {
34+
struct ConfiguredEditor: Codable, Identifiable, Equatable, Hashable {
2935
let id: String
3036
let name: String
3137
let siteUrl: String

ios/Demo-iOS/Sources/GutenbergApp.swift

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,33 @@ import SwiftUI
22
import OSLog
33
import GutenbergKit
44

5+
final class Navigation: ObservableObject {
6+
@Published var path = NavigationPath()
7+
8+
func push(_ path: any Hashable) {
9+
self.path.append(path)
10+
}
11+
}
12+
13+
extension EnvironmentValues {
14+
private struct NavigationKey: EnvironmentKey {
15+
static let defaultValue = Navigation()
16+
}
17+
18+
var navigation: Navigation {
19+
get { self[NavigationKey.self] }
20+
set { self[NavigationKey.self] = newValue }
21+
}
22+
}
23+
524
@main
625
struct GutenbergApp: App {
26+
@StateObject
27+
private var navigation = Navigation()
28+
29+
private let configurationStorage = ConfigurationStorage()
30+
private let authenticationManager = AuthenticationManager()
31+
732
init() {
833
// Configure logger for GutenbergKit
934
EditorLogger.shared = OSLogEditorLogger()
@@ -12,12 +37,19 @@ struct GutenbergApp: App {
1237

1338
var body: some Scene {
1439
WindowGroup {
15-
NavigationStack {
40+
NavigationStack(path: $navigation.path) {
1641
AppRootView()
42+
.navigationDestination(for: RunnableEditor.self) { editor in
43+
EditorView(configuration: editor.configuration, dependencies: editor.dependencies)
44+
}
45+
.navigationDestination(for: ConfigurationItem.self) { item in
46+
SitePreparationView(site: item)
47+
}
1748
}
1849
}
19-
.environmentObject(ConfigurationStorage())
20-
.environmentObject(AuthenticationManager())
50+
.environment(\.navigation, navigation)
51+
.environmentObject(configurationStorage)
52+
.environmentObject(authenticationManager)
2153
}
2254
}
2355

ios/Demo-iOS/Sources/Views/AppRootView.swift

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ struct AppRootView: View {
1111
@EnvironmentObject
1212
private var authenticationManager: AuthenticationManager
1313

14-
@State private var selectedConfiguration: ConfigurationItem?
1514
@State private var configurations: [ConfigurationItem] = [.bundledEditor]
1615
@State private var siteUrlInput = ""
1716

@@ -23,7 +22,7 @@ struct AppRootView: View {
2322
@AppStorage("isNativeInserterEnabled") private var isNativeInserterEnabled = false
2423

2524
var body: some View {
26-
EditorList(isNativeInserterEnabled: $isNativeInserterEnabled, selectedConfiguration: $selectedConfiguration)
25+
EditorList()
2726
.alert(isPresented: $hasError, error: error, actions: {
2827
Button {
2928
self.hasError = false
@@ -35,67 +34,6 @@ struct AppRootView: View {
3534
}
3635
}.buttonStyle(.borderedProminent)
3736
})
38-
.fullScreenCover(item: $selectedConfiguration) { config in
39-
editor
40-
}
41-
.onChange(of: self.selectedConfiguration) { oldValue, newValue in
42-
switch newValue {
43-
case .bundledEditor:
44-
activeEditorConfiguration = EditorConfiguration.bundled
45-
.toBuilder()
46-
.setNativeInserterEnabled(self.isNativeInserterEnabled)
47-
.build()
48-
case .editorConfiguration(let config):
49-
self.loadEditorConfiguration(for: config)
50-
case .none:
51-
self.activeEditorConfiguration = nil
52-
}
53-
}
54-
}
55-
56-
@ViewBuilder
57-
var editor: some View {
58-
NavigationView {
59-
if let activeEditorConfiguration {
60-
EditorView(configuration: activeEditorConfiguration)
61-
} else {
62-
ProgressView("Preparing Editor")
63-
}
64-
}
65-
}
66-
67-
private func loadEditorConfiguration(for config: ConfiguredEditor) {
68-
Task {
69-
do {
70-
let parsedApiRoot = try ParsedUrl.parse(input: config.siteApiRoot)
71-
let client = WordPressAPI(
72-
urlSession: .shared,
73-
apiRootUrl: parsedApiRoot,
74-
authentication: .authorizationHeader(token: config.authHeader)
75-
)
76-
77-
let apiRoot = try await client.apiRoot.get().data
78-
79-
let canUsePlugins = apiRoot.hasRoute(route: "/wpcom/v2/editor-assets")
80-
let canUseEditorStyles = apiRoot.hasRoute(route: "/wp-block-editor/v1/settings")
81-
82-
self.activeEditorConfiguration = EditorConfigurationBuilder(
83-
postType: "post",
84-
siteURL: URL(string: apiRoot.siteUrlString())!,
85-
siteApiRoot: parsedApiRoot.asURL()
86-
)
87-
.setShouldUseThemeStyles(canUseEditorStyles)
88-
.setShouldUsePlugins(canUsePlugins)
89-
.setAuthHeader(config.authHeader)
90-
.setNativeInserterEnabled(isNativeInserterEnabled)
91-
.setLogLevel(.debug)
92-
.setEnableNetworkLogging(true)
93-
.build()
94-
} catch {
95-
self.hasError = true
96-
self.error = AppError(errorDescription: error.localizedDescription)
97-
}
98-
}
9937
}
10038

10139
private func deleteConfiguration(_ config: ConfigurationItem) {

ios/Demo-iOS/Sources/Views/EditorList.swift

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@ struct EditorList: View {
77

88
@State private var showAddDialog = false
99
@State private var showDebugSettings = false
10-
@Binding var isNativeInserterEnabled: Bool
11-
12-
@Binding var selectedConfiguration: ConfigurationItem?
1310

1411
@State var configurationToDelete: ConfigurationItem?
1512

1613
var body: some View {
1714
List {
1815
Section {
19-
Button("Default Editor") {
20-
selectedConfiguration = .bundledEditor
16+
NavigationLink("Default Editor") {
17+
SitePreparationView(site: .bundledEditor)
18+
2119
}
2220
} header: {
2321
if ProcessInfo.processInfo.environment["GUTENBERG_EDITOR_URL"] != nil
@@ -47,10 +45,6 @@ struct EditorList: View {
4745
} footer: {
4846
Text("Editors with site configuration; enabling media uploads, plugin support, etc.")
4947
}
50-
51-
Section("Feature Configuration") {
52-
Toggle("Native Inserter", isOn: $isNativeInserterEnabled)
53-
}
5448
}
5549
.alert(
5650
"Delete Editor Configuration?",
@@ -105,9 +99,7 @@ struct EditorList: View {
10599
if case .editorConfiguration = $0 { return true }
106100
return false
107101
}) { config in
108-
Button(config.displayName) {
109-
self.selectedConfiguration = config
110-
}
102+
NavigationLink(config.displayName, value: config)
111103
.swipeActions(edge: .trailing) {
112104
Button(role: .destructive) {
113105
configurationToDelete = config

ios/Demo-iOS/Sources/Views/EditorView.swift

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,26 @@ import GutenbergKit
33

44
struct EditorView: View {
55
private let configuration: EditorConfiguration
6+
private let dependencies: EditorDependencies?
67

7-
@State private var viewModel = EditorViewModel()
8+
@ObservedObject private var viewModel = EditorViewModel()
89

9-
@Environment(\.dismiss) private var dismiss
10-
11-
init(configuration: EditorConfiguration) {
10+
init(configuration: EditorConfiguration, dependencies: EditorDependencies? = nil) {
1211
self.configuration = configuration
12+
self.dependencies = dependencies
1313
}
1414

1515
var body: some View {
16-
_EditorView(configuration: configuration, viewModel: viewModel)
16+
_EditorView(
17+
configuration: configuration,
18+
dependencies: dependencies,
19+
viewModel: viewModel
20+
)
1721
.toolbar { toolbar }
1822
}
1923

2024
@ToolbarContentBuilder
2125
private var toolbar: some ToolbarContent {
22-
ToolbarItem(placement: .topBarLeading) {
23-
Button {
24-
dismiss()
25-
} label: {
26-
Image(systemName: "xmark")
27-
}
28-
.disabled(viewModel.isModalDialogOpen)
29-
}
30-
3126
ToolbarItemGroup(placement: .topBarTrailing) {
3227
Group {
3328
Button {
@@ -90,13 +85,16 @@ struct EditorView: View {
9085

9186
private struct _EditorView: UIViewControllerRepresentable {
9287
private let configuration: EditorConfiguration
88+
private let dependencies: EditorDependencies?
9389
private let viewModel: EditorViewModel
9490

9591
init(
9692
configuration: EditorConfiguration,
93+
dependencies: EditorDependencies? = nil,
9794
viewModel: EditorViewModel
9895
) {
9996
self.configuration = configuration
97+
self.dependencies = dependencies
10098
self.viewModel = viewModel
10199
}
102100

@@ -105,7 +103,7 @@ private struct _EditorView: UIViewControllerRepresentable {
105103
}
106104

107105
func makeUIViewController(context: Context) -> EditorViewController {
108-
let viewController = EditorViewController(configuration: configuration)
106+
let viewController = EditorViewController(configuration: configuration, dependencies: dependencies)
109107
viewController.delegate = context.coordinator
110108
viewController.webView.isInspectable = true
111109

@@ -209,8 +207,7 @@ private struct _EditorView: UIViewControllerRepresentable {
209207
}
210208
}
211209

212-
@Observable
213-
private final class EditorViewModel {
210+
private final class EditorViewModel: ObservableObject {
214211
var isModalDialogOpen = false
215212
var hasUndo = false
216213
var hasRedo = false

0 commit comments

Comments
 (0)