diff --git a/.distignore b/.distignore index ea9e7a7..889f2aa 100644 --- a/.distignore +++ b/.distignore @@ -5,5 +5,7 @@ /bundled /node_modules +*.zip + .distignore .gitignore diff --git a/.eslintrc.js b/.eslintrc.js index 64fc54d..806e371 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,19 +4,30 @@ module.exports = { es6: true, node: true }, + settings: { + "react": { + "version": "detect" + } + }, + parser: "@babel/eslint-parser", extends: ["eslint:recommended", "prettier", "plugin:react/recommended"], globals: { Atomics: "readonly", SharedArrayBuffer: "readonly", - wp: "readonly" + wp: "readonly", + Lemonsqueezy: "readonly" }, - parser: "babel-eslint", + parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 2018, - sourceType: "module" + requireConfigFile: false, + sourceType: "module", + babelOptions: { + "presets": ["@babel/preset-react"] + }, }, plugins: ["react"], rules: { diff --git a/.gitignore b/.gitignore index c256da7..414728e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ /node_modules /bundled /dist +/build /vendor/ .DS_STORE .wp-env.json +*.zip \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 773eabe..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,21 +0,0 @@ -const gulp = require("gulp"); -const zip = require("gulp-zip"); - -function bundle() { - return gulp - .src([ - "**/*", - "!node_modules/**", - "!bundled/**", - "!gulpfile.js", - "!package.json", - "!package-lock.json", - "!webpack.config.js", - "!phpcs.xml", - "!yarn.lock" - ]) - .pipe(zip("lemonsqueezy.zip")) - .pipe(gulp.dest("bundled")); -} - -exports.bundle = bundle; diff --git a/lemonsqueezy.php b/lemonsqueezy.php index 4ed6adf..9ac10b8 100644 --- a/lemonsqueezy.php +++ b/lemonsqueezy.php @@ -9,7 +9,7 @@ * Plugin Name: Lemon Squeezy * Plugin URI: https://www.lemonsqueezy.com * Description: Sell digital products the easy-peasy way directly from WordPress. - * Version: 1.2.2 + * Version: 1.3.0 * Requires at least: 5.3 * Requires PHP: 7.0 * Author: Lemon Squeezy diff --git a/package.json b/package.json index a97427e..5a40f14 100644 --- a/package.json +++ b/package.json @@ -1,84 +1,44 @@ { - "name": "lemonsqueezy", - "private": true, - "scripts": { - "checkFormat": "prettier --check \"./src/**/*.{js,json,css,scss}\"", - "format": "prettier --write \"./src/**/*.{js,json,css,scss}\"", - "lint": "eslint src", - "start": "webpack --mode=development --watch", - "build": "npm run lint && webpack --mode=production && gulp bundle", - "wp-env": "wp-env" - }, - "repository": { - "type": "git", - "url": "https://github.com/Make-Lemonade/lemonsqueezy-wp.git" - }, - "lint-staged": { - "linters": { - "src/**/*.js": "eslint", - "**/*.{js,json,css,scss}": [ - "prettier --write", - "git add" - ] - } - }, - "author": "lemonsqueezy", - "license": "GPL-2.0+", - "bugs": { - "url": "https://github.com/Make-Lemonade/lemonsqueezy-wp/issues" - }, - "homepage": "https://github.com/Make-Lemonade/lemonsqueezy-wp#readme", - "dependencies": { - "@wordpress/blob": "^2.13.0", - "@wordpress/block-editor": "^3.9.1", - "@wordpress/blocks": "^6.14.1", - "@wordpress/compose": "^3.25.0", - "@wordpress/data": "^4.27.0", - "@wordpress/edit-post": "^3.15.1", - "@wordpress/html-entities": "^2.11.0", - "@wordpress/i18n": "^3.19.0", - "@wordpress/plugins": "^2.25.0", - "react": "^17.0.1", - "react-dom": "^17.0.1", - "react-sortable-hoc": "^1.11.0" - }, - "devDependencies": { - "@babel/core": "^7.13.10", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/preset-env": "^7.13.10", - "@babel/preset-react": "^7.12.13", - "@wordpress/browserslist-config": "^3.0.1", - "@wordpress/components": "^13.0.0", - "@wordpress/editor": "^9.14.1", - "@wordpress/element": "^2.20.0", - "@wordpress/env": "^4.1.2", - "autoprefixer": "^10.2.5", - "babel-eslint": "^10.0.1", - "babel-loader": "^8.2.2", - "browserslist": "^4.16.8", - "classnames": "^2.2.6", - "clean-webpack-plugin": "^3.0.0", - "css-loader": "^5.1.3", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.1.0", - "eslint-loader": "^2.1.2", - "eslint-plugin-react": "^7.22.0", - "file-loader": "^6.2.0", - "gulp": "^4.0.2", - "gulp-zip": "^4.2.0", - "lint-staged": "^10.5.4", - "loadash": "^1.0.0", - "mini-css-extract-plugin": "^1.3.9", - "node-sass": "^7.0.1", - "optimize-css-assets-webpack-plugin": "^6.0.1", - "postcss-loader": "^3.0.0", - "prettier": "^2.2.1", - "sass-loader": "^11.0.1", - "style-loader": "^2.0.0", - "webpack": "^5.26.3", - "webpack-cli": "^4.5.0" - }, - "browserslist": [ - "extends @wordpress/browserslist-config" - ] + "name": "lemonsqueezy", + "files": [ + "src", + "build", + "images", + "languages", + "lemonsqueezy.php", + "uninstall.php", + "readme.txt", + "changelog.*", + "license.*" + ], + "private": true, + "scripts": { + "build": "wp-scripts lint-js && wp-scripts build src/script.js src/editor.js src/admin/admin.js && yarn plugin-zip", + "check-engines": "wp-scripts check-engines", + "check-licenses": "wp-scripts check-licenses", + "format": "wp-scripts format", + "lint:js": "wp-scripts lint-js", + "lint:pkg-json": "wp-scripts lint-pkg-json", + "packages-update": "wp-scripts packages-update", + "plugin-zip": "wp-scripts plugin-zip && move-file lemonsqueezy.zip bundled/lemonsqueezy.zip", + "start": "wp-scripts start src/script.js src/editor.js src/admin/admin.js" + }, + "author": "lemonsqueezy", + "license": "GPL-2.0+", + "bugs": { + "url": "https://github.com/Make-Lemonade/lemonsqueezy-wp/issues" + }, + "homepage": "https://github.com/Make-Lemonade/lemonsqueezy-wp#readme", + "repository": { + "type": "git", + "url": "https://github.com/Make-Lemonade/lemonsqueezy-wp.git" + }, + "devDependencies": { + "@babel/eslint-parser": "^7.5.4", + "@wordpress/scripts": "^26.16.0", + "move-file-cli": "^3.0.0" + }, + "dependencies": { + "standard": "^17.1.0" + } } diff --git a/readme.txt b/readme.txt index 1773ad7..8b19fda 100644 --- a/readme.txt +++ b/readme.txt @@ -3,8 +3,8 @@ Contributors: lemonsqueezy, gilbitron, jamesckemp, patrickposner Donate link: [https://lemonsqueezy.com](https://lemonsqueezy.com/) Tags: lemon squeezy, ecommerce, digital products, checkout, payments, subscriptions, memberships, licenses Requires at least: 5.3 -Tested up to: 6.0.2 -Stable tag: 1.2.2 +Tested up to: 6.4.1 +Stable tag: 1.3.0 Requires PHP: 7.0 License: GPLv2 or later License URI: [https://www.gnu.org/licenses/gpl-2.0.html](https://www.gnu.org/licenses/gpl-2.0.html) @@ -130,6 +130,15 @@ Any digital product you can dream of. Digital downloads, licensed software, eboo == Changelog == += 1.3.0 = + +- Improved performance of Lemon Squeezy in Block Editor on core Buttons +- Added option to pre-fill logged-in user's data on Checkout +- Added option to pre-fill data from URL query string following the same checkout pre-fill pattern +- Added option to define Custom Data when using LS button block +- Added option to define text and background colors for LS button block +- Added option to enter Test API key and with that enable Test Mode + = 1.2.2 = - Minor bug fix diff --git a/src/admin/admin.js b/src/admin/admin.js index 09da8b2..b694041 100644 --- a/src/admin/admin.js +++ b/src/admin/admin.js @@ -26,7 +26,11 @@ class AdminSettings extends Component { isSettingsLoaded: false, isAPILoading: false, isAPISaving: false, + isTestAPISaving: false, lsqApiKey: "", + lsqApiKeyTest: "", + showingTestInput: false, + enteredApiKeyTest: "", lsqUser: null, oauth: window.lsq_oauth || {} }; @@ -40,6 +44,7 @@ class AdminSettings extends Component { this.settings.fetch().then(response => { this.setState({ lsqApiKey: response.lsq_api_key, + lsqApiKeyTest: response.lsq_api_key_test, isSettingsLoaded: true }); @@ -49,6 +54,68 @@ class AdminSettings extends Component { }); } + removeTestKey() { + this.setState({isTestAPISaving: true}); + + return fetch("/wp-json/lsq/v1/delete_test_key", { + method: 'DELETE', + credentials: 'same-origin', + headers: new Headers({ + 'Content-Type': 'application/json;charset=UTF-8', + 'X-WP-Nonce' : Lemonsqueezy.nonce + }) + }) + .then(response => response.json()) + .then(response => { + if (true == response.success) { + this.setState({ + lsqApiKeyTest: '', + isTestAPISaving: false + }); + } else { + this.setState({ + isTestAPISaving: false, + }); + + if ( response.error ) { + alert( response.error ); + } + } + }); + } + + saveTestApiKey() { + this.setState({isTestAPISaving: true}); + + return fetch("/wp-json/lsq/v1/save_test_key", { + method: 'POST', + credentials: 'same-origin', + headers: new Headers({ + 'Content-Type': 'application/json;charset=UTF-8', + 'X-WP-Nonce' : Lemonsqueezy.nonce + }), + body: JSON.stringify({ test_key: this.state.enteredApiKeyTest }), + }) + .then(response => response.json()) + .then(response => { + if (true == response.success) { + this.setState({ + lsqApiKeyTest: this.state.enteredApiKeyTest, + isTestAPISaving: false + }); + } else { + this.setState({ + isTestAPISaving: false, + lsqApiKeyTest: '', + }); + + if ( response.error ) { + alert( response.error ); + } + } + }); + } + checkApi() { this.setState({ isAPILoading: true @@ -99,6 +166,10 @@ class AdminSettings extends Component { }); } + saveTestKey() { + this.saveTestApiKey(); + } + render() { const panelLabel = this.state.lsqUser ? __("Connected to Lemon Squeezy", "lemonsqueezy") @@ -259,10 +330,9 @@ class AdminSettings extends Component { )}
You're on Test Mode.
+ + >} + + >} {!this.state.lsqUser && ( + )}
-
- {this.state
- .isLoadingProducts ? (
-
+ const settings = () => {
+ return this.state ? (
+ [
+ this.state.isApiConnectable ? (
+
+
+ {this.state
+ .isLoadingProducts ? (
+
{__(
"Loading...",
"lemonsqueezy"
)}
- ) : this.state.products
- .length ? (
-
-
-
- {__(
- "Uh oh! Looks like you haven't connected your store yet! Please visit the",
+ )}
+
+
-
- {__(
- "We're fetching your data, hold on for a second!",
+
+
+ {this.state.checkingApi && {__( + "Checking connection status", + "lemonsqueezy" + )}} + + {!this.state.checkingApi && + {__( + "Uh oh! Looks like you haven't connected your store yet! Please visit the", + "lemonsqueezy" + )}{" "} + + {__( + "Lemon Squeezy Settings", + "lemonsqueezy" + )} + {" "} + {__( + "and connect to Lemon Squeezy.", + "lemonsqueezy" + )} + } +
+ ) + ] + ) : ( ++ + {__( + "We're fetching your data, hold on for a second!", + "lemonsqueezy" )} + +
+ ) + } + + return ( +
+
+
+
+
+ Custom Data
+
+
+
@@ -244,4 +417,4 @@ class Edit extends Component { } } -export default Edit; +export default withColors('backgroundColor', {textColor: 'color'})(Edit); diff --git a/src/blocks/ls-button/index.js b/src/blocks/ls-button/index.js index a11d708..79f3693 100644 --- a/src/blocks/ls-button/index.js +++ b/src/blocks/ls-button/index.js @@ -1,5 +1,6 @@ import "./styles.editor.scss"; import { registerBlockType } from "@wordpress/blocks"; +import { getColorClassName } from "@wordpress/block-editor"; import { __ } from "@wordpress/i18n"; import Edit from "./edit"; @@ -15,6 +16,30 @@ const attributes = { }, product: { type: "string" + }, + textColor: { + type: 'string' + }, + customTextColor: { + type: 'string' + }, + backgroundColor: { + type: 'string' + }, + customBackgroundColor: { + type: 'string' + }, + prefillUserData: { + type: "boolean", + default: false + }, + prefillFromURL: { + type: "boolean", + default: false + }, + customData: { + type: "array", + default: [] } }; @@ -53,28 +78,65 @@ registerBlockType("lemonsqueezy/ls-button", { __("digital products", "lemonsqueezy") ], attributes, - deprecated: [], + deprecated: [{ + attributes, + save: ({ attributes }) => { + const { content, overlay, product } = attributes; + let link = product; + let className = [ + 'wp-block-button__link', + ]; + + if ( overlay ) { + className.push('lemonsqueezy-button'); + link = product + "?embed=1"; + } + + return ( +