diff --git a/example/src/androidTest/java/org/wordpress/android/fluxc/mocked/MockedStack_EditorThemeStoreTest.kt b/example/src/androidTest/java/org/wordpress/android/fluxc/mocked/MockedStack_EditorThemeStoreTest.kt index 01feb2c2f7..1164264e09 100644 --- a/example/src/androidTest/java/org/wordpress/android/fluxc/mocked/MockedStack_EditorThemeStoreTest.kt +++ b/example/src/androidTest/java/org/wordpress/android/fluxc/mocked/MockedStack_EditorThemeStoreTest.kt @@ -28,6 +28,7 @@ class MockedStack_EditorThemeStoreTest : MockedStack_Base() { private lateinit var countDownLatch: CountDownLatch private lateinit var site: SiteModel private lateinit var payload: FetchEditorThemePayload + private lateinit var payloadWithGSS: FetchEditorThemePayload private var editorTheme: EditorTheme? = null override fun setUp() { @@ -38,7 +39,9 @@ class MockedStack_EditorThemeStoreTest : MockedStack_Base() { site = SiteModel() site.setIsWPCom(true) + site.softwareVersion = "5.8" payload = FetchEditorThemePayload(site) + payloadWithGSS = FetchEditorThemePayload(site, true) countDownLatch = CountDownLatch(1) } @@ -134,6 +137,52 @@ class MockedStack_EditorThemeStoreTest : MockedStack_Base() { assertEmpty(themeBundle) } + @Test + fun testGlobalStylesSettingsOffSuccess() { + interceptor.respondWith("global-styles-off-success.json") + dispatcher.dispatch(EditorThemeActionBuilder.newFetchEditorThemeAction(payloadWithGSS)) + + // See onEditorThemeChanged for the latch's countdown to fire. + Assert.assertTrue(countDownLatch.await(TestUtils.DEFAULT_TIMEOUT_MS.toLong(), MILLISECONDS)) + + // Validate Callback + assertNotEmpty(editorTheme) + + // Validate Cache + val cachedTheme = editorThemeStore.getEditorThemeForSite(site) + assertNotEmpty(cachedTheme) + + // Validate Bundle + val themeBundle = editorTheme!!.themeSupport.toBundle() + assertNotEmpty(themeBundle) + } + + @Test + fun testGlobalStylesSettingsFullSuccess() { + interceptor.respondWith("global-styles-full-success.json") + dispatcher.dispatch(EditorThemeActionBuilder.newFetchEditorThemeAction(payloadWithGSS)) + + // See onEditorThemeChanged for the latch's countdown to fire. + Assert.assertTrue(countDownLatch.await(TestUtils.DEFAULT_TIMEOUT_MS.toLong(), MILLISECONDS)) + + // Validate Callback + assertEmpty(editorTheme) + Assert.assertNotNull(editorTheme?.themeSupport?.rawStyles) + + // Validate Cache + val cachedTheme = editorThemeStore.getEditorThemeForSite(site) + assertEmpty(cachedTheme) + Assert.assertNotNull(cachedTheme?.themeSupport?.rawStyles) + + // Validate Bundle + val themeBundle = editorTheme!!.themeSupport.toBundle() + assertEmpty(themeBundle) + val styles = themeBundle.getString("rawStyles") + val features = themeBundle.getString("rawFeatures") + Assert.assertNotNull(styles) + Assert.assertNotNull(features) + } + private fun assertNotEmpty(theme: EditorTheme?) { Assert.assertFalse(theme?.themeSupport?.colors.isNullOrEmpty()) Assert.assertFalse(theme?.themeSupport?.gradients.isNullOrEmpty()) diff --git a/example/src/androidTest/resources/global-styles-full-success.json b/example/src/androidTest/resources/global-styles-full-success.json new file mode 100644 index 0000000000..83ca032272 --- /dev/null +++ b/example/src/androidTest/resources/global-styles-full-success.json @@ -0,0 +1,537 @@ +{ + "__unstableEnableFullSiteEditingBlocks": true, + "alignWide": false, + "allowedBlockTypes": true, + "allowedMimeTypes": { + "jpg|jpeg|jpe": "image\/jpeg", + "gif": "image\/gif", + "png": "image\/png", + "bmp": "image\/bmp", + "tiff|tif": "image\/tiff", + "ico": "image\/x-icon", + "heic": "image\/heic", + "asf|asx": "video\/x-ms-asf", + "wmv": "video\/x-ms-wmv", + "wmx": "video\/x-ms-wmx", + "wm": "video\/x-ms-wm", + "avi": "video\/avi", + "divx": "video\/divx", + "flv": "video\/x-flv", + "mov|qt": "video\/quicktime", + "mpeg|mpg|mpe": "video\/mpeg", + "mp4|m4v": "video\/mp4", + "ogv": "video\/ogg", + "webm": "video\/webm", + "mkv": "video\/x-matroska", + "3gp|3gpp": "video\/3gpp", + "3g2|3gp2": "video\/3gpp2", + "txt|asc|c|cc|h|srt": "text\/plain", + "csv": "text\/csv", + "tsv": "text\/tab-separated-values", + "ics": "text\/calendar", + "rtx": "text\/richtext", + "css": "text\/css", + "htm|html": "text\/html", + "vtt": "text\/vtt", + "dfxp": "application\/ttaf+xml", + "mp3|m4a|m4b": "audio\/mpeg", + "aac": "audio\/aac", + "ra|ram": "audio\/x-realaudio", + "wav": "audio\/wav", + "ogg|oga": "audio\/ogg", + "flac": "audio\/flac", + "mid|midi": "audio\/midi", + "wma": "audio\/x-ms-wma", + "wax": "audio\/x-ms-wax", + "mka": "audio\/x-matroska", + "rtf": "application\/rtf", + "js": "application\/javascript", + "pdf": "application\/pdf", + "class": "application\/java", + "tar": "application\/x-tar", + "zip": "application\/zip", + "gz|gzip": "application\/x-gzip", + "rar": "application\/rar", + "7z": "application\/x-7z-compressed", + "psd": "application\/octet-stream", + "xcf": "application\/octet-stream", + "doc": "application\/msword", + "pot|pps|ppt": "application\/vnd.ms-powerpoint", + "wri": "application\/vnd.ms-write", + "xla|xls|xlt|xlw": "application\/vnd.ms-excel", + "mdb": "application\/vnd.ms-access", + "mpp": "application\/vnd.ms-project", + "docx": "application\/vnd.openxmlformats-officedocument.wordprocessingml.document", + "docm": "application\/vnd.ms-word.document.macroEnabled.12", + "dotx": "application\/vnd.openxmlformats-officedocument.wordprocessingml.template", + "dotm": "application\/vnd.ms-word.template.macroEnabled.12", + "xlsx": "application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "xlsm": "application\/vnd.ms-excel.sheet.macroEnabled.12", + "xlsb": "application\/vnd.ms-excel.sheet.binary.macroEnabled.12", + "xltx": "application\/vnd.openxmlformats-officedocument.spreadsheetml.template", + "xltm": "application\/vnd.ms-excel.template.macroEnabled.12", + "xlam": "application\/vnd.ms-excel.addin.macroEnabled.12", + "pptx": "application\/vnd.openxmlformats-officedocument.presentationml.presentation", + "pptm": "application\/vnd.ms-powerpoint.presentation.macroEnabled.12", + "ppsx": "application\/vnd.openxmlformats-officedocument.presentationml.slideshow", + "ppsm": "application\/vnd.ms-powerpoint.slideshow.macroEnabled.12", + "potx": "application\/vnd.openxmlformats-officedocument.presentationml.template", + "potm": "application\/vnd.ms-powerpoint.template.macroEnabled.12", + "ppam": "application\/vnd.ms-powerpoint.addin.macroEnabled.12", + "sldx": "application\/vnd.openxmlformats-officedocument.presentationml.slide", + "sldm": "application\/vnd.ms-powerpoint.slide.macroEnabled.12", + "onetoc|onetoc2|onetmp|onepkg": "application\/onenote", + "oxps": "application\/oxps", + "xps": "application\/vnd.ms-xpsdocument", + "odt": "application\/vnd.oasis.opendocument.text", + "odp": "application\/vnd.oasis.opendocument.presentation", + "ods": "application\/vnd.oasis.opendocument.spreadsheet", + "odg": "application\/vnd.oasis.opendocument.graphics", + "odc": "application\/vnd.oasis.opendocument.chart", + "odb": "application\/vnd.oasis.opendocument.database", + "odf": "application\/vnd.oasis.opendocument.formula", + "wp|wpd": "application\/wordperfect", + "key": "application\/vnd.apple.keynote", + "numbers": "application\/vnd.apple.numbers", + "pages": "application\/vnd.apple.pages" + }, + "blockCategories": [ + { + "slug": "text", + "title": "Text", + "icon": null + }, + { + "slug": "media", + "title": "Media", + "icon": null + }, + { + "slug": "design", + "title": "Design", + "icon": null + }, + { + "slug": "widgets", + "title": "Widgets", + "icon": null + }, + { + "slug": "theme", + "title": "Theme", + "icon": null + }, + { + "slug": "embed", + "title": "Embeds", + "icon": null + }, + { + "slug": "reusable", + "title": "Reusable Blocks", + "icon": null + } + ], + "isRTL": false, + "imageDefaultSize": "large", + "imageDimensions": { + "thumbnail": { + "width": 150, + "height": 150, + "crop": true + }, + "medium": { + "width": 300, + "height": 300, + "crop": false + }, + "large": { + "width": 1024, + "height": 1024, + "crop": false + } + }, + "imageEditing": true, + "imageSizes": [ + { + "slug": "thumbnail", + "name": "Thumbnail" + }, + { + "slug": "medium", + "name": "Medium" + }, + { + "slug": "large", + "name": "Large" + }, + { + "slug": "full", + "name": "Full Size" + } + ], + "maxUploadFileSize": 536870912, + "__experimentalStyles": { + "elements": { + "link": { + "color": { + "text": "var(--wp--preset--color--dark-gray)" + } + }, + "h1": { + "typography": { + "fontSize": "var(--wp--preset--font-size--gigantic)", + "lineHeight": "var(--wp--custom--line-height--page-title)", + "fontWeight": "var(--wp--custom--font-weight--normal)" + } + }, + "h2": { + "typography": { + "fontSize": "var(--wp--preset--font-size--extra-large)", + "lineHeight": "var(--wp--custom--line-height--heading)", + "fontWeight": "var(--wp--custom--font-weight--normal)" + } + }, + "h3": { + "typography": { + "fontSize": "calc(1.25 * var(--wp--preset--font-size--large))", + "lineHeight": "var(--wp--custom--line-height--heading)", + "fontWeight": "var(--wp--custom--font-weight--normal)" + } + }, + "h4": { + "typography": { + "fontSize": "var(--wp--preset--font-size--large)", + "lineHeight": "var(--wp--custom--line-height--heading)" + } + }, + "h5": { + "typography": { + "fontSize": "var(--wp--preset--font-size--small)", + "lineHeight": "var(--wp--custom--line-height--heading)" + } + }, + "h6": { + "typography": { + "fontSize": "var(--wp--preset--font-size--extra-small)", + "lineHeight": "var(--wp--custom--line-height--heading)" + } + } + }, + "color": { + "background": "var(--wp--preset--color--green)", + "text": "var(--wp--preset--color--dark-gray)" + }, + "typography": { + "fontSize": "var(--wp--preset--font-size--normal)", + "lineHeight": "var(--wp--custom--line-height--body)" + }, + "blocks": { + "core\/site-tagline": { + "typography": { + "fontSize": "var(--wp--preset--font-size--small)", + "lineHeight": 1.4 + } + }, + "core\/post-author": { + "typography": { + "fontSize": "var(--wp--preset--font-size--extra-small)", + "lineHeight": "var(--wp--custom--line-height--body)" + } + }, + "core\/post-date": { + "typography": { + "fontSize": "var(--wp--preset--font-size--extra-small)", + "lineHeight": "var(--wp--custom--line-height--body)" + } + }, + "core\/site-title": { + "typography": { + "fontSize": "var(--wp--preset--font-size--large)", + "fontWeight": "var(--wp--custom--font-weight--normal)", + "textTransform": "uppercase" + } + } + } + }, + "__experimentalFeatures": { + "color": { + "palette": [ + { + "slug": "black", + "color": "#000000", + "name": "Black" + }, + { + "slug": "dark-gray", + "color": "#28303D", + "name": "Dark Gray" + }, + { + "slug": "gray", + "color": "#39414D", + "name": "Gray" + }, + { + "slug": "green", + "color": "#D1E4DD", + "name": "Green" + }, + { + "slug": "blue", + "color": "#D1DFE4", + "name": "Blue" + }, + { + "slug": "purple", + "color": "#D1D1E4", + "name": "Purple" + }, + { + "slug": "red", + "color": "#E4D1D1", + "name": "Red" + }, + { + "slug": "orange", + "color": "#E4DAD1", + "name": "Orange" + }, + { + "slug": "yellow", + "color": "#EEEADD", + "name": "Yellow" + }, + { + "slug": "white", + "color": "#FFFFFF", + "name": "White" + } + ], + "gradients": [ + { + "slug": "purple-to-yellow", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--purple), var(--wp--preset--color--yellow))", + "name": "Purple to Yellow" + }, + { + "slug": "yellow-to-purple", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--yellow), var(--wp--preset--color--purple))", + "name": "Yellow to Purple" + }, + { + "slug": "green-to-yellow", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--green), var(--wp--preset--color--yellow))", + "name": "Green to Yellow" + }, + { + "slug": "yellow-to-green", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--yellow), var(--wp--preset--color--green))", + "name": "Yellow to Green" + }, + { + "slug": "red-to-yellow", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--red), var(--wp--preset--color--yellow))", + "name": "Red to Yellow" + }, + { + "slug": "yellow-to-red", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--yellow), var(--wp--preset--color--red))", + "name": "Yellow to Red" + }, + { + "slug": "purple-to-red", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--purple), var(--wp--preset--color--red))", + "name": "Purple to Red" + }, + { + "slug": "red-to-purple", + "gradient": "linear-gradient(160deg, var(--wp--preset--color--red), var(--wp--preset--color--purple))", + "name": "Red to Purple" + } + ], + "duotone": [ + { + "name": "Dark grayscale", + "colors": [ + "#000000", + "#7f7f7f" + ], + "slug": "dark-grayscale" + }, + { + "name": "Grayscale", + "colors": [ + "#000000", + "#ffffff" + ], + "slug": "grayscale" + }, + { + "name": "Purple and yellow", + "colors": [ + "#8c00b7", + "#fcff41" + ], + "slug": "purple-yellow" + }, + { + "name": "Blue and red", + "colors": [ + "#000097", + "#ff4747" + ], + "slug": "blue-red" + }, + { + "name": "Midnight", + "colors": [ + "#000000", + "#00a5ff" + ], + "slug": "midnight" + }, + { + "name": "Magenta and yellow", + "colors": [ + "#c7005a", + "#fff278" + ], + "slug": "magenta-yellow" + }, + { + "name": "Purple and green", + "colors": [ + "#a60072", + "#67ff66" + ], + "slug": "purple-green" + }, + { + "name": "Blue and orange", + "colors": [ + "#1900d8", + "#ffa96b" + ], + "slug": "blue-orange" + } + ], + "custom": true, + "link": false, + "customGradient": true + }, + "typography": { + "dropCap": true, + "customFontSize": true, + "customLineHeight": true, + "customFontStyle": true, + "customFontWeight": true, + "customTextTransforms": true, + "customTextDecorations": true, + "fontSizes": [ + { + "slug": "extra-small", + "size": "16px", + "name": "Extra small" + }, + { + "slug": "small", + "size": "18px", + "name": "Small" + }, + { + "slug": "normal", + "size": "20px", + "name": "Normal" + }, + { + "slug": "large", + "size": "24px", + "name": "Large" + }, + { + "slug": "extra-large", + "size": "40px", + "name": "Extra large" + }, + { + "slug": "huge", + "size": "96px", + "name": "Huge" + }, + { + "slug": "gigantic", + "size": "144px", + "name": "Gigantic" + } + ], + "fontFamilies": [ + { + "fontFamily": "-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell,\"Helvetica Neue\",sans-serif", + "slug": "system-font", + "name": "System Font" + }, + { + "fontFamily": "Helvetica Neue, Helvetica, Arial, sans-serif", + "slug": "helvetica-arial" + }, + { + "fontFamily": "Geneva, Tahoma, Verdana, sans-serif", + "slug": "geneva-verdana" + }, + { + "fontFamily": "Cambria, Georgia, serif", + "slug": "cambria-georgia" + }, + { + "fontFamily": "Hoefler Text, Baskerville Old Face, Garamond, Times New Roman, serif", + "slug": "hoefler-times-new-roman" + } + ] + }, + "spacing": { + "customPadding": true, + "units": [ + "px", + "em", + "rem", + "vh", + "vw" + ] + }, + "border": { + "customColor": false, + "customRadius": false, + "customStyle": false, + "customWidth": false + }, + "blocks": { + "core\/button": { + "border": { + "customRadius": true + } + } + }, + "layout": { + "contentSize": "610px", + "wideSize": "1240px" + }, + "custom": { + "font-primary": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif", + "line-height": { + "body": 1.7, + "heading": 1.3, + "page-title": 1.1 + }, + "spacing": { + "unit": "20px", + "horizontal": "25px", + "vertical": "30px" + }, + "font-weight": { + "light": "300", + "normal": "normal" + } + } + } +} \ No newline at end of file diff --git a/example/src/androidTest/resources/global-styles-off-success.json b/example/src/androidTest/resources/global-styles-off-success.json new file mode 100644 index 0000000000..d6f27e0dc9 --- /dev/null +++ b/example/src/androidTest/resources/global-styles-off-success.json @@ -0,0 +1,534 @@ +{ + "imageDefaultSize": "large", + "__unstableEnableFullSiteEditingBlocks": true, + "styles": [ + + ], + "supportsTemplateMode": true, + "supportsLayout": false, + "widgetTypesToHideFromLegacyWidgetBlock": [ + "pages", + "calendar", + "archives", + "media_audio", + "media_image", + "media_gallery", + "media_video", + "meta", + "search", + "text", + "categories", + "recent-posts", + "recent-comments", + "rss", + "tag_cloud", + "nav_menu", + "custom_html", + "block" + ], + "__experimentalFeatures": { + "defaults": { + "color": { + "palette": [ + { + "name": "Black", + "slug": "black", + "color": "#000000" + }, + { + "name": "Cyan bluish gray", + "slug": "cyan-bluish-gray", + "color": "#abb8c3" + }, + { + "name": "White", + "slug": "white", + "color": "#ffffff" + }, + { + "name": "Pale pink", + "slug": "pale-pink", + "color": "#f78da7" + }, + { + "name": "Vivid red", + "slug": "vivid-red", + "color": "#cf2e2e" + }, + { + "name": "Luminous vivid orange", + "slug": "luminous-vivid-orange", + "color": "#ff6900" + }, + { + "name": "Luminous vivid amber", + "slug": "luminous-vivid-amber", + "color": "#fcb900" + }, + { + "name": "Light green cyan", + "slug": "light-green-cyan", + "color": "#7bdcb5" + }, + { + "name": "Vivid green cyan", + "slug": "vivid-green-cyan", + "color": "#00d084" + }, + { + "name": "Pale cyan blue", + "slug": "pale-cyan-blue", + "color": "#8ed1fc" + }, + { + "name": "Vivid cyan blue", + "slug": "vivid-cyan-blue", + "color": "#0693e3" + }, + { + "name": "Vivid purple", + "slug": "vivid-purple", + "color": "#9b51e0" + } + ], + "gradients": [ + { + "name": "Vivid cyan blue to vivid purple", + "gradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)", + "slug": "vivid-cyan-blue-to-vivid-purple" + }, + { + "name": "Light green cyan to vivid green cyan", + "gradient": "linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)", + "slug": "light-green-cyan-to-vivid-green-cyan" + }, + { + "name": "Luminous vivid amber to luminous vivid orange", + "gradient": "linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)", + "slug": "luminous-vivid-amber-to-luminous-vivid-orange" + }, + { + "name": "Luminous vivid orange to vivid red", + "gradient": "linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)", + "slug": "luminous-vivid-orange-to-vivid-red" + }, + { + "name": "Very light gray to cyan bluish gray", + "gradient": "linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)", + "slug": "very-light-gray-to-cyan-bluish-gray" + }, + { + "name": "Cool to warm spectrum", + "gradient": "linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)", + "slug": "cool-to-warm-spectrum" + }, + { + "name": "Blush light purple", + "gradient": "linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)", + "slug": "blush-light-purple" + }, + { + "name": "Blush bordeaux", + "gradient": "linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)", + "slug": "blush-bordeaux" + }, + { + "name": "Luminous dusk", + "gradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)", + "slug": "luminous-dusk" + }, + { + "name": "Pale ocean", + "gradient": "linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)", + "slug": "pale-ocean" + }, + { + "name": "Electric grass", + "gradient": "linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)", + "slug": "electric-grass" + }, + { + "name": "Midnight", + "gradient": "linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)", + "slug": "midnight" + } + ], + "custom": true, + "link": true, + "customGradient": true + }, + "typography": { + "dropCap": true, + "customFontSize": true, + "customLineHeight": false, + "customFontStyle": true, + "customFontWeight": true, + "customTextTransforms": true, + "customTextDecorations": true, + "fontSizes": [ + { + "name": "Small", + "slug": "small", + "size": "13px" + }, + { + "name": "Normal", + "slug": "normal", + "size": "16px" + }, + { + "name": "Medium", + "slug": "medium", + "size": "20px" + }, + { + "name": "Large", + "slug": "large", + "size": "36px" + }, + { + "name": "Huge", + "slug": "huge", + "size": "42px" + } + ] + }, + "spacing": { + "customPadding": false, + "units": [ + "px", + "em", + "rem", + "vh", + "vw" + ] + }, + "border": { + "customColor": false, + "customRadius": false, + "customStyle": false, + "customWidth": false + } + }, + "core/button": { + "border": { + "customRadius": true + } + } + }, + "__experimentalGlobalStylesUserEntityId": 18, + "alignWide": true, + "allowedBlockTypes": true, + "allowedMimeTypes": { + "jpg|jpeg|jpe": "image/jpeg", + "gif": "image/gif", + "png": "image/png", + "bmp": "image/bmp", + "tiff|tif": "image/tiff", + "ico": "image/x-icon", + "heic": "image/heic", + "asf|asx": "video/x-ms-asf", + "wmv": "video/x-ms-wmv", + "wmx": "video/x-ms-wmx", + "wm": "video/x-ms-wm", + "avi": "video/avi", + "divx": "video/divx", + "flv": "video/x-flv", + "mov|qt": "video/quicktime", + "mpeg|mpg|mpe": "video/mpeg", + "mp4|m4v": "video/mp4", + "ogv": "video/ogg", + "webm": "video/webm", + "mkv": "video/x-matroska", + "3gp|3gpp": "video/3gpp", + "3g2|3gp2": "video/3gpp2", + "txt|asc|c|cc|h|srt": "text/plain", + "csv": "text/csv", + "tsv": "text/tab-separated-values", + "ics": "text/calendar", + "rtx": "text/richtext", + "css": "text/css", + "htm|html": "text/html", + "vtt": "text/vtt", + "dfxp": "application/ttaf+xml", + "mp3|m4a|m4b": "audio/mpeg", + "aac": "audio/aac", + "ra|ram": "audio/x-realaudio", + "wav": "audio/wav", + "ogg|oga": "audio/ogg", + "flac": "audio/flac", + "mid|midi": "audio/midi", + "wma": "audio/x-ms-wma", + "wax": "audio/x-ms-wax", + "mka": "audio/x-matroska", + "rtf": "application/rtf", + "js": "application/javascript", + "pdf": "application/pdf", + "class": "application/java", + "tar": "application/x-tar", + "zip": "application/zip", + "gz|gzip": "application/x-gzip", + "rar": "application/rar", + "7z": "application/x-7z-compressed", + "psd": "application/octet-stream", + "xcf": "application/octet-stream", + "doc": "application/msword", + "pot|pps|ppt": "application/vnd.ms-powerpoint", + "wri": "application/vnd.ms-write", + "xla|xls|xlt|xlw": "application/vnd.ms-excel", + "mdb": "application/vnd.ms-access", + "mpp": "application/vnd.ms-project", + "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "docm": "application/vnd.ms-word.document.macroEnabled.12", + "dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template", + "dotm": "application/vnd.ms-word.template.macroEnabled.12", + "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12", + "xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12", + "xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template", + "xltm": "application/vnd.ms-excel.template.macroEnabled.12", + "xlam": "application/vnd.ms-excel.addin.macroEnabled.12", + "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12", + "ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + "ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", + "potx": "application/vnd.openxmlformats-officedocument.presentationml.template", + "potm": "application/vnd.ms-powerpoint.template.macroEnabled.12", + "ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12", + "sldx": "application/vnd.openxmlformats-officedocument.presentationml.slide", + "sldm": "application/vnd.ms-powerpoint.slide.macroEnabled.12", + "onetoc|onetoc2|onetmp|onepkg": "application/onenote", + "oxps": "application/oxps", + "xps": "application/vnd.ms-xpsdocument", + "odt": "application/vnd.oasis.opendocument.text", + "odp": "application/vnd.oasis.opendocument.presentation", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "odg": "application/vnd.oasis.opendocument.graphics", + "odc": "application/vnd.oasis.opendocument.chart", + "odb": "application/vnd.oasis.opendocument.database", + "odf": "application/vnd.oasis.opendocument.formula", + "wp|wpd": "application/wordperfect", + "key": "application/vnd.apple.keynote", + "numbers": "application/vnd.apple.numbers", + "pages": "application/vnd.apple.pages" + }, + "blockCategories": [ + { + "slug": "text", + "title": "Text", + "icon": null + }, + { + "slug": "media", + "title": "Media", + "icon": null + }, + { + "slug": "design", + "title": "Design", + "icon": null + }, + { + "slug": "widgets", + "title": "Widgets", + "icon": null + }, + { + "slug": "theme", + "title": "Theme", + "icon": null + }, + { + "slug": "embed", + "title": "Embeds", + "icon": null + }, + { + "slug": "reusable", + "title": "Reusable Blocks", + "icon": null + } + ], + "disableCustomColors": false, + "disableCustomFontSizes": false, + "disableCustomGradients": false, + "enableCustomLineHeight": true, + "enableCustomSpacing": true, + "enableCustomUnits": true, + "isRTL": false, + "imageDimensions": { + "thumbnail": { + "width": 150, + "height": 150, + "crop": true + }, + "medium": { + "width": 300, + "height": 300, + "crop": false + }, + "large": { + "width": 1024, + "height": 1024, + "crop": false + } + }, + "imageEditing": true, + "imageSizes": [ + { + "slug": "thumbnail", + "name": "Thumbnail" + }, + { + "slug": "medium", + "name": "Medium" + }, + { + "slug": "large", + "name": "Large" + }, + { + "slug": "full", + "name": "Full Size" + } + ], + "maxUploadFileSize": 2097152, + "colors": [ + { + "name": "Black", + "slug": "black", + "color": "#000000" + }, + { + "name": "Dark gray", + "slug": "dark-gray", + "color": "#28303D" + }, + { + "name": "Gray", + "slug": "gray", + "color": "#39414D" + }, + { + "name": "Green", + "slug": "green", + "color": "#D1E4DD" + }, + { + "name": "Blue", + "slug": "blue", + "color": "#D1DFE4" + }, + { + "name": "Purple", + "slug": "purple", + "color": "#D1D1E4" + }, + { + "name": "Red", + "slug": "red", + "color": "#E4D1D1" + }, + { + "name": "Orange", + "slug": "orange", + "color": "#E4DAD1" + }, + { + "name": "Yellow", + "slug": "yellow", + "color": "#EEEADD" + }, + { + "name": "White", + "slug": "white", + "color": "#FFFFFF" + } + ], + "fontSizes": [ + { + "name": "Extra small", + "shortName": "XS", + "size": 16, + "slug": "extra-small" + }, + { + "name": "Small", + "shortName": "S", + "size": 18, + "slug": "small" + }, + { + "name": "Normal", + "shortName": "M", + "size": 20, + "slug": "normal" + }, + { + "name": "Large", + "shortName": "L", + "size": 24, + "slug": "large" + }, + { + "name": "Extra large", + "shortName": "XL", + "size": 40, + "slug": "extra-large" + }, + { + "name": "Huge", + "shortName": "XXL", + "size": 96, + "slug": "huge" + }, + { + "name": "Gigantic", + "shortName": "XXXL", + "size": 144, + "slug": "gigantic" + } + ], + "gradients": [ + { + "name": "Purple to yellow", + "gradient": "linear-gradient(160deg, #D1D1E4 0%, #EEEADD 100%)", + "slug": "purple-to-yellow" + }, + { + "name": "Yellow to purple", + "gradient": "linear-gradient(160deg, #EEEADD 0%, #D1D1E4 100%)", + "slug": "yellow-to-purple" + }, + { + "name": "Green to yellow", + "gradient": "linear-gradient(160deg, #D1E4DD 0%, #EEEADD 100%)", + "slug": "green-to-yellow" + }, + { + "name": "Yellow to green", + "gradient": "linear-gradient(160deg, #EEEADD 0%, #D1E4DD 100%)", + "slug": "yellow-to-green" + }, + { + "name": "Red to yellow", + "gradient": "linear-gradient(160deg, #E4D1D1 0%, #EEEADD 100%)", + "slug": "red-to-yellow" + }, + { + "name": "Yellow to red", + "gradient": "linear-gradient(160deg, #EEEADD 0%, #E4D1D1 100%)", + "slug": "yellow-to-red" + }, + { + "name": "Purple to red", + "gradient": "linear-gradient(160deg, #D1D1E4 0%, #E4D1D1 100%)", + "slug": "purple-to-red" + }, + { + "name": "Red to purple", + "gradient": "linear-gradient(160deg, #E4D1D1 0%, #D1D1E4 100%)", + "slug": "red-to-purple" + } + ] +} \ No newline at end of file diff --git a/fluxc/src/main/java/org/wordpress/android/fluxc/model/EditorTheme.kt b/fluxc/src/main/java/org/wordpress/android/fluxc/model/EditorTheme.kt index 88d18698b6..6a28b436b9 100644 --- a/fluxc/src/main/java/org/wordpress/android/fluxc/model/EditorTheme.kt +++ b/fluxc/src/main/java/org/wordpress/android/fluxc/model/EditorTheme.kt @@ -17,17 +17,32 @@ const val MAP_KEY_ELEMENT_DISPLAY_NAME: String = "name" const val MAP_KEY_ELEMENT_SLUG: String = "slug" const val MAP_KEY_ELEMENT_COLORS: String = "colors" const val MAP_KEY_ELEMENT_GRADIENTS: String = "gradients" +const val MAP_KEY_ELEMENT_STYLES: String = "rawStyles" +const val MAP_KEY_ELEMENT_FEATURES: String = "rawFeatures" data class EditorTheme( @SerializedName("theme_supports") val themeSupport: EditorThemeSupport, val stylesheet: String?, val version: String? ) { + constructor(blockEditorSettings: BlockEditorSettings) : this( + themeSupport = EditorThemeSupport( + blockEditorSettings.colors, + blockEditorSettings.gradients, + blockEditorSettings.styles.toString(), + blockEditorSettings.features.toString() + ), + stylesheet = null, + version = null + ) + fun toBuilder(siteId: Int): EditorThemeBuilder { val element = EditorThemeBuilder() element.localSiteId = siteId element.stylesheet = stylesheet element.version = version + element.rawStyles = themeSupport.rawStyles + element.rawFeatures = themeSupport.rawFeatures return element } @@ -35,20 +50,29 @@ data class EditorTheme( override fun equals(other: Any?): Boolean { if (other == null || other !is EditorTheme || - stylesheet != other.stylesheet || - version != other.version) return false + themeSupport != other.themeSupport) return false return true } } +data class BlockEditorSettings( + @SerializedName("__unstableEnableFullSiteEditingBlocks") val isFSETheme: Boolean, + @SerializedName("__experimentalStyles") val styles: JsonElement?, + @SerializedName("__experimentalFeatures") val features: JsonElement?, + @JsonAdapter(EditorThemeElementListSerializer::class) val colors: List?, + @JsonAdapter(EditorThemeElementListSerializer::class) val gradients: List? +) + data class EditorThemeSupport( @JsonAdapter(EditorThemeElementListSerializer::class) @SerializedName("editor-color-palette") val colors: List?, @JsonAdapter(EditorThemeElementListSerializer::class) @SerializedName("editor-gradient-presets") - val gradients: List? + val gradients: List?, + val rawStyles: String?, + val rawFeatures: String? ) { fun toBundle(): Bundle { val bundle = Bundle() @@ -61,6 +85,14 @@ data class EditorThemeSupport( bundle.putParcelableArrayList(MAP_KEY_ELEMENT_GRADIENTS, ArrayList(it)) } + rawStyles?.let { + bundle.putString(MAP_KEY_ELEMENT_STYLES, it) + } + + rawFeatures?.let { + bundle.putString(MAP_KEY_ELEMENT_FEATURES, it) + } + return bundle } } diff --git a/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/EditorThemeSqlUtils.kt b/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/EditorThemeSqlUtils.kt index c9e628a1e2..5d2c463ff9 100644 --- a/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/EditorThemeSqlUtils.kt +++ b/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/EditorThemeSqlUtils.kt @@ -84,6 +84,8 @@ class EditorThemeSqlUtils { set @Column var stylesheet: String? = null @Column var version: String? = null + @Column var rawStyles: String? = null + @Column var rawFeatures: String? = null override fun setId(id: Int) { this.mId = id @@ -105,7 +107,7 @@ class EditorThemeSqlUtils { gradients = storedGradients.mapNotNull { it.toEditorThemeElement() } } - val editorThemeSupport = EditorThemeSupport(colors, gradients) + val editorThemeSupport = EditorThemeSupport(colors, gradients, rawStyles, rawFeatures) return EditorTheme(editorThemeSupport, stylesheet, version) } diff --git a/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt b/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt index 1e6e57934a..76ba178246 100644 --- a/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt +++ b/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt @@ -30,7 +30,7 @@ open class WellSqlConfig : DefaultWellConfig { annotation class AddOn override fun getDbVersion(): Int { - return 154 + return 155 } override fun getDbName(): String { @@ -1776,6 +1776,19 @@ open class WellSqlConfig : DefaultWellConfig { 153 -> migrateAddOn(ADDON_WOOCOMMERCE, version) { db.execSQL("ALTER TABLE WCOrderModel ADD META_DATA TEXT") } + 154 -> migrate(version) { + db.execSQL("DROP TABLE IF EXISTS EditorTheme") + db.execSQL( + "CREATE TABLE EditorTheme(" + + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + + "LOCAL_SITE_ID INTEGER," + + "STYLESHEET TEXT," + + "VERSION TEXT," + + "RAW_STYLES TEXT," + + "RAW_FEATURES TEXT," + + "FOREIGN KEY(LOCAL_SITE_ID) REFERENCES SiteModel(_id) ON DELETE CASCADE)" + ) + } } } db.setTransactionSuccessful() diff --git a/fluxc/src/main/java/org/wordpress/android/fluxc/store/EditorThemeStore.kt b/fluxc/src/main/java/org/wordpress/android/fluxc/store/EditorThemeStore.kt index 2f458a9323..f7f2318911 100644 --- a/fluxc/src/main/java/org/wordpress/android/fluxc/store/EditorThemeStore.kt +++ b/fluxc/src/main/java/org/wordpress/android/fluxc/store/EditorThemeStore.kt @@ -8,6 +8,7 @@ import org.wordpress.android.fluxc.Payload import org.wordpress.android.fluxc.action.EditorThemeAction import org.wordpress.android.fluxc.action.EditorThemeAction.FETCH_EDITOR_THEME import org.wordpress.android.fluxc.annotations.action.Action +import org.wordpress.android.fluxc.model.BlockEditorSettings import org.wordpress.android.fluxc.model.EditorTheme import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.network.BaseRequest.BaseNetworkError @@ -16,9 +17,14 @@ import org.wordpress.android.fluxc.store.ReactNativeFetchResponse.Error import org.wordpress.android.fluxc.store.ReactNativeFetchResponse.Success import org.wordpress.android.fluxc.tools.CoroutineEngine import org.wordpress.android.util.AppLog +import org.wordpress.android.util.helpers.Version import javax.inject.Inject import javax.inject.Singleton +private const val THEME_REQUEST_PATH = "/wp/v2/themes?status=active" +private const val GSS_REQUEST_PATH = "__experimental/wp-block-editor/v1/settings?context=mobile" +private const val GSS_LIMIT_VERSION = "5.8" + @Singleton class EditorThemeStore @Inject constructor( @@ -26,17 +32,10 @@ class EditorThemeStore private val coroutineEngine: CoroutineEngine, dispatcher: Dispatcher ) : Store(dispatcher) { - private val THEME_REQUEST_PATH = "/wp/v2/themes?status=active" private val editorThemeSqlUtils = EditorThemeSqlUtils() - class FetchEditorThemePayload(val site: SiteModel) : Payload() { - constructor( - error: BaseNetworkError, - site: SiteModel - ) : this(site = site) { - this.error = error - } - } + class FetchEditorThemePayload @JvmOverloads constructor(val site: SiteModel, val gssEnabled: Boolean = false) : + Payload() data class OnEditorThemeChanged( val editorTheme: EditorTheme?, @@ -59,19 +58,24 @@ class EditorThemeStore val actionType = action.type as? EditorThemeAction ?: return when (actionType) { FETCH_EDITOR_THEME -> { - coroutineEngine.launch( - AppLog.T.API, - this, - TransactionsStore::class.java.simpleName + ": On FETCH_EDITOR_THEME" - ) { - handleFetchEditorTheme((action.payload as FetchEditorThemePayload).site, actionType) + coroutineEngine.launch( + AppLog.T.API, + this, + EditorThemeStore::class.java.simpleName + ": On FETCH_EDITOR_THEME" + ) { + val payload = action.payload as FetchEditorThemePayload + if (globalStyleSettingsAvailable(payload.site, payload.gssEnabled)) { + handleFetchGlobalStylesSettings(payload.site, actionType) + } else { + handleFetchEditorTheme(payload.site, actionType) + } + } } } - } } override fun onRegister() { - AppLog.d(AppLog.T.API, TransactionsStore::class.java.simpleName + " onRegister") + AppLog.d(AppLog.T.API, EditorThemeStore::class.java.simpleName + " onRegister") } private suspend fun handleFetchEditorTheme(site: SiteModel, action: EditorThemeAction) { @@ -105,4 +109,40 @@ class EditorThemeStore } } } + + private suspend fun handleFetchGlobalStylesSettings(site: SiteModel, action: EditorThemeAction) { + val response = reactNativeStore.executeRequest(site, GSS_REQUEST_PATH, false) + + when (response) { + is Success -> { + val noGssError = OnEditorThemeChanged(EditorThemeError("Response does not contain GSS"), action) + if (response.result == null || !response.result.isJsonObject) { + emitChange(noGssError) + return + } + + val responseTheme = response.result.asJsonObject + if (responseTheme == null) { + emitChange(noGssError) + return + } + + val blockEditorSettings = Gson().fromJson(responseTheme, BlockEditorSettings::class.java) + val newTheme = EditorTheme(blockEditorSettings) + val existingTheme = editorThemeSqlUtils.getEditorThemeForSite(site) + if (newTheme != existingTheme) { + editorThemeSqlUtils.replaceEditorThemeForSite(site, newTheme) + val onChanged = OnEditorThemeChanged(newTheme, site.id, action) + emitChange(onChanged) + } + } + is Error -> { + val onChanged = OnEditorThemeChanged(EditorThemeError(response.error.message), action) + emitChange(onChanged) + } + } + } + + private fun globalStyleSettingsAvailable(site: SiteModel, gssEnabled: Boolean) = + gssEnabled && Version(site.softwareVersion) >= Version(GSS_LIMIT_VERSION) }