Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.wordpress.android.ui.posts

import org.wordpress.android.util.UrlUtils
import org.wordpress.gutenberg.EditorConfiguration
import org.wordpress.gutenberg.model.EditorConfiguration
import org.wordpress.gutenberg.model.PostTypeDetails

/**
* Utility object for building EditorConfiguration from settings maps.
Expand All @@ -12,47 +13,64 @@ object EditorConfigurationBuilder {
* Builds an EditorConfiguration from the provided settings map.
*
* @param settings The settings map containing all configuration values
* @param editorSettings Optional editor settings string (null for warmup scenarios)
* @return Configured EditorConfiguration instance
*/
fun build(
settings: Map<String, Any?>,
editorSettings: String? = null
): EditorConfiguration {
return EditorConfiguration.Builder().apply {
val postId = settings.getSetting<Int>("postId")?.let { if (it == 0) -1 else it }
val siteURL = settings.getSetting<String>("siteURL") ?: ""
val siteApiNamespace = settings.getStringArray("siteApiNamespace")
val siteURL = settings.getSetting<String>("siteURL") ?: ""
val siteApiRoot = settings.getSetting<String>("siteApiRoot") ?: ""
val postType = settings.getSetting<PostTypeDetails>("postType")
?: PostTypeDetails.post
val siteApiNamespace = settings.getStringArray("siteApiNamespace")

return EditorConfiguration.builder(
siteURL = siteURL,
siteApiRoot = siteApiRoot,
postType = postType
).apply {
val postId = settings.getSetting<Int>("postId")
?.let { if (it == 0) null else it.toUInt() }

// Post settings
setTitle(settings.getSetting<String>("postTitle") ?: "")
setContent(settings.getSetting<String>("postContent") ?: "")
setPostId(postId)
setPostType(settings.getSetting<String>("postType"))
setPostStatus(settings.getSetting<String>("status") ?: "draft")

// Site settings
setSiteURL(siteURL)
setSiteApiRoot(settings.getSetting<String>("siteApiRoot") ?: "")
setSiteApiNamespace(siteApiNamespace)
setNamespaceExcludedPaths(settings.getStringArray("namespaceExcludedPaths"))
setAuthHeader(settings.getSetting<String>("authHeader") ?: "")
setNamespaceExcludedPaths(
settings.getStringArray("namespaceExcludedPaths")
)
setAuthHeader(
settings.getSetting<String>("authHeader") ?: ""
)

// Features
setThemeStyles(settings.getSettingOrDefault("themeStyles", false))
setPlugins(settings.getSettingOrDefault("plugins", false))
setThemeStyles(
settings.getSettingOrDefault("themeStyles", false)
)
setPlugins(
settings.getSettingOrDefault("plugins", false)
)
setLocale(settings.getSetting<String>("locale") ?: "en")

// Editor asset caching configuration
configureEditorAssetCaching(settings, siteURL, siteApiNamespace)
configureEditorAssetCaching(
settings, siteURL, siteApiNamespace
)

// Cookies
setCookies(settings.getSetting<Map<String, String>>("cookies") ?: emptyMap())
setCookies(
settings.getSetting<Map<String, String>>("cookies")
?: emptyMap()
)

// Network logging for debugging
setEnableNetworkLogging(settings.getSettingOrDefault("enableNetworkLogging", false))

// Editor settings (null for warmup scenarios)
setEditorSettings(editorSettings)
setEnableNetworkLogging(
settings.getSettingOrDefault("enableNetworkLogging", false)
)
}.build()
}

Expand All @@ -72,18 +90,28 @@ object EditorConfigurationBuilder {
setCachedAssetHosts(cachedHosts)

val firstNamespace = siteApiNamespace.firstOrNull() ?: ""
val siteApiRoot = settings.getSetting<String>("siteApiRoot") ?: ""
val siteApiRoot =
settings.getSetting<String>("siteApiRoot") ?: ""
if (firstNamespace.isNotEmpty() && siteApiRoot.isNotEmpty()) {
setEditorAssetsEndpoint("${siteApiRoot}wpcom/v2/${firstNamespace}editor-assets")
setEditorAssetsEndpoint(
"${siteApiRoot}wpcom/v2/${firstNamespace}editor-assets"
)
}
}

// Type-safe settings accessors - moved from GutenbergKitEditorFragment
private inline fun <reified T> Map<String, Any?>.getSetting(key: String): T? = this[key] as? T
// Type-safe settings accessors
private inline fun <reified T> Map<String, Any?>.getSetting(
key: String
): T? = this[key] as? T

private inline fun <reified T> Map<String, Any?>.getSettingOrDefault(key: String, default: T): T =
getSetting(key) ?: default
private inline fun <reified T> Map<String, Any?>.getSettingOrDefault(
key: String, default: T
): T = getSetting(key) ?: default

private fun Map<String, Any?>.getStringArray(key: String): Array<String> =
getSetting<Array<String?>>(key)?.asSequence()?.filterNotNull()?.toList()?.toTypedArray() ?: emptyArray()
private fun Map<String, Any?>.getStringArray(
key: String
): Array<String> =
getSetting<Array<String?>>(key)
?.asSequence()?.filterNotNull()?.toList()?.toTypedArray()
?: emptyArray()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2209,40 +2209,35 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene
}

val siteConfig = GutenbergKitSettingsBuilder.SiteConfig.fromSiteModel(siteModel)

val postConfig = GutenbergKitSettingsBuilder.PostConfig.fromPostModel(
editPostRepository.getPost()
)

val featureConfig = GutenbergKitSettingsBuilder.FeatureConfig(
isPluginsFeatureEnabled = gutenbergKitPluginsFeature.isEnabled(),
isThemeStylesFeatureEnabled = siteSettings?.useThemeStyles ?: true,
isNetworkLoggingEnabled = AppPrefs.isTrackNetworkRequestsEnabled()
)

val appConfig = GutenbergKitSettingsBuilder.AppConfig(
accessToken = accountStore.accessToken,
locale = perAppLocaleManager.getCurrentLocaleLanguageCode(),
cookies = editPostAuthViewModel.getCookiesForPrivateSites(site, privateAtomicCookie),
cookies = editPostAuthViewModel.getCookiesForPrivateSites(
site, privateAtomicCookie
),
accountUserId = accountStore.account.userId,
accountUserName = accountStore.account.userName,
userAgent = userAgent,
isJetpackSsoEnabled = isJetpackSsoEnabled
)

val config = GutenbergKitSettingsBuilder.GutenbergKitConfig(
val settings = GutenbergKitSettingsBuilder.buildSettings(
siteConfig = siteConfig,
postConfig = postConfig,
appConfig = appConfig,
featureConfig = featureConfig
)
val configuration = EditorConfigurationBuilder.build(settings)

return GutenbergKitEditorFragment.newInstanceWithBuilder(
getContext(),
isNewPost,
jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(),
config
)
return GutenbergKitEditorFragment.newInstance(configuration)
}

override fun instantiateItem(container: ViewGroup, position: Int): Any {
Expand Down Expand Up @@ -2955,6 +2950,10 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene
Handler(Looper.getMainLooper()).post { invalidateOptionsMenu() }
}

override fun getPersistedTitle(): String = editPostRepository.title

override fun getPersistedContent(): String = editPostRepository.content

// FluxC events
@Suppress("unused", "CyclomaticComplexMethod")
@Subscribe(threadMode = ThreadMode.MAIN)
Expand Down Expand Up @@ -3133,8 +3132,9 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene
@Suppress("unused")
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
fun onEditorSettingsChanged(event: OnEditorSettingsChanged) {
val editorSettingsString = event.editorSettings?.toJsonString() ?: "undefined"
editorFragment?.startWithEditorSettings(editorSettingsString)
// In GutenbergKit v0.15.0, the editor configuration is provided at
// construction time. Editor settings are no longer applied after the
// fact. This handler is retained for the EventBus subscription.
}

// EditorDataProvider methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.wordpress.android.fluxc.utils.extensions.getPasswordProcessed
import org.wordpress.android.fluxc.utils.extensions.getUserNameProcessed
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.UrlUtils
import org.wordpress.gutenberg.model.PostTypeDetails

object GutenbergKitSettingsBuilder {
private const val AUTH_BEARER_PREFIX = "Bearer "
Expand Down Expand Up @@ -54,15 +55,17 @@ object GutenbergKitSettingsBuilder {
val remotePostId: Long?,
val isPage: Boolean,
val title: String?,
val content: String?
val content: String?,
val status: String?
) {
companion object {
fun fromPostModel(postModel: PostImmutableModel?): PostConfig {
return PostConfig(
remotePostId = postModel?.remotePostId,
isPage = postModel?.isPage ?: false,
title = postModel?.title,
content = postModel?.content
content = postModel?.content,
status = postModel?.status
)
}
}
Expand Down Expand Up @@ -126,7 +129,12 @@ object GutenbergKitSettingsBuilder {

return mutableMapOf(
"postId" to postConfig.remotePostId?.toInt(),
"postType" to if (postConfig.isPage) "page" else "post",
"postType" to if (postConfig.isPage) {
PostTypeDetails.page
} else {
PostTypeDetails.post
},
"status" to postConfig.status,
"postTitle" to postConfig.title,
"postContent" to postConfig.content,
"siteURL" to siteConfig.url,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package org.wordpress.android.ui.posts

import android.content.Context
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.UserAgent
import org.wordpress.android.fluxc.store.AccountStore
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.AppLog.T
import org.wordpress.android.util.PerAppLocaleManager
import org.wordpress.android.util.SiteUtils
import org.wordpress.android.util.config.GutenbergKitPluginsFeature
import org.wordpress.gutenberg.EditorConfiguration
import org.wordpress.gutenberg.GutenbergView
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
Expand All @@ -25,12 +18,7 @@ import javax.inject.Singleton
*/
@Singleton
class GutenbergKitWarmupHelper @Inject constructor(
private val appContext: Context,
private val accountStore: AccountStore,
private val userAgent: UserAgent,
private val perAppLocaleManager: PerAppLocaleManager,
private val gutenbergKitFeatureChecker: GutenbergKitFeatureChecker,
private val gutenbergKitPluginsFeature: GutenbergKitPluginsFeature,
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
) {
private var lastWarmedUpSiteId: Long? = null
Expand Down Expand Up @@ -93,62 +81,13 @@ class GutenbergKitWarmupHelper @Inject constructor(
return shouldWarmup
}

@Suppress("UnusedParameter")
private suspend fun performWarmup(site: SiteModel) {
try {
isWarmupInProgress = true
AppLog.d(T.EDITOR, "GutenbergKitWarmupHelper: Starting warmup for site ${site.siteId}")

val configuration = buildWarmupConfiguration(site)

// Perform the warmup on the main thread as it involves WebView
kotlinx.coroutines.withContext(kotlinx.coroutines.Dispatchers.Main) {
GutenbergView.warmup(appContext, configuration)
}

lastWarmedUpSiteId = site.siteId
AppLog.d(T.EDITOR, "GutenbergKitWarmupHelper: Warmup completed for site ${site.siteId}")
} catch (e: IllegalStateException) {
AppLog.e(T.EDITOR, "GutenbergKitWarmupHelper: Warmup failed - illegal state", e)
} finally {
isWarmupInProgress = false
}
}

private fun buildWarmupConfiguration(site: SiteModel): EditorConfiguration {
// Build the configuration using the same patterns as GutenbergKitSettingsBuilder
val siteConfig = GutenbergKitSettingsBuilder.SiteConfig.fromSiteModel(site)

// Create minimal post config for warmup (no specific post data)
val postConfig = GutenbergKitSettingsBuilder.PostConfig(
remotePostId = null,
isPage = false,
title = "",
content = ""
// GutenbergView.warmup() was removed in GutenbergKit v0.15.0.
// Warmup/preloading needs to be reimplemented using the new API.
AppLog.d(
T.EDITOR,
"GutenbergKitWarmupHelper: Warmup not yet supported in v0.15.0"
)

val appConfig = GutenbergKitSettingsBuilder.AppConfig(
accessToken = accountStore.accessToken,
locale = perAppLocaleManager.getCurrentLocaleLanguageCode(),
cookies = null, // No cookies needed for warmup
accountUserId = accountStore.account.userId,
accountUserName = accountStore.account.userName,
userAgent = userAgent,
isJetpackSsoEnabled = false // Default to false for warmup
)

val featureConfig = GutenbergKitSettingsBuilder.FeatureConfig(
isPluginsFeatureEnabled = gutenbergKitPluginsFeature.isEnabled(),
// Default to true during warmup; actual value will be used when editor launches
isThemeStylesFeatureEnabled = true
)

val settings = GutenbergKitSettingsBuilder.buildSettings(
siteConfig = siteConfig,
postConfig = postConfig,
appConfig = appConfig,
featureConfig = featureConfig
)

return EditorConfigurationBuilder.build(settings, editorSettings = null)
}
}
Loading
Loading