Skip to content
Draft
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
Expand Up @@ -22,7 +22,7 @@
import java.io.OutputStream;

public class WordPressDB {
private static final int DATABASE_VERSION = 70;
private static final int DATABASE_VERSION = 71;


// Warning renaming DATABASE_NAME could break previous App backups (see: xml/backup_scheme.xml)
Expand Down Expand Up @@ -187,6 +187,9 @@ public WordPressDB(Context ctx) {
case 69:
// add editor theme styles site setting
mDb.execSQL(SiteSettingsModel.ADD_USE_THEME_STYLES);
case 70:
// add third-party blocks site setting
mDb.execSQL(SiteSettingsModel.ADD_USE_THIRD_PARTY_BLOCKS);
}
mDb.setVersion(DATABASE_VERSION);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.wordpress.android.datasets

import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.models.SiteSettingsModel

/**
* Provides site-level settings for a given [SiteModel].
*/
interface SiteSettingsProvider {
fun getSettings(site: SiteModel): SiteSettingsModel?
fun isBlockEditorDefault(site: SiteModel): Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.wordpress.android.datasets

import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.models.SiteSettingsModel
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class SiteSettingsProviderImpl @Inject constructor() :
SiteSettingsProvider {
override fun getSettings(site: SiteModel): SiteSettingsModel? {
val cursor = SiteSettingsTable.getSettings(site.id.toLong())
?: return null
return cursor.use {
if (it.moveToFirst()) {
SiteSettingsModel().also { model ->
model.deserializeOptionsDatabaseCursor(it, null)
}
} else {
null
}
}
}

override fun isBlockEditorDefault(site: SiteModel): Boolean {
val editor = site.mobileEditor
if (editor.isNullOrEmpty()) return true
val isWpComSimple = site.isWPCom && !site.isWPComAtomic
return isWpComSimple || editor == GUTENBERG_EDITOR_NAME
}

private companion object {
const val GUTENBERG_EDITOR_NAME = "gutenberg"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class SiteSettingsModel {
private static final String JETPACK_SEARCH_SUPPORTED_COLUMN_NAME = "jetpackSearchSupported";
private static final String JETPACK_SEARCH_ENABLED_COLUMN_NAME = "jetpackSearchEnabled";
private static final String USE_THEME_STYLES_COLUMN_NAME = "useThemeStyles";
private static final String USE_THIRD_PARTY_BLOCKS_COLUMN_NAME = "useThirdPartyBlocks";

public static final String SETTINGS_TABLE_NAME = "site_settings";

Expand Down Expand Up @@ -107,6 +108,9 @@ public class SiteSettingsModel {
+ " add " + SITE_ICON_COLUMN_NAME + " INTEGER;";
public static final String ADD_USE_THEME_STYLES = "alter table " + SETTINGS_TABLE_NAME
+ " add " + USE_THEME_STYLES_COLUMN_NAME + " BOOLEAN DEFAULT 1;";
public static final String ADD_USE_THIRD_PARTY_BLOCKS = "alter table " + SETTINGS_TABLE_NAME
+ " add " + USE_THIRD_PARTY_BLOCKS_COLUMN_NAME
+ " BOOLEAN DEFAULT 0;";

public static final String CREATE_SETTINGS_TABLE_SQL =
"CREATE TABLE IF NOT EXISTS "
Expand Down Expand Up @@ -198,6 +202,7 @@ public class SiteSettingsModel {
public boolean jetpackSearchSupported;
public boolean jetpackSearchEnabled;
public boolean useThemeStyles = true;
public boolean useThirdPartyBlocks;
public String quotaDiskSpace;

@Override
Expand Down Expand Up @@ -243,6 +248,7 @@ && equals(timezone, otherModel.timezone)
&& jetpackSearchEnabled == otherModel.jetpackSearchEnabled
&& jetpackSearchSupported == otherModel.jetpackSearchSupported
&& useThemeStyles == otherModel.useThemeStyles
&& useThirdPartyBlocks == otherModel.useThirdPartyBlocks
&& maxLinks == otherModel.maxLinks
&& equals(defaultPostFormat, otherModel.defaultPostFormat)
&& holdForModeration != null
Expand Down Expand Up @@ -309,6 +315,7 @@ public void copyFrom(SiteSettingsModel other) {
jetpackSearchSupported = other.jetpackSearchSupported;
jetpackSearchEnabled = other.jetpackSearchEnabled;
useThemeStyles = other.useThemeStyles;
useThirdPartyBlocks = other.useThirdPartyBlocks;
if (other.holdForModeration != null) {
holdForModeration = new ArrayList<>(other.holdForModeration);
}
Expand Down Expand Up @@ -374,6 +381,7 @@ public void deserializeOptionsDatabaseCursor(Cursor cursor, SparseArrayCompat<Ca
jetpackSearchSupported = getBooleanFromCursor(cursor, JETPACK_SEARCH_SUPPORTED_COLUMN_NAME);
jetpackSearchEnabled = getBooleanFromCursor(cursor, JETPACK_SEARCH_ENABLED_COLUMN_NAME);
useThemeStyles = getBooleanFromCursor(cursor, USE_THEME_STYLES_COLUMN_NAME);
useThirdPartyBlocks = getBooleanFromCursor(cursor, USE_THIRD_PARTY_BLOCKS_COLUMN_NAME);

String moderationKeys = getStringFromCursor(cursor, MODERATION_KEYS_COLUMN_NAME);
String denylistKeys = getStringFromCursor(cursor, DENYLIST_KEYS_COLUMN_NAME);
Expand Down Expand Up @@ -467,6 +475,7 @@ public ContentValues serializeToDatabase() {
values.put(JETPACK_SEARCH_SUPPORTED_COLUMN_NAME, jetpackSearchSupported);
values.put(JETPACK_SEARCH_ENABLED_COLUMN_NAME, jetpackSearchEnabled);
values.put(USE_THEME_STYLES_COLUMN_NAME, useThemeStyles);
values.put(USE_THIRD_PARTY_BLOCKS_COLUMN_NAME, useThirdPartyBlocks);

StringBuilder moderationKeys = new StringBuilder();
if (holdForModeration != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.wordpress.android.datasets.SiteSettingsProvider
import org.wordpress.android.datasets.SiteSettingsProviderImpl
import org.wordpress.android.ui.posts.IPostFreshnessChecker
import org.wordpress.android.ui.posts.PostFreshnessCheckerImpl
import javax.inject.Singleton
Expand All @@ -13,5 +15,12 @@ import javax.inject.Singleton
class PostModule {
@Singleton
@Provides
fun providePostFreshnessChecker(): IPostFreshnessChecker = PostFreshnessCheckerImpl()
fun providePostFreshnessChecker(): IPostFreshnessChecker =
PostFreshnessCheckerImpl()

@Singleton
@Provides
fun provideSiteSettingsProvider(
impl: SiteSettingsProviderImpl
): SiteSettingsProvider = impl
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.wordpress.android.repositories

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.withContext
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.fluxc.persistence.EditorSettingsSqlUtils
import org.wordpress.android.modules.IO_THREAD
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.AppLog.T
import rs.wordpress.api.kotlin.WpRequestResult
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton

@Singleton
class EditorSettingsRepository @Inject constructor(
private val wpApiClientProvider: WpApiClientProvider,
private val appPrefsWrapper: AppPrefsWrapper,
private val themeRepository: ThemeRepository,
@Named(IO_THREAD) private val ioDispatcher: CoroutineDispatcher
) {
private val editorSettingsSqlUtils = EditorSettingsSqlUtils()

/**
* Returns whether the site is known to support the
* `wp-block-editor/v1/settings` endpoint, based on
* cached editor settings or a previously persisted
* result from [fetchEditorCapabilitiesForSite].
*/
fun getSupportsEditorSettingsForSite(site: SiteModel): Boolean {
val hasExisting =
editorSettingsSqlUtils.getEditorSettingsForSite(site) != null
val cachedPref =
appPrefsWrapper.getSiteSupportsEditorSettings(site)
return hasExisting || cachedPref
}

/**
* Returns whether the site is known to support the
* `wpcom/v2/editor-assets` endpoint, based on a
* previously persisted result from
* [fetchEditorCapabilitiesForSite].
*/
fun getSupportsEditorAssetsForSite(
site: SiteModel
): Boolean =
appPrefsWrapper.getSiteSupportsEditorAssets(site)

/**
* Returns whether the site's active theme is a block
* theme, based on a previously persisted result from
* [fetchEditorCapabilitiesForSite].
*/
fun getThemeSupportsBlockStyles(
site: SiteModel
): Boolean =
appPrefsWrapper.getSiteThemeIsBlockTheme(site)

/**
* Queries the site's REST API to check whether the
* `wp-block-editor/v1/settings` and
* `wpcom/v2/editor-assets` routes are available,
* and fetches the current theme to determine if it
* is a block theme. All results are persisted so
* that [getSupportsEditorSettingsForSite],
* [getSupportsEditorAssetsForSite], and
* [getThemeSupportsBlockStyles] return them
* synchronously on future calls.
*/
suspend fun fetchEditorCapabilitiesForSite(
site: SiteModel
) = withContext(ioDispatcher) {
supervisorScope {
launch { fetchRouteSupport(site) }
launch { fetchThemeBlockStyleSupport(site) }
}
}

private suspend fun fetchRouteSupport(site: SiteModel) {
val client = wpApiClientProvider.getWpApiClient(site)
val response = client.request { it.apiRoot().get() }

when (response) {
is WpRequestResult.Success -> {
val data = response.response.data
val supportsSettings = data.hasRoute(
"/wp-block-editor/v1/settings"
)
val supportsAssets = data.hasRoute(
"/wpcom/v2/editor-assets"
)
appPrefsWrapper.setSiteSupportsEditorSettings(
site, supportsSettings
)
appPrefsWrapper.setSiteSupportsEditorAssets(
site, supportsAssets
)
}
else -> {
appPrefsWrapper.setSiteSupportsEditorSettings(
site, false
)
appPrefsWrapper.setSiteSupportsEditorAssets(
site, false
)
}
}
}

private suspend fun fetchThemeBlockStyleSupport(
site: SiteModel
) {
val theme = themeRepository.fetchCurrentTheme(site)
val isBlockTheme = theme?.isBlockTheme ?: false
AppLog.d(
T.EDITOR,
"EditorSettingsRepository: theme fetched" +
" for site=${site.name}" +
" themeName=${theme?.name}" +
" isBlockTheme=$isBlockTheme"
)
appPrefsWrapper.setSiteThemeIsBlockTheme(
site, isBlockTheme
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.wordpress.android.repositories

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider
import org.wordpress.android.modules.IO_THREAD
import rs.wordpress.api.kotlin.WpRequestResult
import uniffi.wp_api.ThemeListParams
import uniffi.wp_api.ThemeStatus
import uniffi.wp_api.ThemeWithEditContext
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton

@Singleton
class ThemeRepository @Inject constructor(
private val wpApiClientProvider: WpApiClientProvider,
@Named(IO_THREAD) private val ioDispatcher: CoroutineDispatcher
) {
/**
* Fetches the current active theme for the given site
* via the `wp/v2/themes?status=active` endpoint.
*/
suspend fun fetchCurrentTheme(site: SiteModel): ThemeWithEditContext? =
withContext(ioDispatcher) {
val client = wpApiClientProvider.getWpApiClient(site)
val response = client.request {
it.themes().listWithEditContext(ThemeListParams(
status = ThemeStatus.Active
))
}

when (response) {
is WpRequestResult.Success ->
response.response.data.firstOrNull()
else -> null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ object EditPostCustomerSupportHelper {
ActivityLauncher.viewHelp(context, EDITOR_HELP, site, getTagsList(site), experimentalFeatures)
}

@Suppress("DEPRECATION")
private fun getTagsList(site: SiteModel): List<String>? =
// Append the "mobile_gutenberg_is_default" tag if gutenberg is set to default for new posts
if (SiteUtils.isBlockEditorDefaultForNewPost(site)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class EditorLauncher @Inject constructor(
site: SiteModel
) {
val hasGutenbergBlocks = PostUtils.contentContainsGutenbergBlocks(postContent)
@Suppress("DEPRECATION")
val isBlockEditorDefaultForNewPosts = SiteUtils.isBlockEditorDefaultForNewPost(site)

val postInfo = if (post != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class GutenbergKitWarmupHelper @Inject constructor(
return false
}

@Suppress("DEPRECATION")
val shouldWarmup = SiteUtils.isBlockEditorDefaultForNewPost(site)

if (shouldWarmup) {
Expand Down
Loading
Loading