Skip to content

Commit 518ebe3

Browse files
committed
refactor: Use GutenbergKit configuration builder
Adopt the latest patterns to embrace immutable configuration.
1 parent 4b4041a commit 518ebe3

File tree

4 files changed

+102
-72
lines changed

4 files changed

+102
-72
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import Foundation
2+
import GutenbergKit
3+
import WordPressData
4+
import WordPressShared
5+
6+
extension EditorConfigurationBuilder {
7+
init(blog: Blog) {
8+
let selfHostedApiUrl = blog.restApiRootURL ?? blog.url(withPath: "wp-json/")
9+
let isWPComSite = blog.isHostedAtWPcom || blog.isAtomic()
10+
let siteApiRoot = blog.isAccessibleThroughWPCom() && isWPComSite ? blog.wordPressComRestApi?.baseURL.absoluteString : selfHostedApiUrl
11+
let siteId = blog.dotComID?.stringValue
12+
let siteDomain = blog.primaryDomainAddress
13+
let authToken = blog.authToken ?? ""
14+
var authHeader = "Bearer \(authToken)"
15+
16+
let applicationPassword = try? blog.getApplicationToken()
17+
18+
if let appPassword = applicationPassword, let username = blog.username {
19+
let credentials = "\(username):\(appPassword)"
20+
if let credentialsData = credentials.data(using: .utf8) {
21+
let base64Credentials = credentialsData.base64EncodedString()
22+
authHeader = "Basic \(base64Credentials)"
23+
}
24+
}
25+
26+
// Must provide both namespace forms to detect usages of both forms in third-party code
27+
var siteApiNamespace: [String] = []
28+
if isWPComSite {
29+
if let siteId {
30+
siteApiNamespace.append("sites/\(siteId)/")
31+
}
32+
siteApiNamespace.append("sites/\(siteDomain)/")
33+
}
34+
35+
self = EditorConfigurationBuilder()
36+
.setSiteUrl(blog.url ?? "")
37+
.setSiteApiRoot(siteApiRoot ?? "")
38+
.setSiteApiNamespace(siteApiNamespace)
39+
.setNamespaceExcludedPaths(["/wpcom/v2/following/recommendations", "/wpcom/v2/following/mine"])
40+
.setAuthHeader(authHeader)
41+
.setShouldUseThemeStyles(FeatureFlag.newGutenbergThemeStyles.enabled)
42+
43+
// Limited to Simple sites until application password auth is supported
44+
if RemoteFeatureFlag.newGutenbergPlugins.enabled() && blog.isHostedAtWPcom {
45+
self = self.setShouldUsePlugins(true)
46+
if var editorAssetsEndpoint = blog.wordPressComRestApi?.baseURL {
47+
editorAssetsEndpoint.appendPathComponent("wpcom/v2/sites")
48+
if let siteId {
49+
editorAssetsEndpoint.appendPathComponent(siteId)
50+
} else {
51+
editorAssetsEndpoint.appendPathComponent(siteDomain)
52+
}
53+
editorAssetsEndpoint.appendPathComponent("editor-assets")
54+
self = self.setEditorAssetsEndpoint(editorAssetsEndpoint)
55+
}
56+
}
57+
self = self.setLocale(WordPressComLanguageDatabase().deviceLanguage.slug)
58+
59+
if !blog.isSelfHosted {
60+
let siteType: String = blog.isHostedAtWPcom ? "simple" : "atomic"
61+
do {
62+
self = self.setWebViewGlobals([
63+
try WebViewGlobal(name: "_currentSiteType", value: .string(siteType))
64+
])
65+
} catch {
66+
wpAssertionFailure("Failed to create WebViewGlobal", userInfo: ["error": "\(error)"])
67+
self = self.setWebViewGlobals([])
68+
}
69+
}
70+
}
71+
}

WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ final class MySiteViewController: UIViewController, UIScrollViewDelegate, NoSite
172172

173173
if RemoteFeatureFlag.newGutenberg.enabled() {
174174
GutenbergKit.EditorViewController.warmup(
175-
configuration: blog.flatMap(EditorConfiguration.init(blog:)) ?? .default
175+
configuration: blog.flatMap { EditorConfigurationBuilder(blog: $0).build() } ?? .default
176176
)
177177
}
178178
}

WordPress/Classes/ViewRelated/Comments/Controllers/Editor/CommentGutenbergEditorViewController.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ final class CommentGutenbergEditorViewController: UIViewController {
3535
override func viewDidLoad() {
3636
super.viewDidLoad()
3737

38-
var configuration = EditorConfiguration(content: initialContent ?? "")
39-
configuration.hideTitle = true
38+
let configuration = EditorConfigurationBuilder(content: initialContent ?? "")
39+
.setShouldHideTitle(true)
40+
.build()
4041

4142
let editorVC = GutenbergKit.EditorViewController(configuration: configuration)
4243
editorVC.delegate = self

WordPress/Classes/ViewRelated/NewGutenberg/NewGutenbergViewController.swift

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ class NewGutenbergViewController: UIViewController, PostEditor, PublishingEditor
128128
self.editorSession = PostEditorAnalyticsSession(editor: .gutenbergKit, post: post)
129129
self.navigationBarManager = navigationBarManager ?? PostEditorNavigationBarManager()
130130

131-
var conf = EditorConfiguration(blog: post.blog)
132-
conf.title = post.postTitle ?? ""
133-
conf.content = post.content ?? ""
134-
conf.postID = post.postID?.intValue != -1 ? post.postID?.intValue : nil
135-
conf.postType = post is Page ? "page" : "post"
131+
let configuration = EditorConfigurationBuilder(blog: post.blog)
132+
.setTitle(post.postTitle ?? "")
133+
.setContent(post.content ?? "")
134+
.setPostID(post.postID?.intValue != -1 ? post.postID?.intValue : nil)
135+
.setPostType(post is Page ? "page" : "post")
136+
.build()
136137

137-
self.editorViewController = GutenbergKit.EditorViewController(configuration: conf)
138+
self.editorViewController = GutenbergKit.EditorViewController(configuration: configuration)
138139

139140
super.init(nibName: nil, bundle: nil)
140141

@@ -367,8 +368,12 @@ class NewGutenbergViewController: UIViewController, PostEditor, PublishingEditor
367368
hasEditorStarted = true
368369

369370
if let settings {
370-
var updatedConfig = self.editorViewController.configuration
371-
updatedConfig.updateEditorSettings(settings)
371+
// TODO: `setEditorSettings` throws due to incompatibility between `[String: Any]`
372+
// and `[String: Encodable]`. The latter is now expected by
373+
// `GutenbergKitConfiguration.EditorSettings`. How should we reconcile this?
374+
let updatedConfig = self.editorViewController.configuration.toBuilder()
375+
.setEditorSettings(settings)
376+
.build()
372377
self.editorViewController.updateConfiguration(updatedConfig)
373378
}
374379
self.editorViewController.startEditorSetup()
@@ -855,71 +860,24 @@ private extension NewGutenbergViewController {
855860
}
856861
}
857862

858-
extension EditorConfiguration {
859-
init(blog: Blog) {
860-
let selfHostedApiUrl = blog.restApiRootURL ?? blog.url(withPath: "wp-json/")
861-
let isWPComSite = blog.isHostedAtWPcom || blog.isAtomic()
862-
let siteApiRoot = blog.isAccessibleThroughWPCom() && isWPComSite ? blog.wordPressComRestApi?.baseURL.absoluteString : selfHostedApiUrl
863-
let siteId = blog.dotComID?.stringValue
864-
let siteDomain = blog.primaryDomainAddress
865-
let authToken = blog.authToken ?? ""
866-
var authHeader = "Bearer \(authToken)"
867-
868-
let applicationPassword = try? blog.getApplicationToken()
869-
870-
if let appPassword = applicationPassword, let username = blog.username {
871-
let credentials = "\(username):\(appPassword)"
872-
if let credentialsData = credentials.data(using: .utf8) {
873-
let base64Credentials = credentialsData.base64EncodedString()
874-
authHeader = "Basic \(base64Credentials)"
875-
}
876-
}
863+
// Block Editor Settings
864+
extension NewGutenbergViewController {
877865

878-
// Must provide both namespace forms to detect usages of both forms in third-party code
879-
var siteApiNamespace: [String] = []
880-
if isWPComSite {
881-
if let siteId {
882-
siteApiNamespace.append("sites/\(siteId)/")
883-
}
884-
siteApiNamespace.append("sites/\(siteDomain)/")
866+
private func fetchBlockSettings() {
867+
guard let service = editorSettingsService else {
868+
return // TODO: when can it happen?
885869
}
886-
887-
self = EditorConfiguration()
888-
889-
self.siteURL = blog.url ?? ""
890-
self.siteApiRoot = siteApiRoot ?? ""
891-
self.siteApiNamespace = siteApiNamespace
892-
self.namespaceExcludedPaths = ["/wpcom/v2/following/recommendations", "/wpcom/v2/following/mine"]
893-
self.authHeader = authHeader
894-
895-
self.themeStyles = FeatureFlag.newGutenbergThemeStyles.enabled
896-
// Limited to Simple sites until application password auth is supported
897-
if RemoteFeatureFlag.newGutenbergPlugins.enabled() && blog.isHostedAtWPcom {
898-
self.plugins = true
899-
if var editorAssetsEndpoint = blog.wordPressComRestApi?.baseURL {
900-
editorAssetsEndpoint.appendPathComponent("wpcom/v2/sites")
901-
if let siteId {
902-
editorAssetsEndpoint.appendPathComponent(siteId)
903-
} else {
904-
editorAssetsEndpoint.appendPathComponent(siteDomain)
870+
service.fetchSettings({ [weak self] result in
871+
switch result {
872+
case .success(let response):
873+
if response.hasChanges {
874+
// TODO: inject in hte editor
875+
// self.gutenberg.updateEditorSettings(response.blockEditorSettings)
905876
}
906-
editorAssetsEndpoint.appendPathComponent("editor-assets")
907-
self.editorAssetsEndpoint = editorAssetsEndpoint
877+
case .failure(let err):
878+
DDLogError("Error fetching settings: \(err)")
908879
}
909-
}
910-
self.locale = WordPressComLanguageDatabase().deviceLanguage.slug
911-
912-
if !blog.isSelfHosted {
913-
let siteType: String = blog.isHostedAtWPcom ? "simple" : "atomic"
914-
do {
915-
self.webViewGlobals = [
916-
try WebViewGlobal(name: "_currentSiteType", value: .string(siteType))
917-
]
918-
} catch {
919-
wpAssertionFailure("Failed to create WebViewGlobal", userInfo: ["error": "\(error)"])
920-
self.webViewGlobals = []
921-
}
922-
}
880+
})
923881
}
924882
}
925883

0 commit comments

Comments
 (0)