From 808ee939f5fc2f43ba3233434bf00c88ffed1107 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 12:37:04 +0100 Subject: [PATCH 01/59] feat: Add skeleton code VideoPress media processor The skeleton code for the VideoPress block's media processor has been added with this commit. Its functionality will be fleshed out in future commits. For now, it follows the same pattern as other block processors. The audio block was followed the most closely, given it was the newest processor at the time of writing: https://github.com/wordpress-mobile/WordPress-Android/blob/d609fa52b6c600da9c23f37f60053bbb79bb811b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/AudioBlockProcessor.kt --- .../BlockProcessorFactory.java | 2 ++ .../MediaBlockType.java | 1 + .../VideoPressBlockProcessor.kt | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java index f4e9058f87c9..463bb428090c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java @@ -12,6 +12,7 @@ import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.IMAGE; import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.MEDIA_TEXT; import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.VIDEO; +import static org.wordpress.android.ui.posts.mediauploadcompletionprocessors.MediaBlockType.VIDEOPRESS; class BlockProcessorFactory { private final MediaUploadCompletionProcessor mMediaUploadCompletionProcessor; @@ -34,6 +35,7 @@ class BlockProcessorFactory { */ BlockProcessorFactory init(String localId, MediaFile mediaFile, String siteUrl) { mMediaBlockTypeBlockProcessorMap.put(IMAGE, new ImageBlockProcessor(localId, mediaFile)); + mMediaBlockTypeBlockProcessorMap.put(VIDEOPRESS, new VideoPressBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(VIDEO, new VideoBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(MEDIA_TEXT, new MediaTextBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(GALLERY, new GalleryBlockProcessor(localId, mediaFile, siteUrl, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java index e5eefff16d05..f89870f5bbc0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/MediaBlockType.java @@ -12,6 +12,7 @@ enum MediaBlockType { IMAGE("image"), + VIDEOPRESS("videopress/video"), VIDEO("video"), MEDIA_TEXT("media-text"), GALLERY("gallery"), diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt new file mode 100644 index 000000000000..f6cc72abd401 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -0,0 +1,35 @@ +package org.wordpress.android.ui.posts.mediauploadcompletionprocessors + +import com.google.gson.JsonObject +import org.jsoup.nodes.Document +import org.wordpress.android.util.helpers.MediaFile + +class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockProcessor(localId, mediaFile) { + override fun processBlockContentDocument(document: Document?): Boolean { + val videoPressElements = document?.select("figure") + + if (videoPressElements != null) { + // Functionality for populating the block's content will go here. + } + + return false + } + + override fun processBlockJsonAttributes(jsonAttributes: JsonObject?): Boolean { + val id = jsonAttributes?.get(ID_ATTRIBUTE) + + return if (id != null && !id.isJsonNull && id.asString == mLocalId) { + jsonAttributes.apply { + addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) + // Functionality for populating the block's attributes will go here. + } + true + } else { + false + } + } + + companion object { + const val ID_ATTRIBUTE = "id" + } +} From c7358325e3a843a6fd629b0c56b2b31929dc5cdf Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 12:40:39 +0100 Subject: [PATCH 02/59] feat: Add GUID to block's attributes --- .../posts/mediauploadcompletionprocessors/BlockProcessor.java | 2 ++ .../VideoPressBlockProcessor.kt | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessor.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessor.java index 21dba8597cc6..79d28b122706 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessor.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessor.java @@ -30,6 +30,7 @@ public abstract class BlockProcessor { String mLocalId; String mRemoteId; String mRemoteUrl; + String mRemoteGuid; private String mBlockName; private JsonObject mJsonAttributes; @@ -46,6 +47,7 @@ public abstract class BlockProcessor { mRemoteId = mediaFile.getMediaId(); mRemoteUrl = org.wordpress.android.util.StringUtils.notNullStr(Utils.escapeQuotes(mediaFile .getOptimalFileURL())); + mRemoteGuid = mediaFile.getVideoPressGuid(); } private JsonObject parseJson(String blockJson) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index f6cc72abd401..17e696105e6e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -21,7 +21,7 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP return if (id != null && !id.isJsonNull && id.asString == mLocalId) { jsonAttributes.apply { addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) - // Functionality for populating the block's attributes will go here. + addProperty(GUID_ATTRIBUTE, mRemoteGuid) } true } else { @@ -31,5 +31,6 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP companion object { const val ID_ATTRIBUTE = "id" + const val GUID_ATTRIBUTE = "guid" } } From 043cdacc0628fbd62968f91427b9db7a10134a3a Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 12:44:36 +0100 Subject: [PATCH 03/59] feat: Use attributes to define/update settings The block's settings may differ from the defaults. We'll need to detect this in order to populate the block's content. As such, we'll define a class and use the information we get from the block's attributes to update the settings. --- .../VideoPressBlockProcessor.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 17e696105e6e..ff30a6e09e34 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -5,6 +5,39 @@ import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockProcessor(localId, mediaFile) { + class VideoPressBlockSettings( + var autoplay: Boolean? = null, + var controls: Boolean? = null, + var loop: Boolean? = null, + var muted: Boolean? = null, + var persistVolume: Boolean? = null, + var playsinline: Boolean? = null, + var poster: String? = null, + var preload: String? = null, + var seekbarColor: String? = null, + var seekbarPlayedColor: String? = null, + var seekbarLoadingColor: String? = null, + var useAverageColor: Boolean? = null + ) { + constructor(jsonAttributes: JsonObject) : this() { + autoplay = jsonAttributes["autoplay"]?.asBoolean ?: false + controls = jsonAttributes["controls"]?.asBoolean ?: true + loop = jsonAttributes["loop"]?.asBoolean ?: false + jsonAttributes["muted"]?.asBoolean?.let { isMuted -> + muted = isMuted + persistVolume = !isMuted + } + poster = jsonAttributes["poster"]?.toString() + preload = jsonAttributes["preload"]?.toString() ?: "metadata" + seekbarColor = jsonAttributes["seekbarColor"]?.toString() + seekbarPlayedColor = jsonAttributes["seekbarPlayedColor"]?.toString() + seekbarLoadingColor = jsonAttributes["seekbarLoadingColor"]?.toString() + useAverageColor = jsonAttributes["useAverageColor"]?.asBoolean ?: true + } + } + + private var mBlockSettings = VideoPressBlockSettings() + override fun processBlockContentDocument(document: Document?): Boolean { val videoPressElements = document?.select("figure") @@ -23,6 +56,9 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) addProperty(GUID_ATTRIBUTE, mRemoteGuid) } + + mBlockSettings = VideoPressBlockSettings(jsonAttributes) + true } else { false From bf4029087ce4818f15ac20f50025aa0f72074934 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 12:45:20 +0100 Subject: [PATCH 04/59] feat: Populate block's content, including URL --- .../VideoPressBlockProcessor.kt | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index ff30a6e09e34..c5d195719685 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors +import android.net.Uri import com.google.gson.JsonObject import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile @@ -38,11 +39,53 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP private var mBlockSettings = VideoPressBlockSettings() + /** + * Build VideoPress URL based on the values of the block's various settings. + * In order to have a cleaner URL, only the options differing from the default settings are added. + * + * Turned OFF by default: Autoplay, Loop, Muted, Plays Inline + * Turned ON by default: Controls, UseAverageColor + * No values by default: Poster, SeekbarColor, SeekbarPlayerColor, SeekbarLoadingColor + * Set to "metadata" by default: Preload + * + * Matches logic in Jetpack. + * Ref: https://github.com/Automattic/jetpack/blob/b1b826ab38690c5fad18789301ac81297a458878/projects/packages/videopress/src/client/lib/url/index.ts#L19-L67 + */ + fun getVideoPressURL(guid: String): String { + // Add default options. + val queryArgs = mutableMapOf( + "resizeToParent" to "true", + "cover" to "true" + ) + + with(mBlockSettings) { + autoplay?.let { if (it) queryArgs["autoPlay"] = "true" } + controls?.let { if (!it) queryArgs["controls"] = "false" } + loop?.let { if (it) queryArgs["loop"] = "true" } + muted?.let { if (it) { queryArgs["muted"] = "true"; queryArgs["persistVolume"] = "false" } } + playsinline?.let { if (it) queryArgs["playsinline"] = "true" } + poster?.let { queryArgs["posterUrl"] = it } + preload?.let { if (it.isNotEmpty()) queryArgs["preloadContent"] = it } + seekbarColor?.let { if (it.isNotEmpty()) queryArgs["sbc"] = it } + seekbarPlayedColor?.let { if (it.isNotEmpty()) queryArgs["sbpc"] = it } + seekbarLoadingColor?.let { if (it.isNotEmpty()) queryArgs["sblc"] = it } + useAverageColor?.let { if (it) queryArgs["useAverageColor"] = "true" } + } + + val encodedQueryArgs = queryArgs.entries.joinToString("&") { + "${Uri.encode(it.key)}=${Uri.encode(it.value)}" + } + + return "https://videopress.com/v/$guid?$encodedQueryArgs" + } + override fun processBlockContentDocument(document: Document?): Boolean { val videoPressElements = document?.select("figure") if (videoPressElements != null) { - // Functionality for populating the block's content will go here. + val url = getVideoPressURL(mRemoteGuid) + videoPressElements.append("
$url
") + return true } return false From 9b9b72cc43e3b17a0c2068da9b78ba6299f648d9 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 13:23:22 +0100 Subject: [PATCH 05/59] refactor: Split getVideoPressURL to smaller funcs The code previously failed linting checks with the following error: > The function getVideoPressURL appears to be too complex (23). Defined complexity threshold for methods is set to '15' [ComplexMethod] As such, this commit refactors that function and seeks to reduce its complexity by splitting it into smaller, more readable functions. --- .../VideoPressBlockProcessor.kt | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index c5d195719685..fd0de23be255 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -41,6 +41,27 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP /** * Build VideoPress URL based on the values of the block's various settings. + * + */ + fun getVideoPressURL(guid: String): String { + val queryArgs = getDefaultQueryArgs() + getBlockSettingsQueryArgs(queryArgs, mBlockSettings) + + val encodedQueryArgs = queryArgs.entries.joinToString("&") { + "${Uri.encode(it.key)}=${Uri.encode(it.value)}" + } + + return "https://videopress.com/v/$guid?$encodedQueryArgs" + } + + private fun getDefaultQueryArgs(): MutableMap { + return mutableMapOf( + "resizeToParent" to "true", + "cover" to "true" + ) + } + + /** * In order to have a cleaner URL, only the options differing from the default settings are added. * * Turned OFF by default: Autoplay, Loop, Muted, Plays Inline @@ -50,19 +71,21 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP * * Matches logic in Jetpack. * Ref: https://github.com/Automattic/jetpack/blob/b1b826ab38690c5fad18789301ac81297a458878/projects/packages/videopress/src/client/lib/url/index.ts#L19-L67 + * */ - fun getVideoPressURL(guid: String): String { - // Add default options. - val queryArgs = mutableMapOf( - "resizeToParent" to "true", - "cover" to "true" - ) - - with(mBlockSettings) { + private fun getBlockSettingsQueryArgs( + queryArgs: MutableMap, + blockSettings: VideoPressBlockSettings + ) { + with(blockSettings) { autoplay?.let { if (it) queryArgs["autoPlay"] = "true" } controls?.let { if (!it) queryArgs["controls"] = "false" } loop?.let { if (it) queryArgs["loop"] = "true" } - muted?.let { if (it) { queryArgs["muted"] = "true"; queryArgs["persistVolume"] = "false" } } + muted?.let { + if (it) { + queryArgs["muted"] = "true"; queryArgs["persistVolume"] = "false" + } + } playsinline?.let { if (it) queryArgs["playsinline"] = "true" } poster?.let { queryArgs["posterUrl"] = it } preload?.let { if (it.isNotEmpty()) queryArgs["preloadContent"] = it } @@ -71,12 +94,6 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP seekbarLoadingColor?.let { if (it.isNotEmpty()) queryArgs["sblc"] = it } useAverageColor?.let { if (it) queryArgs["useAverageColor"] = "true" } } - - val encodedQueryArgs = queryArgs.entries.joinToString("&") { - "${Uri.encode(it.key)}=${Uri.encode(it.value)}" - } - - return "https://videopress.com/v/$guid?$encodedQueryArgs" } override fun processBlockContentDocument(document: Document?): Boolean { From e265f545ff5a6fcab5fd6b18defc90e86ce0349d Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 16:08:11 +0100 Subject: [PATCH 06/59] refactor: Further simplify logic for building URL Following the last commit, the linting checks still indicated that the logic for building the VideoPress URL was too complex. As such, this commit further simplifies the functionality by splitting each individual setting into its own function. This now matches the approach taken in the iOS PR here: https://github.com/wordpress-mobile/WordPress-iOS/pull/20380/ --- .../VideoPressBlockProcessor.kt | 109 +++++++++++++----- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index fd0de23be255..a16a8f11a9e1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -41,6 +41,9 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP /** * Build VideoPress URL based on the values of the block's various settings. + * In order to have a cleaner URL, only the options differing from the default settings are added. + * Matches logic in Jetpack. + * Ref: https://github.com/Automattic/jetpack/blob/b1b826ab38690c5fad18789301ac81297a458878/projects/packages/videopress/src/client/lib/url/index.ts#L19-L67 * */ fun getVideoPressURL(guid: String): String { @@ -61,38 +64,90 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP ) } - /** - * In order to have a cleaner URL, only the options differing from the default settings are added. - * - * Turned OFF by default: Autoplay, Loop, Muted, Plays Inline - * Turned ON by default: Controls, UseAverageColor - * No values by default: Poster, SeekbarColor, SeekbarPlayerColor, SeekbarLoadingColor - * Set to "metadata" by default: Preload - * - * Matches logic in Jetpack. - * Ref: https://github.com/Automattic/jetpack/blob/b1b826ab38690c5fad18789301ac81297a458878/projects/packages/videopress/src/client/lib/url/index.ts#L19-L67 - * - */ private fun getBlockSettingsQueryArgs( queryArgs: MutableMap, blockSettings: VideoPressBlockSettings ) { with(blockSettings) { - autoplay?.let { if (it) queryArgs["autoPlay"] = "true" } - controls?.let { if (!it) queryArgs["controls"] = "false" } - loop?.let { if (it) queryArgs["loop"] = "true" } - muted?.let { - if (it) { - queryArgs["muted"] = "true"; queryArgs["persistVolume"] = "false" - } - } - playsinline?.let { if (it) queryArgs["playsinline"] = "true" } - poster?.let { queryArgs["posterUrl"] = it } - preload?.let { if (it.isNotEmpty()) queryArgs["preloadContent"] = it } - seekbarColor?.let { if (it.isNotEmpty()) queryArgs["sbc"] = it } - seekbarPlayedColor?.let { if (it.isNotEmpty()) queryArgs["sbpc"] = it } - seekbarLoadingColor?.let { if (it.isNotEmpty()) queryArgs["sblc"] = it } - useAverageColor?.let { if (it) queryArgs["useAverageColor"] = "true" } + addAutoplayArg(queryArgs, autoplay) + addControlsArg(queryArgs, controls) + addLoopArg(queryArgs, loop) + addMutedAndPersistVolumeArgs(queryArgs, muted) + addPlaysinlineArg(queryArgs, playsinline) + addPosterArg(queryArgs, poster) + addPreloadArg(queryArgs, preload) + addSeekbarArgs(queryArgs, seekbarColor, seekbarPlayedColor, seekbarLoadingColor) + addUseAverageColorArg(queryArgs, useAverageColor) + } + } + + // Adds AutoPlay option. Turned OFF by default. + private fun addAutoplayArg(queryArgs: MutableMap, autoplay: Boolean?) { + if (autoplay == true) { + queryArgs["autoPlay"] = "true" + } + } + + // Adds Controls option. Turned ON by default. + private fun addControlsArg(queryArgs: MutableMap, controls: Boolean?) { + if (controls == false) { + queryArgs["controls"] = "false" + } + } + + // Adds Loops option. Turned OFF by default. + private fun addLoopArg(queryArgs: MutableMap, loop: Boolean?) { + if (loop == true) { + queryArgs["loop"] = "true" + } + } + + // Adds Volume-related options. Muted: Turned OFF by default. + private fun addMutedAndPersistVolumeArgs(queryArgs: MutableMap, muted: Boolean?) { + if (muted == true) { + queryArgs["muted"] = "true" + queryArgs["persistVolume"] = "false" + } + } + + // Adds PlaysInline option. Turned OFF by default. + private fun addPlaysinlineArg(queryArgs: MutableMap, playsinline: Boolean?) { + if (playsinline == true) { + queryArgs["playsinline"] = "true" + } + } + + // Adds Poster option. No image by default. + private fun addPosterArg(queryArgs: MutableMap, poster: String?) { + poster?.let { queryArgs["posterUrl"] = it } + } + + // Adds Preload option. Metadata by default. + private fun addPreloadArg(queryArgs: MutableMap, preload: String?) { + preload?.let { if (it.isNotEmpty()) queryArgs["preloadContent"] = it } + } + + /** + * Adds Seekbar options. + * - SeekbarColor: No color by default. + * - SeekbarPlayerColor: No color by default. + * - SeekbarLoadingColor: No color by default. + */ + private fun addSeekbarArgs( + queryArgs: MutableMap, + seekbarColor: String?, + seekbarPlayedColor: String?, + seekbarLoadingColor: String? + ) { + seekbarColor?.let { if (it.isNotEmpty()) queryArgs["sbc"] = it } + seekbarPlayedColor?.let { if (it.isNotEmpty()) queryArgs["sbpc"] = it } + seekbarLoadingColor?.let { if (it.isNotEmpty()) queryArgs["sblc"] = it } + } + + // Adds UseAverageColor option. Turned ON by default. + private fun addUseAverageColorArg(queryArgs: MutableMap, useAverageColor: Boolean?) { + if (useAverageColor == true) { + queryArgs["useAverageColor"] = "true" } } From 06ddf402d6398808930f8d3933d4d821a6e737a5 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 15 Mar 2023 19:14:12 +0100 Subject: [PATCH 07/59] Add perform post request --- .../android/ui/posts/EditPostActivity.java | 11 +++++++++++ .../reactnative/ReactNativeRequestHandler.kt | 15 ++++++++++++++- .../android/editor/EditorFragmentAbstract.java | 1 + .../editor/gutenberg/GutenbergEditorFragment.java | 14 +++++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 8a1d9d389dfd..043c13901e03 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -3135,6 +3135,17 @@ public void onAddFileClicked(boolean allowMultipleSelection) { } } + @Override public void onPerformPost( + String path, + Map body, + Consumer onResult, + Consumer onError + ) { + if (mSite != null) { + mReactNativeRequestHandler.performPostRequest(path, body, mSite, onResult, onError); + } + } + @Override public void onCaptureVideoClicked() { onPhotoPickerIconClicked(PhotoPickerIcon.ANDROID_CAPTURE_VIDEO, false); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/reactnative/ReactNativeRequestHandler.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/reactnative/ReactNativeRequestHandler.kt index 446bdb0f63c4..f39fb91a6a16 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/reactnative/ReactNativeRequestHandler.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/reactnative/ReactNativeRequestHandler.kt @@ -31,7 +31,20 @@ class ReactNativeRequestHandler @Inject constructor( onError: Consumer ) { launch { - val response = reactNativeStore.executeRequest(mSite, pathWithParams, enableCaching) + val response = reactNativeStore.executeGetRequest(mSite, pathWithParams, enableCaching) + handleResponse(response, onSuccess::accept, onError::accept) + } + } + + fun performPostRequest( + pathWithParams: String, + body: Map, + mSite: SiteModel, + onSuccess: Consumer, + onError: Consumer + ) { + launch { + val response = reactNativeStore.executePostRequest(mSite, pathWithParams, body) handleResponse(response, onSuccess::accept, onError::accept) } } diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java b/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java index 09dedc9b30fb..6ccb1aaf0218 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/EditorFragmentAbstract.java @@ -208,6 +208,7 @@ public interface EditorFragmentListener extends DialogVisibilityProvider { void onAddFileClicked(boolean allowMultipleSelection); void onAddAudioFileClicked(boolean allowMultipleSelection); void onPerformFetch(String path, boolean enableCaching, Consumer onResult, Consumer onError); + void onPerformPost(String path, Map body, Consumer onResult, Consumer onError); void showUserSuggestions(Consumer onResult); void showXpostSuggestions(Consumer onResult); void onGutenbergEditorSetFocalPointPickerTooltipShown(boolean tooltipShown); diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index f1a0b1c7d8b4..288fea095701 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -32,6 +32,7 @@ import androidx.lifecycle.LiveData; import com.android.volley.toolbox.ImageLoader; +import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableNativeMap; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.gson.Gson; @@ -61,6 +62,7 @@ import org.wordpress.aztec.IHistoryListener; import org.wordpress.mobile.WPAndroidGlue.Media; import org.wordpress.mobile.WPAndroidGlue.MediaOption; +import org.wordpress.mobile.WPAndroidGlue.RequestExecutor; import org.wordpress.mobile.WPAndroidGlue.ShowSuggestionsUtil; import org.wordpress.mobile.WPAndroidGlue.UnsupportedBlock; import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnBlockTypeImpressionsEventListener; @@ -397,7 +399,17 @@ public void run() { }, mTextWatcher::postTextChanged, mEditorFragmentListener::onAuthHeaderRequested, - mEditorFragmentListener::onPerformFetch, + new RequestExecutor() { + @Override + public void performGetRequest(String path, boolean enableCaching, Consumer onSuccess, + Consumer onError) { + mEditorFragmentListener.onPerformFetch(path, enableCaching, onSuccess, onError); + } + @Override + public void performPostRequest(String path, ReadableMap data, Consumer onSuccess, Consumer onError) { + mEditorFragmentListener.onPerformPost(path, data.toHashMap(), onSuccess, onError); + } + }, mEditorImagePreviewListener::onImagePreviewRequested, mEditorEditMediaListener::onMediaEditorRequested, new OnGutenbergDidRequestUnsupportedBlockFallbackListener() { From 17262e6253207abea36359060cd71dacac44f52f Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 28 Mar 2023 16:29:00 +0200 Subject: [PATCH 08/59] Fix checkstyle issue --- .../android/editor/gutenberg/GutenbergEditorFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java index 288fea095701..9494980db126 100644 --- a/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java +++ b/libs/editor/src/main/java/org/wordpress/android/editor/gutenberg/GutenbergEditorFragment.java @@ -406,7 +406,11 @@ public void performGetRequest(String path, boolean enableCaching, Consumer onSuccess, Consumer onError) { + public void performPostRequest( + String path, + ReadableMap data, + Consumer onSuccess, + Consumer onError) { mEditorFragmentListener.onPerformPost(path, data.toHashMap(), onSuccess, onError); } }, From cf88c0c0a7312b813d06da47566899de675f6449 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 27 Mar 2023 17:33:32 +0200 Subject: [PATCH 09/59] Update Gutenberg Mobile reference --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 14d3c71836f5..1cacd1d8eacb 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ ext { automatticRestVersion = '1.0.8' automatticStoriesVersion = '2.0.0' automatticTracksVersion = '2.2.0' - gutenbergMobileVersion = 'v1.92.0-alpha1' + gutenbergMobileVersion = '5596-bd043a0d71a20f565c76bd10122d0c44db92c851' wordPressAztecVersion = 'v1.6.3' wordPressFluxCVersion = 'trunk-fcede535112327abf59416b7b544cf526c44fd00' wordPressLoginVersion = '1.0.0' From 0c9ad1bcecd1fddc89b672788c3cdd3a329498f7 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 28 Mar 2023 17:20:14 +0200 Subject: [PATCH 10/59] Bump FluxC library reference --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1cacd1d8eacb..d2673380f02b 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { automatticTracksVersion = '2.2.0' gutenbergMobileVersion = '5596-bd043a0d71a20f565c76bd10122d0c44db92c851' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = 'trunk-fcede535112327abf59416b7b544cf526c44fd00' + wordPressFluxCVersion = '2691-a3bac6077768944a3e79a6a1eb4c7c22dd2e1183' wordPressLoginVersion = '1.0.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From 91cc0bdd7f5352bb0c04e51ef38d4ecd3bdbb843 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 16:40:20 +0100 Subject: [PATCH 11/59] test: video processor doesn't impact VideoPress --- .../VideoBlockProcessorTest.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoBlockProcessorTest.kt index 0ca83416b29c..3d7b9ae35307 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoBlockProcessorTest.kt @@ -29,4 +29,12 @@ class VideoBlockProcessorTest { val processedBlock = processor.processBlock(TestContent.oldVideoBlockIdNotFirst) Assertions.assertThat(processedBlock).isEqualTo(TestContent.newVideoBlockIdNotFirst) } + + @Test + fun `processBlock leaves VideoPress block unchanged`() { + val nonMatchingId = "123" + val processor = VideoPressBlockProcessor(nonMatchingId, mediaFile) + val processedBlock = processor.processBlock(TestContent.oldVideoPressBlockWithDefaultAttrs) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.oldVideoPressBlockWithDefaultAttrs) + } } From ec71ddbe594d64720f1dc371367204b9abba4af6 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 17:19:29 +0100 Subject: [PATCH 12/59] test: VP processor doesn't impact video block In this commit, a "VideoPressBlockProcessorTest.kt" file has been created, with its first test. The test confirms that the video block remains unchanged when the VideoPress processor runs. --- .../TestContent.kt | 1 + .../VideoPressBlockProcessorTest.kt | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt index c1b5d730cd37..90a6d2c4ce2a 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt @@ -30,6 +30,7 @@ object TestContent { const val remoteMediaId = "97629" const val remoteMediaId2 = "97630" const val attachmentPageUrl = "https://wordpress.org?p=${remoteMediaId}" + const val videoPressGuid = "AbCdE" const val oldImageBlock = """
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt new file mode 100644 index 000000000000..03e8a8c65f3c --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -0,0 +1,27 @@ +package org.wordpress.android.ui.posts.mediauploadcompletionprocessors + +import org.assertj.core.api.Assertions +import org.junit.Before +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.wordpress.android.util.helpers.MediaFile + +class VideoPressBlockProcessorTest { + private val mediaFile: MediaFile = mock() + private lateinit var processor: VideoPressBlockProcessor + + @Before + fun before() { + whenever(mediaFile.mediaId).thenReturn(TestContent.remoteMediaId) + whenever(mediaFile.videoPressGuid).thenReturn(TestContent.videoPressGuid) + processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile) + } + @Test + fun `processBlock leaves Video block unchanged`() { + val nonMatchingId = "123" + val processor = VideoPressBlockProcessor(nonMatchingId, mediaFile) + val processedBlock = processor.processBlock(TestContent.oldVideoBlock) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.oldVideoBlock) + } +} From 17ec90ae1104301662907baae23e1bfbe72365f8 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 28 Mar 2023 18:20:24 +0200 Subject: [PATCH 13/59] Update Gutenberg Mobile reference --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d2673380f02b..aa0a7b2f2702 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ ext { automatticRestVersion = '1.0.8' automatticStoriesVersion = '2.0.0' automatticTracksVersion = '2.2.0' - gutenbergMobileVersion = '5596-bd043a0d71a20f565c76bd10122d0c44db92c851' + gutenbergMobileVersion = '5596-5a7826bee6a11d22a2a96703009afb1b2c47fba2' wordPressAztecVersion = 'v1.6.3' wordPressFluxCVersion = '2691-a3bac6077768944a3e79a6a1eb4c7c22dd2e1183' wordPressLoginVersion = '1.0.0' From 5ea8a976c43c9f8f32dff29b11024785784682bc Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 17:25:56 +0100 Subject: [PATCH 14/59] fix: Enable unit tests to mock URL The Android-specific Uri class for encoding query parameters doesn't work with unit tests. As such, it's been replaced with the java.net.URLEncoder class with this commit. As the URLEncoder class isn't supported on versions of Android lower than 13 (and the app still officially supports versions down to Android 7), conditional logic is used to incorporate both. --- .../VideoPressBlockProcessor.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index a16a8f11a9e1..6db812c5a858 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -1,9 +1,12 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors import android.net.Uri +import android.os.Build import com.google.gson.JsonObject import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile +import java.net.URLEncoder +import java.nio.charset.StandardCharsets class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockProcessor(localId, mediaFile) { class VideoPressBlockSettings( @@ -51,7 +54,11 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP getBlockSettingsQueryArgs(queryArgs, mBlockSettings) val encodedQueryArgs = queryArgs.entries.joinToString("&") { - "${Uri.encode(it.key)}=${Uri.encode(it.value)}" + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + "${URLEncoder.encode(it.key, StandardCharsets.UTF_8)}=${URLEncoder.encode(it.value, StandardCharsets.UTF_8)}" + } else { + "${Uri.encode(it.key)}=${Uri.encode(it.value)}" + } } return "https://videopress.com/v/$guid?$encodedQueryArgs" From f36eb72bd561f93fed04a66340a0c9ae3b2b8dd0 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 17:26:39 +0100 Subject: [PATCH 15/59] test: process default VideoPress block --- .../posts/mediauploadcompletionprocessors/TestContent.kt | 8 ++++++++ .../VideoPressBlockProcessorTest.kt | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt index 90a6d2c4ce2a..23590120b9cb 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt @@ -660,6 +660,14 @@ $newRefactoredGalleryBlockInnerBlocks
""" + const val oldVideoPressBlockWithDefaultAttrs = """ +
+""" + + const val newVideoPressBlockWithDefaultAttrs = """ +
https://videopress.com/v/${videoPressGuid}?resizeToParent=true&cover=true&preloadContent=metadata&useAverageColor=true
+""" + const val oldPostImage = paragraphBlock + oldImageBlock + newVideoBlock + newMediaTextBlock + newGalleryBlock const val newPostImage = paragraphBlock + newImageBlock + newVideoBlock + newMediaTextBlock + newGalleryBlock const val oldPostVideo = paragraphBlock + newImageBlock + oldVideoBlock + newMediaTextBlock + newGalleryBlock diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt index 03e8a8c65f3c..5afe8f7a5af2 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -17,6 +17,13 @@ class VideoPressBlockProcessorTest { whenever(mediaFile.videoPressGuid).thenReturn(TestContent.videoPressGuid) processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile) } + + @Test + fun `processBlock replaces id and contents in VideoPress block with default attributes`() { + val processedBlock = processor.processBlock(TestContent.oldVideoPressBlockWithDefaultAttrs) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.newVideoPressBlockWithDefaultAttrs) + } + @Test fun `processBlock leaves Video block unchanged`() { val nonMatchingId = "123" From dd8c9947026ec221aea7b488e60f0f8d65cb14f9 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 18:22:44 +0100 Subject: [PATCH 16/59] fix: Add missing setting The 'playsinline' setting was not being correctly added to the VideoPress URL when set, due to it being missing from the class. This commit fixes that mistake. --- .../mediauploadcompletionprocessors/VideoPressBlockProcessor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 6db812c5a858..e6687770ca5f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -31,6 +31,7 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP muted = isMuted persistVolume = !isMuted } + playsinline = jsonAttributes["playsinline"]?.asBoolean ?: false poster = jsonAttributes["poster"]?.toString() preload = jsonAttributes["preload"]?.toString() ?: "metadata" seekbarColor = jsonAttributes["seekbarColor"]?.toString() From 4083c4d233659ae46c818d890cb24fe8cc31625b Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 18:25:23 +0100 Subject: [PATCH 17/59] test: process VP block with non-default settings --- .../posts/mediauploadcompletionprocessors/TestContent.kt | 8 ++++++++ .../VideoPressBlockProcessorTest.kt | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt index 23590120b9cb..2370850c584c 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/TestContent.kt @@ -666,6 +666,14 @@ $newRefactoredGalleryBlockInnerBlocks const val newVideoPressBlockWithDefaultAttrs = """
https://videopress.com/v/${videoPressGuid}?resizeToParent=true&cover=true&preloadContent=metadata&useAverageColor=true
+""" + + const val oldVideoPressBlockWithAttrs = """ +
+""" + + const val newVideoPressBlockWithAttrs = """ +
https://videopress.com/v/AbCdE?resizeToParent=true&cover=true&autoPlay=true&controls=false&loop=true&muted=true&persistVolume=false&playsinline=true&posterUrl=https%3A%2F%2Ftest.files.wordpress.com%2F2022%2F02%2F265-5000x5000-1.jpeg&preloadContent=none&sbc=%23abb8c3&sbpc=%239b51e0&sblc=%23cf2e2e
""" const val oldPostImage = paragraphBlock + oldImageBlock + newVideoBlock + newMediaTextBlock + newGalleryBlock diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt index 5afe8f7a5af2..3004503fb10b 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -24,6 +24,12 @@ class VideoPressBlockProcessorTest { Assertions.assertThat(processedBlock).isEqualTo(TestContent.newVideoPressBlockWithDefaultAttrs) } + @Test + fun `processBlock replaces id and contents in VideoPress block with different attributes to the default`() { + val processedBlock = processor.processBlock(TestContent.oldVideoPressBlockWithAttrs) + Assertions.assertThat(processedBlock).isEqualTo(TestContent.newVideoPressBlockWithAttrs) + } + @Test fun `processBlock leaves Video block unchanged`() { val nonMatchingId = "123" From c52bced2391004f146060b693d6908ef0564fe7b Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 22:41:20 +0100 Subject: [PATCH 18/59] refactor: Signify code that requests SDK S --- .../VideoPressBlockProcessor.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index e6687770ca5f..3646b3bd9fe7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -2,6 +2,7 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors import android.net.Uri import android.os.Build +import androidx.annotation.RequiresApi import com.google.gson.JsonObject import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile @@ -55,16 +56,25 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP getBlockSettingsQueryArgs(queryArgs, mBlockSettings) val encodedQueryArgs = queryArgs.entries.joinToString("&") { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - "${URLEncoder.encode(it.key, StandardCharsets.UTF_8)}=${URLEncoder.encode(it.value, StandardCharsets.UTF_8)}" + if (Build.VERSION.SDK_INT >= 33) { + encodeQueryArgsSdkSAndAbove(it.key, it.value) } else { - "${Uri.encode(it.key)}=${Uri.encode(it.value)}" + encodeQueryArgsBelowSdkS(it.key, it.value) } } return "https://videopress.com/v/$guid?$encodedQueryArgs" } + @RequiresApi(33) + private fun encodeQueryArgsSdkSAndAbove(key: String, value: String): String { + return "${URLEncoder.encode(key, StandardCharsets.UTF_8)}=${URLEncoder.encode(value, StandardCharsets.UTF_8)}" + } + + private fun encodeQueryArgsBelowSdkS(key: String, value: String): String { + return "${Uri.encode(key)}=${Uri.encode(value)}" + } + private fun getDefaultQueryArgs(): MutableMap { return mutableMapOf( "resizeToParent" to "true", From eb645e57a9d656bb622a0de1810e4faf9b6318e5 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 22:42:04 +0100 Subject: [PATCH 19/59] refactor: Follow lint recs to set funcs to private --- .../VideoPressBlockProcessor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 3646b3bd9fe7..a22a64ca7110 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -15,7 +15,7 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP var controls: Boolean? = null, var loop: Boolean? = null, var muted: Boolean? = null, - var persistVolume: Boolean? = null, + private var persistVolume: Boolean? = null, var playsinline: Boolean? = null, var poster: String? = null, var preload: String? = null, @@ -51,7 +51,7 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP * Ref: https://github.com/Automattic/jetpack/blob/b1b826ab38690c5fad18789301ac81297a458878/projects/packages/videopress/src/client/lib/url/index.ts#L19-L67 * */ - fun getVideoPressURL(guid: String): String { + private fun getVideoPressURL(guid: String): String { val queryArgs = getDefaultQueryArgs() getBlockSettingsQueryArgs(queryArgs, mBlockSettings) From 2b68a5761c1bf4fdc422092364360545bbdd283e Mon Sep 17 00:00:00 2001 From: Siobhan Date: Tue, 28 Mar 2023 22:44:23 +0100 Subject: [PATCH 20/59] fix: Ensure encoded quotes are removed from URL --- .../mediauploadcompletionprocessors/VideoPressBlockProcessor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index a22a64ca7110..ce7ad29fd634 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -57,7 +57,7 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP val encodedQueryArgs = queryArgs.entries.joinToString("&") { if (Build.VERSION.SDK_INT >= 33) { - encodeQueryArgsSdkSAndAbove(it.key, it.value) + encodeQueryArgsSdkSAndAbove(it.key, it.value).replace("%23", "") } else { encodeQueryArgsBelowSdkS(it.key, it.value) } From 9e6713f10a1372264f06fac65bd5e79db61d6d3f Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 29 Mar 2023 17:31:59 +0200 Subject: [PATCH 21/59] Update Gutenberg Mobile reference --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa0a7b2f2702..aaca6df235b3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ ext { automatticRestVersion = '1.0.8' automatticStoriesVersion = '2.0.0' automatticTracksVersion = '2.2.0' - gutenbergMobileVersion = '5596-5a7826bee6a11d22a2a96703009afb1b2c47fba2' + gutenbergMobileVersion = '5596-966b12f8bd5fd7c35fb3ef499566451bfb6a2463' wordPressAztecVersion = 'v1.6.3' wordPressFluxCVersion = '2691-a3bac6077768944a3e79a6a1eb4c7c22dd2e1183' wordPressLoginVersion = '1.0.0' From a05ac2bc40a5bef4c5136387870a4eb88438b6e9 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Wed, 29 Mar 2023 17:57:28 +0100 Subject: [PATCH 22/59] refactor: Move encode func to wrapper for testing With this commit, a wrapper has been added for the Uri class, so that we can easily reference the encode functionality in our unit tests. We also discard the usage of URLEncoder.encode for devices with API 33 or above, for simplicity. Uri.encode will work with all APIs. --- .../BlockProcessorFactory.java | 4 +++- .../UriWrapper.kt | 18 ++++++++++++++++++ .../VideoPressBlockProcessor.kt | 19 +++---------------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java index 463bb428090c..cdf94386f7e8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java @@ -17,6 +17,7 @@ class BlockProcessorFactory { private final MediaUploadCompletionProcessor mMediaUploadCompletionProcessor; private final Map mMediaBlockTypeBlockProcessorMap; + private final UriWrapper mUriWrapper; /** * This factory initializes block processors for all media block types and provides a method to retrieve a block @@ -25,6 +26,7 @@ class BlockProcessorFactory { BlockProcessorFactory(MediaUploadCompletionProcessor mediaUploadCompletionProcessor) { mMediaUploadCompletionProcessor = mediaUploadCompletionProcessor; mMediaBlockTypeBlockProcessorMap = new HashMap<>(); + mUriWrapper = new UriWrapper(); } /** @@ -35,7 +37,7 @@ class BlockProcessorFactory { */ BlockProcessorFactory init(String localId, MediaFile mediaFile, String siteUrl) { mMediaBlockTypeBlockProcessorMap.put(IMAGE, new ImageBlockProcessor(localId, mediaFile)); - mMediaBlockTypeBlockProcessorMap.put(VIDEOPRESS, new VideoPressBlockProcessor(localId, mediaFile)); + mMediaBlockTypeBlockProcessorMap.put(VIDEOPRESS, new VideoPressBlockProcessor(localId, mediaFile, mUriWrapper)); mMediaBlockTypeBlockProcessorMap.put(VIDEO, new VideoBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(MEDIA_TEXT, new MediaTextBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(GALLERY, new GalleryBlockProcessor(localId, mediaFile, siteUrl, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt new file mode 100644 index 000000000000..f2a41923d279 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt @@ -0,0 +1,18 @@ +package org.wordpress.android.ui.posts.mediauploadcompletionprocessors + +import android.net.Uri + +/** + * Wrapper for the Uri class. + * + * We need to use the Uri.encode function in order to encode a URL for the VideoPress block. + * However, As Uri.encode is part an Android class, it cannot run in unit tests by default. + * Note, java.net.URLEncoder is not currently a suitable alternative as it require API 33 and above (our minimum is 24 at the time of writing) + * + * The main purpose of this wrapper is to make it easier to reference and replace this functionality in unit tests. + */ +class UriWrapper { + fun encode(input: String): String { + return Uri.encode(input) + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index ce7ad29fd634..15ce9f6b21aa 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -1,6 +1,5 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors -import android.net.Uri import android.os.Build import androidx.annotation.RequiresApi import com.google.gson.JsonObject @@ -9,7 +8,7 @@ import org.wordpress.android.util.helpers.MediaFile import java.net.URLEncoder import java.nio.charset.StandardCharsets -class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockProcessor(localId, mediaFile) { +class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?, private val uriWrapper: UriWrapper = UriWrapper()) : BlockProcessor(localId, mediaFile) { class VideoPressBlockSettings( var autoplay: Boolean? = null, var controls: Boolean? = null, @@ -56,25 +55,13 @@ class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?) : BlockP getBlockSettingsQueryArgs(queryArgs, mBlockSettings) val encodedQueryArgs = queryArgs.entries.joinToString("&") { - if (Build.VERSION.SDK_INT >= 33) { - encodeQueryArgsSdkSAndAbove(it.key, it.value).replace("%23", "") - } else { - encodeQueryArgsBelowSdkS(it.key, it.value) - } + val encodedValue = it.value.removeSurrounding("\"") + "${uriWrapper.encode(it.key)}=${uriWrapper.encode(encodedValue)}" } return "https://videopress.com/v/$guid?$encodedQueryArgs" } - @RequiresApi(33) - private fun encodeQueryArgsSdkSAndAbove(key: String, value: String): String { - return "${URLEncoder.encode(key, StandardCharsets.UTF_8)}=${URLEncoder.encode(value, StandardCharsets.UTF_8)}" - } - - private fun encodeQueryArgsBelowSdkS(key: String, value: String): String { - return "${Uri.encode(key)}=${Uri.encode(value)}" - } - private fun getDefaultQueryArgs(): MutableMap { return mutableMapOf( "resizeToParent" to "true", From a9286576aa938b9098cf14e460e5e912847712f8 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Wed, 29 Mar 2023 18:00:22 +0100 Subject: [PATCH 23/59] test: Mock URL encoding --- .../VideoPressBlockProcessorTest.kt | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt index 3004503fb10b..9ddf18e70153 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -3,19 +3,93 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors import org.assertj.core.api.Assertions import org.junit.Before import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.mock import org.mockito.kotlin.whenever import org.wordpress.android.util.helpers.MediaFile +import java.net.URLEncoder +import java.nio.charset.StandardCharsets +@RunWith(MockitoJUnitRunner::class) class VideoPressBlockProcessorTest { private val mediaFile: MediaFile = mock() + private val uriWrapper = Mockito.mock(UriWrapper::class.java) private lateinit var processor: VideoPressBlockProcessor + // Keys for each query in VideoPress URL. + private val resizeToParentKey = "resizeToParent" + private val coverKey = "cover" + private val autoPlayKey = "autoPlay" + private val controlsKey = "controls" + private val loopKey = "loop" + private val mutedKey = "muted" + private val persistVolumeKey = "persistVolume" + private val playsinlineKey = "playsinline" + private val posterUrlKey = "posterUrl" + private val preloadContentKey = "preloadContent" + private val sbcKey = "sbc" + private val sbpcKey = "sbpc" + private val sblcKey = "sblc" + private val useAverageColorKey = "useAverageColor" + + // Un-encoded values for each query in VideoPress URL. + private val falseVal = "false" + private val trueVal = "true" + private val posterUrlVal = "https://test.files.wordpress.com/2022/02/265-5000x5000-1.jpeg" + private val defaultPreloadContentVal = "metadata" + private val changedPreloadContentVal = "none" + private val sbcVal = "#abb8c3" + private val sbpcVal = "#9b51e0" + private val sblcVal = "#cf2e2e" + + private val urlKeys = listOf( + resizeToParentKey, + coverKey, + autoPlayKey, + controlsKey, + loopKey, + mutedKey, + persistVolumeKey, + playsinlineKey, + posterUrlKey, + preloadContentKey, + sbcKey, + sbpcKey, + sblcKey, + useAverageColorKey + ) + private val urlValues = listOf( + falseVal, + trueVal, + posterUrlVal, + defaultPreloadContentVal, + changedPreloadContentVal, + sbcVal, + sbpcVal, + sblcVal + ) + @Before fun before() { whenever(mediaFile.mediaId).thenReturn(TestContent.remoteMediaId) whenever(mediaFile.videoPressGuid).thenReturn(TestContent.videoPressGuid) - processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile) + + /* + * As Uri.encode is part of an Android class, it cannot run locally in unit tests by default. + * To workaround this, it has been replaced below with URLEncoder.encode, which works in a similar manner. + * Note, we cannot currently use URLEncoder.encode in the main app as it only runs with API 33 or later (we support a min of 24) + */ + for (key in urlKeys) { + whenever(uriWrapper.encode(key)).thenReturn(URLEncoder.encode(key, StandardCharsets.UTF_8)) + } + + for (value in urlValues) { + whenever(uriWrapper.encode(value)).thenReturn(URLEncoder.encode(value, StandardCharsets.UTF_8)) + } + + processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile, uriWrapper) } @Test From 9588fbb01a039029074ec175689418bc0ada1d3e Mon Sep 17 00:00:00 2001 From: Siobhan Date: Wed, 29 Mar 2023 18:00:54 +0100 Subject: [PATCH 24/59] refactor: Remove unused imports --- .../VideoPressBlockProcessor.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 15ce9f6b21aa..4139102b103d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -1,12 +1,8 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors -import android.os.Build -import androidx.annotation.RequiresApi import com.google.gson.JsonObject import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile -import java.net.URLEncoder -import java.nio.charset.StandardCharsets class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?, private val uriWrapper: UriWrapper = UriWrapper()) : BlockProcessor(localId, mediaFile) { class VideoPressBlockSettings( From 611d1ee56dcc5d1525ab65c1f0b7e514c30c028c Mon Sep 17 00:00:00 2001 From: Siobhan Date: Wed, 29 Mar 2023 18:09:21 +0100 Subject: [PATCH 25/59] refactor: Reduce line width to accommodate linter --- .../ui/posts/mediauploadcompletionprocessors/UriWrapper.kt | 5 +++-- .../VideoPressBlockProcessor.kt | 6 +++++- .../VideoPressBlockProcessorTest.kt | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt index f2a41923d279..a6a2c3bc4c52 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt @@ -4,10 +4,11 @@ import android.net.Uri /** * Wrapper for the Uri class. - * + * * We need to use the Uri.encode function in order to encode a URL for the VideoPress block. * However, As Uri.encode is part an Android class, it cannot run in unit tests by default. - * Note, java.net.URLEncoder is not currently a suitable alternative as it require API 33 and above (our minimum is 24 at the time of writing) + * Note, java.net.URLEncoder is not currently a suitable alternative as it requires API 33 or later + * (we support down to API 24 at the time of writing). * * The main purpose of this wrapper is to make it easier to reference and replace this functionality in unit tests. */ diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 4139102b103d..ac533ea8b6ca 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -4,7 +4,11 @@ import com.google.gson.JsonObject import org.jsoup.nodes.Document import org.wordpress.android.util.helpers.MediaFile -class VideoPressBlockProcessor(localId: String?, mediaFile: MediaFile?, private val uriWrapper: UriWrapper = UriWrapper()) : BlockProcessor(localId, mediaFile) { +class VideoPressBlockProcessor( + localId: String?, + mediaFile: MediaFile?, + private val uriWrapper: UriWrapper = UriWrapper() +) : BlockProcessor(localId, mediaFile) { class VideoPressBlockSettings( var autoplay: Boolean? = null, var controls: Boolean? = null, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt index 9ddf18e70153..014bcbda7ea0 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -79,7 +79,8 @@ class VideoPressBlockProcessorTest { /* * As Uri.encode is part of an Android class, it cannot run locally in unit tests by default. * To workaround this, it has been replaced below with URLEncoder.encode, which works in a similar manner. - * Note, we cannot currently use URLEncoder.encode in the main app as it only runs with API 33 or later (we support a min of 24) + * Note, we cannot currently use URLEncoder.encode in the main app as it only runs with API 33 or later. + * We support a minimum of API 24. */ for (key in urlKeys) { whenever(uriWrapper.encode(key)).thenReturn(URLEncoder.encode(key, StandardCharsets.UTF_8)) From db0f57ecb76d458ebdd77f99def4244c41458f6a Mon Sep 17 00:00:00 2001 From: Siobhan Date: Wed, 29 Mar 2023 19:36:06 +0100 Subject: [PATCH 26/59] fix: Prevent local URL being stored in JSON --- .../VideoPressBlockProcessor.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index ac533ea8b6ca..8e27b82fa26d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -170,11 +170,16 @@ class VideoPressBlockProcessor( override fun processBlockJsonAttributes(jsonAttributes: JsonObject?): Boolean { val id = jsonAttributes?.get(ID_ATTRIBUTE) + val src = jsonAttributes?.get(SRC_ATTRIBUTE) return if (id != null && !id.isJsonNull && id.asString == mLocalId) { jsonAttributes.apply { addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) addProperty(GUID_ATTRIBUTE, mRemoteGuid) + when (src) { + null -> Unit + else -> jsonAttributes.addProperty(SRC_ATTRIBUTE, mRemoteUrl) + } } mBlockSettings = VideoPressBlockSettings(jsonAttributes) @@ -188,5 +193,6 @@ class VideoPressBlockProcessor( companion object { const val ID_ATTRIBUTE = "id" const val GUID_ATTRIBUTE = "guid" + const val SRC_ATTRIBUTE = "src" } } From db6fb39fffd6f5af79c4845535ea7fb972733697 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Thu, 30 Mar 2023 19:15:36 +0100 Subject: [PATCH 27/59] refactor: Re-use existing UriWrapper for encoding --- .../BlockProcessorFactory.java | 7 ++++--- .../UriWrapper.kt | 19 ------------------- .../VideoPressBlockProcessor.kt | 5 +++-- .../org/wordpress/android/util/UriWrapper.kt | 12 ++++++++++++ .../VideoPressBlockProcessorTest.kt | 9 +++++---- 5 files changed, 24 insertions(+), 28 deletions(-) delete mode 100644 WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java index cdf94386f7e8..522407826de9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/BlockProcessorFactory.java @@ -1,5 +1,6 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors; +import org.wordpress.android.util.UriEncoder; import org.wordpress.android.util.helpers.MediaFile; import java.util.HashMap; @@ -17,7 +18,7 @@ class BlockProcessorFactory { private final MediaUploadCompletionProcessor mMediaUploadCompletionProcessor; private final Map mMediaBlockTypeBlockProcessorMap; - private final UriWrapper mUriWrapper; + private final UriEncoder mUriEncoder; /** * This factory initializes block processors for all media block types and provides a method to retrieve a block @@ -26,7 +27,7 @@ class BlockProcessorFactory { BlockProcessorFactory(MediaUploadCompletionProcessor mediaUploadCompletionProcessor) { mMediaUploadCompletionProcessor = mediaUploadCompletionProcessor; mMediaBlockTypeBlockProcessorMap = new HashMap<>(); - mUriWrapper = new UriWrapper(); + mUriEncoder = new UriEncoder(); } /** @@ -37,7 +38,7 @@ class BlockProcessorFactory { */ BlockProcessorFactory init(String localId, MediaFile mediaFile, String siteUrl) { mMediaBlockTypeBlockProcessorMap.put(IMAGE, new ImageBlockProcessor(localId, mediaFile)); - mMediaBlockTypeBlockProcessorMap.put(VIDEOPRESS, new VideoPressBlockProcessor(localId, mediaFile, mUriWrapper)); + mMediaBlockTypeBlockProcessorMap.put(VIDEOPRESS, new VideoPressBlockProcessor(localId, mediaFile, mUriEncoder)); mMediaBlockTypeBlockProcessorMap.put(VIDEO, new VideoBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(MEDIA_TEXT, new MediaTextBlockProcessor(localId, mediaFile)); mMediaBlockTypeBlockProcessorMap.put(GALLERY, new GalleryBlockProcessor(localId, mediaFile, siteUrl, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt deleted file mode 100644 index a6a2c3bc4c52..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/UriWrapper.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.wordpress.android.ui.posts.mediauploadcompletionprocessors - -import android.net.Uri - -/** - * Wrapper for the Uri class. - * - * We need to use the Uri.encode function in order to encode a URL for the VideoPress block. - * However, As Uri.encode is part an Android class, it cannot run in unit tests by default. - * Note, java.net.URLEncoder is not currently a suitable alternative as it requires API 33 or later - * (we support down to API 24 at the time of writing). - * - * The main purpose of this wrapper is to make it easier to reference and replace this functionality in unit tests. - */ -class UriWrapper { - fun encode(input: String): String { - return Uri.encode(input) - } -} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 8e27b82fa26d..ff6e5133617e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -2,12 +2,13 @@ package org.wordpress.android.ui.posts.mediauploadcompletionprocessors import com.google.gson.JsonObject import org.jsoup.nodes.Document +import org.wordpress.android.util.UriEncoder import org.wordpress.android.util.helpers.MediaFile class VideoPressBlockProcessor( localId: String?, mediaFile: MediaFile?, - private val uriWrapper: UriWrapper = UriWrapper() + private val uriEncoder: UriEncoder = UriEncoder() ) : BlockProcessor(localId, mediaFile) { class VideoPressBlockSettings( var autoplay: Boolean? = null, @@ -56,7 +57,7 @@ class VideoPressBlockProcessor( val encodedQueryArgs = queryArgs.entries.joinToString("&") { val encodedValue = it.value.removeSurrounding("\"") - "${uriWrapper.encode(it.key)}=${uriWrapper.encode(encodedValue)}" + "${uriEncoder.encode(it.key)}=${uriEncoder.encode(encodedValue)}" } return "https://videopress.com/v/$guid?$encodedQueryArgs" diff --git a/WordPress/src/main/java/org/wordpress/android/util/UriWrapper.kt b/WordPress/src/main/java/org/wordpress/android/util/UriWrapper.kt index 943e8c68eb3e..8d5fbb09d316 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/UriWrapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/UriWrapper.kt @@ -20,3 +20,15 @@ data class UriWrapper(val uri: Uri) { return this.copy(uri = newUri) } } + +/** + * Note, java.net.URLEncoder is not currently a suitable alternative to using Uri.encode in the main codebase. + * This is because java.net.URLEncoder requires API 33 or later (we support down to API 24 at the time of writing). + * However, java.net.URLEncoder can be used in unit tests to avoid fully mocking the encode function. + * e.g. whenever(uriWrapper.encode(value)).thenReturn(URLEncoder.encode(value, StandardCharsets.UTF_8)) + */ +class UriEncoder { + fun encode(input: String): String { + return Uri.encode(input) + } +} diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt index 014bcbda7ea0..b755b694548e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessorTest.kt @@ -8,6 +8,7 @@ import org.mockito.Mockito import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.mock import org.mockito.kotlin.whenever +import org.wordpress.android.util.UriEncoder import org.wordpress.android.util.helpers.MediaFile import java.net.URLEncoder import java.nio.charset.StandardCharsets @@ -15,7 +16,7 @@ import java.nio.charset.StandardCharsets @RunWith(MockitoJUnitRunner::class) class VideoPressBlockProcessorTest { private val mediaFile: MediaFile = mock() - private val uriWrapper = Mockito.mock(UriWrapper::class.java) + private val uriEncoder = Mockito.mock(UriEncoder::class.java) private lateinit var processor: VideoPressBlockProcessor // Keys for each query in VideoPress URL. @@ -83,14 +84,14 @@ class VideoPressBlockProcessorTest { * We support a minimum of API 24. */ for (key in urlKeys) { - whenever(uriWrapper.encode(key)).thenReturn(URLEncoder.encode(key, StandardCharsets.UTF_8)) + whenever(uriEncoder.encode(key)).thenReturn(URLEncoder.encode(key, StandardCharsets.UTF_8)) } for (value in urlValues) { - whenever(uriWrapper.encode(value)).thenReturn(URLEncoder.encode(value, StandardCharsets.UTF_8)) + whenever(uriEncoder.encode(value)).thenReturn(URLEncoder.encode(value, StandardCharsets.UTF_8)) } - processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile, uriWrapper) + processor = VideoPressBlockProcessor(TestContent.localMediaId, mediaFile, uriEncoder) } @Test From f8cd6a8865370c1c131382a23c49135d4a95682b Mon Sep 17 00:00:00 2001 From: Siobhan Date: Fri, 31 Mar 2023 13:06:20 +0100 Subject: [PATCH 28/59] fix: Leave src unchanged following re-upload This commit follows the feedback here: https://github.com/wordpress-mobile/WordPress-Android/pull/18187#discussion_r1153418105 --- .../VideoPressBlockProcessor.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index ff6e5133617e..89ea31391589 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -177,10 +177,6 @@ class VideoPressBlockProcessor( jsonAttributes.apply { addProperty(ID_ATTRIBUTE, Integer.parseInt(mRemoteId)) addProperty(GUID_ATTRIBUTE, mRemoteGuid) - when (src) { - null -> Unit - else -> jsonAttributes.addProperty(SRC_ATTRIBUTE, mRemoteUrl) - } } mBlockSettings = VideoPressBlockSettings(jsonAttributes) From 93a5649f5db6532542e329c34abbe19fc9111ebf Mon Sep 17 00:00:00 2001 From: Siobhan Date: Fri, 31 Mar 2023 13:15:27 +0100 Subject: [PATCH 29/59] refactor: Remove unused src attributes --- .../mediauploadcompletionprocessors/VideoPressBlockProcessor.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt index 89ea31391589..e26699a21ab4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/mediauploadcompletionprocessors/VideoPressBlockProcessor.kt @@ -171,7 +171,6 @@ class VideoPressBlockProcessor( override fun processBlockJsonAttributes(jsonAttributes: JsonObject?): Boolean { val id = jsonAttributes?.get(ID_ATTRIBUTE) - val src = jsonAttributes?.get(SRC_ATTRIBUTE) return if (id != null && !id.isJsonNull && id.asString == mLocalId) { jsonAttributes.apply { @@ -190,6 +189,5 @@ class VideoPressBlockProcessor( companion object { const val ID_ATTRIBUTE = "id" const val GUID_ATTRIBUTE = "guid" - const val SRC_ATTRIBUTE = "src" } } From e6341847bfe87f6fdf60c4ae3f5241f9ffc7ee70 Mon Sep 17 00:00:00 2001 From: Siobhan Date: Fri, 31 Mar 2023 14:27:00 +0100 Subject: [PATCH 30/59] Empty commit to retrigger checks. From 012148282f38e0793ca786e06af2e80f326c074d Mon Sep 17 00:00:00 2001 From: Ravi Date: Mon, 3 Apr 2023 16:13:28 +1000 Subject: [PATCH 31/59] Add Domains Dashboard Card field Adds buildConfigField for enabling Domains Dashboard Card feature --- WordPress/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 0f9bc5c81848..7442c924cda0 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -135,6 +135,7 @@ android { buildConfigField "boolean", "WP_INDIVIDUAL_PLUGIN_OVERLAY", "false" buildConfigField "boolean", "DASHBOARD_CARD_PAGES", "false" buildConfigField "boolean", "DASHBOARD_CARD_ACTIVITY_LOG", "false" + buildConfigField "boolean", "ENABLE_DOMAINS_DASHBOARD_CARD_FEATURE", "false" // Override these constants in jetpack product flavor to enable/ disable features buildConfigField "boolean", "ENABLE_SITE_CREATION", "true" From 7ea97c597ee1fea2f775218db9bb8ac65c61772f Mon Sep 17 00:00:00 2001 From: Ravi Date: Mon, 3 Apr 2023 16:14:18 +1000 Subject: [PATCH 32/59] Create DomainsDasboardCardFeatureConfig.kt Add Remote Domains Dashboard Card Feature Config class --- .../config/DomainsDasboardCardFeatureConfig.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt new file mode 100644 index 000000000000..a541c8a3f730 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt @@ -0,0 +1,16 @@ +package org.wordpress.android.util.config + +import org.wordpress.android.BuildConfig +import org.wordpress.android.annotation.Feature +import javax.inject.Inject + +private const val DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD = "domains_dashboard_card" + +@Feature(DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD, false) +class DomainsDashboardCardFeatureConfig @Inject constructor( + appConfig: AppConfig +) : FeatureConfig( + appConfig, + BuildConfig.ENABLE_DOMAINS_DASHBOARD_CARD_FEATURE, + DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD +) From e7b40a0b6ae2ee1bcf1d0dc1b6aa1d3be6645242 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 3 Apr 2023 12:05:26 +0200 Subject: [PATCH 33/59] Update Gutenberg Mobile reference --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7f0633805d96..53d8ba07f74e 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ ext { automatticRestVersion = '1.0.8' automatticStoriesVersion = '2.0.0' automatticTracksVersion = '2.2.0' - gutenbergMobileVersion = '5596-966b12f8bd5fd7c35fb3ef499566451bfb6a2463' + gutenbergMobileVersion = '5596-9329ef7ca9c1a34aaef6ea37b30887f802694474' wordPressAztecVersion = 'v1.6.3' wordPressFluxCVersion = '2691-a3bac6077768944a3e79a6a1eb4c7c22dd2e1183' wordPressLoginVersion = '1.0.0' From b385700cc1a38aa577c37c3ad09af268be31c4eb Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 3 Apr 2023 16:33:28 +0200 Subject: [PATCH 34/59] Point FluxC version to `trunk` commit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a254110fb01..4d184fa9ade4 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { automatticTracksVersion = '2.2.0' gutenbergMobileVersion = '5596-9329ef7ca9c1a34aaef6ea37b30887f802694474' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = '2691-a3bac6077768944a3e79a6a1eb4c7c22dd2e1183' + wordPressFluxCVersion = 'trunk-4c38c0da2445f4136a92a587414e9e4a27e5e534' wordPressLoginVersion = '116-9e75c5927871287fccb0617f15f69bb066656570' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From 6d6c04ff7c0b2fb1675ef2f992d01a0428358d0a Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:39:30 -0400 Subject: [PATCH 35/59] Bump version number --- version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.properties b/version.properties index 84b917db60bd..8bcbda89dc15 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ #Mon, 30 Aug 2021 11:48:28 +0200 -versionName=22.0 -versionCode=1326 +versionName=22.1-rc-1 +versionCode=1327 From e7fd2d23974343f9af5c0292959cba4ba360a753 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:39:31 -0400 Subject: [PATCH 36/59] Update draft release notes for 22.1. --- WordPress/metadata/release_notes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/metadata/release_notes.txt b/WordPress/metadata/release_notes.txt index 4bad8f44ffea..3f2e28cea77f 100644 --- a/WordPress/metadata/release_notes.txt +++ b/WordPress/metadata/release_notes.txt @@ -1 +1,2 @@ -You can now transform most types of blocks into other block types, like quotes, columns, and groups. +* [**] [WordPress-only] Warns user about sites with only individual plugins not supporting core app features and offers the option to switch to the Jetpack app. [https://github.com/wordpress-mobile/WordPress-Android/pull/18199] + From 5a59f0f2a601a04e4820f60bb07df800c3df95f7 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:39:32 -0400 Subject: [PATCH 37/59] Update draft release notes for Jetpack 22.1. --- WordPress/jetpack_metadata/release_notes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/jetpack_metadata/release_notes.txt b/WordPress/jetpack_metadata/release_notes.txt index 4bad8f44ffea..3f2e28cea77f 100644 --- a/WordPress/jetpack_metadata/release_notes.txt +++ b/WordPress/jetpack_metadata/release_notes.txt @@ -1 +1,2 @@ -You can now transform most types of blocks into other block types, like quotes, columns, and groups. +* [**] [WordPress-only] Warns user about sites with only individual plugins not supporting core app features and offers the option to switch to the Jetpack app. [https://github.com/wordpress-mobile/WordPress-Android/pull/18199] + From ce2de71c28b5222db1f7412092b4c2e3491167df Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:39:32 -0400 Subject: [PATCH 38/59] Release Notes: add new section for next version (22.2) --- RELEASE-NOTES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 4be2eef3bf60..99b2e4491262 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,5 +1,9 @@ *** PLEASE FOLLOW THIS FORMAT: [] [] +22.2 +----- + + 22.1 ----- * [**] [WordPress-only] Warns user about sites with only individual plugins not supporting core app features and offers the option to switch to the Jetpack app. [https://github.com/wordpress-mobile/WordPress-Android/pull/18199] From d029ee299dc46176d2af3119239005d31c34138b Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:46:11 -0400 Subject: [PATCH 39/59] Update login library to 1.3.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 015fd610b2dd..fbd81b9b72d4 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,7 @@ ext { gutenbergMobileVersion = 'v1.92.0' wordPressAztecVersion = 'v1.6.3' wordPressFluxCVersion = 'trunk-fcede535112327abf59416b7b544cf526c44fd00' - wordPressLoginVersion = '116-9e75c5927871287fccb0617f15f69bb066656570' + wordPressLoginVersion = '1.3.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From 01036016368d33f16ac3925ebfe9c2521053ce38 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:48:23 -0400 Subject: [PATCH 40/59] Update FluxC version to 2.23.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fbd81b9b72d4..e77fd98d6b89 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { automatticTracksVersion = '2.2.0' gutenbergMobileVersion = 'v1.92.0' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = 'trunk-fcede535112327abf59416b7b544cf526c44fd00' + wordPressFluxCVersion = '2.23.0' wordPressLoginVersion = '1.3.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From d3051945df66badcf23139b579b3a360172a1b57 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:55:44 -0400 Subject: [PATCH 41/59] Remove WordPress only release notes from Jetpack release notes --- WordPress/jetpack_metadata/release_notes.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/jetpack_metadata/release_notes.txt b/WordPress/jetpack_metadata/release_notes.txt index 3f2e28cea77f..8b137891791f 100644 --- a/WordPress/jetpack_metadata/release_notes.txt +++ b/WordPress/jetpack_metadata/release_notes.txt @@ -1,2 +1 @@ -* [**] [WordPress-only] Warns user about sites with only individual plugins not supporting core app features and offers the option to switch to the Jetpack app. [https://github.com/wordpress-mobile/WordPress-Android/pull/18199] From 5f8f6c1cff103da4b990c6057f941e08a82903b1 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 3 Apr 2023 15:56:59 -0400 Subject: [PATCH 42/59] Freeze strings for translation --- fastlane/resources/values/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/fastlane/resources/values/strings.xml b/fastlane/resources/values/strings.xml index c21915bf03e0..7ab09264aede 100644 --- a/fastlane/resources/values/strings.xml +++ b/fastlane/resources/values/strings.xml @@ -4453,4 +4453,28 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> @string/label_done_button @string/blaze_activity_title + + + Switch to the Jetpack app + Please switch to the Jetpack app where we’ll guide you through connecting the full Jetpack plugin to use this site with the app. + + Unable to access one of your sites + Unable to access some of your sites + + + <b>%1$s</b> is using the <b>%2$s</b> plugin, which isn’t supported by the WordPress app. + + <b>%1$s</b> is using individual Jetpack plugins, which aren’t supported by the WordPress app. + Sites with individual Jetpack plugins aren’t supported by the WordPress app. + + <b>%1$s</b> is using the <b>%2$s</b> plugin + + <b>%1$s</b> is using %2$s individual Jetpack plugins From 0f1ce5acbb0a2c895eb26c302bcda46136de68cf Mon Sep 17 00:00:00 2001 From: Ravi Date: Tue, 4 Apr 2023 14:46:11 +1000 Subject: [PATCH 43/59] Rename to Dashboard Card Domain Refactoring DOMAINS_DASHBOARD_CARD to DASHBOARD_CARD_DOMAIN for consistency with other cards on dashboard --- WordPress/build.gradle | 2 +- .../config/DasboardCardDomainFeatureConfig.kt | 16 ++++++++++++++++ .../config/DomainsDasboardCardFeatureConfig.kt | 16 ---------------- 3 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/util/config/DasboardCardDomainFeatureConfig.kt delete mode 100644 WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 7442c924cda0..a72abd2d47de 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -135,7 +135,7 @@ android { buildConfigField "boolean", "WP_INDIVIDUAL_PLUGIN_OVERLAY", "false" buildConfigField "boolean", "DASHBOARD_CARD_PAGES", "false" buildConfigField "boolean", "DASHBOARD_CARD_ACTIVITY_LOG", "false" - buildConfigField "boolean", "ENABLE_DOMAINS_DASHBOARD_CARD_FEATURE", "false" + buildConfigField "boolean", "DASHBOARD_CARD_DOMAIN", "false" // Override these constants in jetpack product flavor to enable/ disable features buildConfigField "boolean", "ENABLE_SITE_CREATION", "true" diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/DasboardCardDomainFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/DasboardCardDomainFeatureConfig.kt new file mode 100644 index 000000000000..d685aacfed93 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/util/config/DasboardCardDomainFeatureConfig.kt @@ -0,0 +1,16 @@ +package org.wordpress.android.util.config + +import org.wordpress.android.BuildConfig +import org.wordpress.android.annotation.Feature +import javax.inject.Inject + +private const val DASHBOARD_CARD_DOMAIN_REMOTE_FIELD = "dashboard_card_domain" + +@Feature(DASHBOARD_CARD_DOMAIN_REMOTE_FIELD, false) +class DashboardCardDomainFeatureConfig @Inject constructor( + appConfig: AppConfig +) : FeatureConfig( + appConfig, + BuildConfig.DASHBOARD_CARD_DOMAIN, + DASHBOARD_CARD_DOMAIN_REMOTE_FIELD +) diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt deleted file mode 100644 index a541c8a3f730..000000000000 --- a/WordPress/src/main/java/org/wordpress/android/util/config/DomainsDasboardCardFeatureConfig.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.wordpress.android.util.config - -import org.wordpress.android.BuildConfig -import org.wordpress.android.annotation.Feature -import javax.inject.Inject - -private const val DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD = "domains_dashboard_card" - -@Feature(DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD, false) -class DomainsDashboardCardFeatureConfig @Inject constructor( - appConfig: AppConfig -) : FeatureConfig( - appConfig, - BuildConfig.ENABLE_DOMAINS_DASHBOARD_CARD_FEATURE, - DOMAINS_DASHBOARD_CARD_FEATURE_REMOTE_FIELD -) From 93daf07d8f979ba17883eb9ee16d16d2063497d0 Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 4 Apr 2023 12:00:45 -0300 Subject: [PATCH 44/59] point to fixed FluxC version (commit hash) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e77fd98d6b89..867f3fc3e4e6 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { automatticTracksVersion = '2.2.0' gutenbergMobileVersion = 'v1.92.0' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = '2.23.0' + wordPressFluxCVersion = '2701-4d67a3e7dff3ba53e110629516bcbcaa81b5f7af' // TODO use 2.23.1 wordPressLoginVersion = '1.3.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From ff35a759d6b8acffa1d4f2615d5f8b757c2c6ecb Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 4 Apr 2023 12:39:05 -0300 Subject: [PATCH 45/59] remove URL scheme from the site URL in the overlay --- .../individualplugin/WPJetpackIndividualPluginHelper.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelper.kt index b2acfd12f3c3..4dead6498e0d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelper.kt @@ -3,6 +3,8 @@ package org.wordpress.android.ui.jetpackoverlay.individualplugin import org.wordpress.android.fluxc.persistence.JetpackCPConnectedSiteModel import org.wordpress.android.fluxc.store.SiteStore import org.wordpress.android.ui.prefs.AppPrefsWrapper +import org.wordpress.android.util.StringUtils +import org.wordpress.android.util.UrlUtils import org.wordpress.android.util.config.WPIndividualPluginOverlayFeatureConfig import org.wordpress.android.util.config.WPIndividualPluginOverlayMaxShownConfig import org.wordpress.android.util.extensions.activeIndividualJetpackPluginNames @@ -27,7 +29,7 @@ class WPJetpackIndividualPluginHelper @Inject constructor( return individualPluginConnectedSites.map { site -> SiteWithIndividualJetpackPlugins( name = site.name, - url = site.url, + url = StringUtils.removeTrailingSlash(UrlUtils.removeScheme(site.url)), individualPluginNames = site.activeIndividualJetpackPluginNames(), ) } From 39f0baba1ece580588e036c44587a0f13e3940fb Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 4 Apr 2023 12:39:56 -0300 Subject: [PATCH 46/59] update unit tests --- .../WPJetpackIndividualPluginHelperTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelperTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelperTest.kt index f27fd0ee895a..bc213323df37 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelperTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/jetpackoverlay/individualplugin/WPJetpackIndividualPluginHelperTest.kt @@ -152,12 +152,12 @@ class WPJetpackIndividualPluginHelperTest : BaseUnitTest() { val connectedSites = listOf( jetpackCPConnectedSiteModel( name = "site1", - url = "site1.com", + url = "https://site1.com", activeJpPlugins = "jetpack-social" ), jetpackCPConnectedSiteModel( name = "site2", - url = "site2.com", + url = "https://site2.com", activeJpPlugins = "other-plugin" ) ) @@ -190,12 +190,12 @@ class WPJetpackIndividualPluginHelperTest : BaseUnitTest() { val connectedSites = listOf( jetpackCPConnectedSiteModel( name = "site1", - url = "site1.com", + url = "https://site1.com", activeJpPlugins = "jetpack-social" ), jetpackCPConnectedSiteModel( name = "site2", - url = "site2.com", + url = "https://site2.com", activeJpPlugins = "other-plugin" ) ) From c7670114315df862c0304105796c9fa281fb894a Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 4 Apr 2023 14:15:22 -0300 Subject: [PATCH 47/59] Update FluxC version to 2.23.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 867f3fc3e4e6..a891cd063f41 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { automatticTracksVersion = '2.2.0' gutenbergMobileVersion = 'v1.92.0' wordPressAztecVersion = 'v1.6.3' - wordPressFluxCVersion = '2701-4d67a3e7dff3ba53e110629516bcbcaa81b5f7af' // TODO use 2.23.1 + wordPressFluxCVersion = '2.23.1' wordPressLoginVersion = '1.3.0' wordPressPersistentEditTextVersion = '1.0.2' wordPressUtilsVersion = '3.3.0' From 98145bf14caead83a4515bba5529a9aadb1ec3a3 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Tue, 4 Apr 2023 15:08:38 -0400 Subject: [PATCH 48/59] Update translations --- WordPress/src/main/res/values-ar/strings.xml | 19 +- WordPress/src/main/res/values-de/strings.xml | 13 +- WordPress/src/main/res/values-el/strings.xml | 6 +- WordPress/src/main/res/values-es/strings.xml | 1622 ++++++++--------- WordPress/src/main/res/values-he/strings.xml | 17 +- WordPress/src/main/res/values-id/strings.xml | 12 +- WordPress/src/main/res/values-it/strings.xml | 18 +- WordPress/src/main/res/values-ja/strings.xml | 17 +- WordPress/src/main/res/values-ko/strings.xml | 1426 ++++++++------- WordPress/src/main/res/values-nl/strings.xml | 63 +- WordPress/src/main/res/values-ro/strings.xml | 11 +- .../src/main/res/values-zh-rCN/strings.xml | 18 +- .../src/main/res/values-zh-rHK/strings.xml | 829 ++++----- .../src/main/res/values-zh-rTW/strings.xml | 19 +- 14 files changed, 2156 insertions(+), 1934 deletions(-) diff --git a/WordPress/src/main/res/values-ar/strings.xml b/WordPress/src/main/res/values-ar/strings.xml index e677d0df8d19..9fbd70a268d4 100644 --- a/WordPress/src/main/res/values-ar/strings.xml +++ b/WordPress/src/main/res/values-ar/strings.xml @@ -1,6 +1,6 @@ + <b>%1$s</b> benutzt %2$s individuelle Jetpack-Plugins + <b>%1$s</b> benutzt das <b>%2$s</b> Plugin + Websites mit individuellen Jetpack-Plugins werden von der WordPress-App nicht unterstützt. + <b>%1$s</b> benutzt individuelle Jetpack-Plugins, die von der WordPress-App nicht unterstützt werden. + <b>%1$s</b> benutzt das <b>%2$s</b> Plugin, welches nicht von der WordPress-App unterstützt wird. + Auf manche deiner Websites kann nicht zugegriffen werden + Auf eine deiner Websites kann nicht zugegriffen werden + Bitte wechsle zu der Jetpack-App, wo wir dich durch die Anbindung des vollständigen Jetpack-Plugins führen, damit diese Website mit der App benutzt werden kann. + Zur Jetpack-App wechseln %1$s verwendet %2$s, das noch nicht alle Funktionen der App unterstützt.\n\nBitte installiere das %3$s, um die App mit dieser Website zu verwenden. Diese Website %1$s verwendet %2$s, das noch nicht alle Funktionen der App unterstützt. Bitte installiere das %3$s. @@ -2851,7 +2860,7 @@ Language: de %s: Folge ich bereits %s: Bereits ein Mitglied %s: Benutzer nicht gefunden - Kommentar genehmigt! + Kommentar freigegeben! Like Jetzt Besucher diff --git a/WordPress/src/main/res/values-el/strings.xml b/WordPress/src/main/res/values-el/strings.xml index d9ef3dcc9df9..b4a69c259eaa 100644 --- a/WordPress/src/main/res/values-el/strings.xml +++ b/WordPress/src/main/res/values-el/strings.xml @@ -1,6 +1,6 @@ %1$s gebruikt %2$s. Deze ondersteunt nog niet alle functies van de app.\n\nInstalleer de %3$s om de app met deze site te gebruiken. + Deze site %1$s gebruikt %2$s. Deze ondersteunen nog niet alle functies van de app. Installeer de %3$s. %1$s gebruikt %2$s. Deze ondersteunt nog niet alle functies van de app. Installeer de %3$s. We stappen binnen een paar dagen over naar Jetpack. + Overstappen is gratis en duurt maar een minuut. Statistieken, Reader, meldingen en andere functies die door Jetpack aangedreven worden, zijn verwijderd uit de WordPress-app en kunnen nu alleen in de Jetpack-app gevonden worden. Ga naar Jetpack.com voor meer informatie Schakel over naar de Jetpack-app %s zijn naar de Jetpack-app verplaatst %s is naar de Jetpack-app verplaatst WP Admin + Beheren Bezoekersaantallen + Inhoud + Instellen Gereed Nu Jetpack is geïnstalleerd, hoeven we er alleen nog voor te zorgen dat alles goed ingesteld is. Dit duurt maar heel even. + Blaze nu een bericht + Blaze deze pagina + Blaze dit bericht Volg prestaties, start en stop je Blaze op elk gewenst moment. Je content zal op miljoenen WordPress en Tumblr sites verschijnen. Promoot in een paar minuten elke post of pagina voor slechts enkele euro’s per dag. Zorg dat meer mensen je site bezoeken met Blaze + Blaze + Dit domein is al geregistreerd Aanbieding! + Aanbevolen + Beste alternatief + %s/jr + Hulp Bekijk onze pagina met veelgestelde vragen om mogelijke antwoorden te vinden op jouw vragen. Bedankt voor het overschakelen naar de Jetpack-app! Logbestanden + Tickets + Gratis + Hulp Blokkenmenu Dit verbergen Stel je werk tentoon op miljoenen sites. + Promoot je content met Blaze + Sluiten Neem contact op met de ondersteuning De volledige plug-in installeren + Voorwaarden en condities Door Jetpack in te stellen, ga je akkoord met onze volledige Jetpack-plug-in individuele Jetpack-plug-ins de %1$s-plug-in + %1$s gebruikt %2$s. Deze ondersteunen nog niet alle functies van de app.\n\nInstalleer de %3$s om de app met deze site te gebruiken. Installeer de volledige Jetpack-plug-in + Er is maar één site beschikbaar, dus je kunt je primaire site niet wijzigen. + Neem contact op met de ondersteuning + Opnieuw proberen + Jetpack kan momenteel niet geïnstalleerd worden. + Er is een probleem opgetreden + Foutpictogram + Gereed om deze site met de app te gebruiken. + Jetpack geïnstalleerd + Jetpack installeren op je site. Het kan een aantal minuten duren voordat de installatie is afgerond. + Jetpack installeren + Doorgaan + De inloggegevens voor je website zullen niet worden opgeslagen en worden alleen gebruikt om Jetpack te installeren. + Jetpack installeren Jetpack pictogram + Promoten met Blaze Ontgrendel de volledige functionaliteit van je site. Krijg Statistieken, Lezer, Meldingen en meer met Jetpack. Je site heeft de Jetpack-plugin De Jetpack mobiele app is ontworpen om samen met de Jetpack-plugin te werken. Stap nu over om toegang te krijgen tot Statistieken, Meldingen, Reader en meer. @@ -46,6 +81,7 @@ Language: nl Laat het aantal bezoekers van je site groeien via waardevolle inzichten en uitgebreide statistieken. Statistieken en inzichten Met Jetpack kun je meer doen met je WordPress-site. Overstappen is gratis en duurt maar een minuut. + Geef WordPress een boost met Jetpack Je kunt blogmeldingen en -herinneringen te allen tijde beheren via Mijn site > Instellingen > Bloggen Meldingen bevatten een woord of korte zin ter inspiratie Ga naar <b>Site-instellingen</b> om weer in te schakelen @@ -55,7 +91,9 @@ Language: nl Communityforums Blogherinneringen Meldingen weergeven + Bloggen Installeer Google Play Store om de Jetpack-app te downloaden + Doe dit later Overstappen naar Jetpack Statistieken, Reader, meldingen en andere functies die door Jetpack aangedreven worden, zijn verwijderd uit de WordPress-app. Jetpack-functies zijn verplaatst. @@ -71,7 +109,10 @@ Language: nl Je hebt de afgelopen 7dagen %1$s meer bezoekers gehad dan de vorige 7 dagen. Je hebt de afgelopen 7dagen %1$s minder weergaven gehad dan de vorige 7 dagen. Je hebt de afgelopen 7dagen %1$s meer weergaven gehad dan de vorige 7 dagen. + Vorige 7 dagen + Afgelopen 7 dagen %d weken + 1 week Vanaf <b>DayOne</b> Dit verbergen Herinner mij hier later aan @@ -89,19 +130,32 @@ Language: nl Controleer je netwerkverbinding en probeer het nogmaals. Deze inhoud kan momenteel niet geladen worden Er is een fout opgetreden bij het laden van opdrachten. + Oeps Er zijn nog geen opdrachten + %d antwoorden + 1 antwoord + 0 antwoorden ✓ Beantwoord + Prompts + sluiten + Als alternatief, kun je dit blok ook losmaken en afzonderlijk bewerken door op \'Converteren naar normaal blok\' te tikken. + Categorie \'%s\' permanent verwijderen? Categorie is verwijderd Verwijderen van categorie mislukt Categorie verwijderen Categorie bijwerken Categorie bijwerken + Berichten van deze gebruiker zullen niet meer getoond worden Gebruiker blokkeren Deze gebruiker rapporteren + Links openen in WordPress Het lijkt erop dat je de Jetpack-app geïnstalleerd hebt.\n\nWil je links in de toekomst in de Jetpack-app openen?\n\nJe kan dit altijd veranderen in App-instellingen > Links openen in Jetpack + Links openen in Jetpack? + Doorgaan zonder Jetpack Jetpack biedt statistieken, meldingen en meer om je te helpen de WordPress-site van je dromen te bouwen.\n\nDe WordPress-app ondersteunt het maken van een nieuwe site niet meer. Jetpack biedt statistieken, meldingen en meer om je te helpen de WordPress-site van je dromen te bouwen. Maak een nieuwe WordPress-site met de Jetpack-app + weblinks uri-links Schakel over naar de Jetpack-app om realtime meldingen te blijven ontvangen op je apparaat. Schakel over naar de Jetpack-app om je favoriete sites en berichten te vinden, te volgen en een like te geven met Reader. @@ -112,12 +166,14 @@ Language: nl Kan links openen in Jetpack niet uitschakelen Kan links openen in Jetpack niet inschakelen Links openen in Jetpack + Hulp nodig? Duidelijk <b>Verwijder de WordPress-app</b> om gegevensconflicten te vermijden. Het lijkt erop dat je de WordPress-app nog steeds geïnstalleerd hebt. We raden je aan om de WordPress-app te verwijderen om gegevensconflicten te vermijden. Je hebt de WordPress-app niet meer nodig We kunnen je gegevens en instellingen niet overdragen zonder netwerkverbinding. Controleer of je een netwerkverbinding hebt en probeer het opnieuw. + Kan geen verbinding maken met het internet. Probeer het later opnieuw of neem contact op met de klantenservice. Er is iets misgegaan. Je gegevens zijn veilig, maar we kunnen ze op dit moment niet overdragen. Oeps, er is iets fout gegaan… @@ -125,12 +181,14 @@ Language: nl Afronden Verwijder pictogram WordPress-app <b>Verwijder de WordPress-app</b> om gegevensconflicten te vermijden. + We hebben al je gegevens en instellingen overgedragen. Alles staat precies waar je het gelaten hebt. Bedankt dat je bent overgestapt naar Jetpack! We zullen meldingen van de WordPress-app uitschakelen. Je krijgt dezelfde meldingen, maar ze komen nu van de Jetpack-app. Je krijgt nu meldingen van Jetpack Verwijder de WordPress-app WordPress help centrum + Ondersteuning Staat de app toe om meldingen van WordPress uit te schakelen. meldingen van WordPress uitschakelen Hulp nodig? @@ -376,6 +434,7 @@ Language: nl Bijv. mode, poëzie, politiek Onderwerp van de site Tik op <b>%1$s</b> om door te gaan. + Sla deze prompt over Bekijk meer prompts %d antwoorden Blog-opdracht delen @@ -1892,7 +1951,7 @@ Language: nl Kies een unieke site pictogram Je bezoekers zien je pictogram in hun browser. Voeg een aangepast pictogram toe voor een stijlvolle, professionele look. Selecteer %1$s Statistieken %2$s om te zien hoe je site presteert. - Tik op %1$s Jouw favicon %2$s om een nieuwe te uploaden + Tik op %1$s je site pictogram %2$s om een nieuwe te uploaden Stel een bericht op en publiceer het. Berichten delen inschakelen Deel nieuwe berichten automatisch op je socialmedia-accounts. diff --git a/WordPress/src/main/res/values-ro/strings.xml b/WordPress/src/main/res/values-ro/strings.xml index 16d28f68f98d..506c8305c9e1 100644 --- a/WordPress/src/main/res/values-ro/strings.xml +++ b/WordPress/src/main/res/values-ro/strings.xml @@ -1,11 +1,20 @@ + <b>%1$s</b> folosește %2$s module Jetpack individuale + Site-urile cu module Jetpack individuale nu sunt acceptate de aplicația WordPress. + <b>%1$s</b> folosește modulul <b>%2$s</b> + <b>%1$s</b> folosește module Jetpack individuale care nu sunt acceptate de aplicația WordPress. + <b>%1$s</b> folosește modulul <b>%2$s</b> care nu este acceptat de aplicația WordPress. + Nu pot să accesez unele dintre site-urile tale + Nu pot să accesez unul dintre site-urile tale + Te rog să comuți la aplicația Jetpack, te vom ghida la conectarea integrală a modulului Jetpack ca să poți să folosești acest site cu aplicația. + Comută la aplicația Jetpack %1$s folosește %2$s care nu suportă încă toate funcționalitățile aplicației. \n\nPentru a folosi aplicația cu acest site, te rog să instalezi %3$s. Acest site %1$s folosește %2$s, care încă nu suportă toate funcționalitățile aplicației. Te rog instalează %3$s. diff --git a/WordPress/src/main/res/values-zh-rCN/strings.xml b/WordPress/src/main/res/values-zh-rCN/strings.xml index c368428c8f46..e97de910528f 100644 --- a/WordPress/src/main/res/values-zh-rCN/strings.xml +++ b/WordPress/src/main/res/values-zh-rCN/strings.xml @@ -1,6 +1,6 @@