diff --git a/.gitignore b/.gitignore index 135f8327..80501a21 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ # Build Files /build/ + +# Temperary Files +/tmp/ diff --git a/includes/restapi/class-notification-controller.php b/includes/restapi/class-notification-controller.php index 6351d5fe..ea710179 100644 --- a/includes/restapi/class-notification-controller.php +++ b/includes/restapi/class-notification-controller.php @@ -73,7 +73,7 @@ public function authenticate() : bool { * @return WP_REST_RESPONSE|WP_Error REST response or WP Error */ public function get_notifications( $request ) { - $demo_data = file_get_contents( dirname( __FILE__ ) . '/fake_api.json' ); + $demo_data = file_get_contents( WP_NOTIFICATION_CENTER_PLUGIN_DIR . '/tmp/demo-data.json' ); if ( empty( $demo_data ) ) { return new WP_Error( 'demo', __( 'Could not read demo data.' ) ); diff --git a/includes/restapi/fake_api.json b/includes/restapi/fake_api.json deleted file mode 100644 index 485f45e6..00000000 --- a/includes/restapi/fake_api.json +++ /dev/null @@ -1,202 +0,0 @@ -[ - { - "id": 1, - "context": "dashboard", - "title": "Try this new Notification feature", - "source": "#WP-Notify", - "date": 1664992015, - "message": "We have just added a wonderful feature! You might want to give it a try so click on the bell icon on the right side of the adminbar.", - "icon": { - "src": "https://raw.githubusercontent.com/erikyo/wp-notify/design_implementation/src/images/i.svg" - }, - "action": { - "acceptMessage": "Try this new feature", - "acceptLink": "https://github.com/WordPress/wp-notify", - "dismissible": false - } - }, - { - "id": 2, - "context": "dashboard", - "title": "Message variant #1", - "date": 1654866071, - "message": "This is an example of on-page message variant #1. It has a title, a message, an image, an action button with a URL, is dismissable.", - "source": "#Test", - "icon": { - "src": "https://source.unsplash.com/random/400×400/?notify" - }, - "action": { - "acceptMessage": "TEST", - "acceptLink": "https://github.com/WordPress/wp-notify", - "dismissible": true, - "unread": true - } - }, - { - "id": 3, - "title": "Message variant #1 (copy)", - "date": 1654866081, - "action": { - "acceptMessage": "TEST", - "acceptLink": "https://github.com/WordPress/wp-notify" - } - }, - { - "id": 4, - "context": "adminbar", - "title": "Message variant #2", - "source": "#WP-Notify", - "date": 1654866091, - "message": "This is an example of on-page message variant #2. It has a title, a message, a custom date, an action button with a URL, is dismissable, but has no images.", - "action": { - "acceptMessage": "OK", - "acceptLink": "https://github.com/WordPress/wp-notify", - "dismissible": true, - "unread": true - } - }, - { - "id": 5, - "context": "dashboard", - "date": 1654866101, - "title": "Message variant #3", - "message": "if you're wondering where notice #2 is try looking at the adminbar at the top right near the bell icon 😉.", - "icon": { - "src": "https://gifimage.net/wp-content/uploads/2018/10/animation-notification-gif-2.gif" - }, - "action": { - "acceptLink": "https://github.com/WordPress/wp-notify", - "dismissible": true, - "unread": true - } - }, - { - "id": 6, - "title": "WordPress", - "message": "WordPress was successfully updated to version 6.1", - "date": 1664992015, - "source": "WordPress", - "action": { - "acceptMessage": "Read what's new in 6.1", - "acceptLink": "#", - "unread": true - } - }, - { - "id": 7, - "message": "WordPress was successfully updated to version 5.9.", - "source": "WordPress", - "date": 1654866081, - "image": { - "svg": "" - } - }, - { - "id": 8, - "title": "WordPress", - "message": "WordPress was successfully updated to version 6.1", - "source": "WordPress", - "date": 1654850000, - "action": { - "acceptMessage": "Read what's new in 6.1", - "acceptLink": "#" - } - }, - { - "id": 9, - "title": "WordPress", - "message": "WordPress was successfully updated to version 6.1", - "action": { - "acceptMessage": "Read what's new in 6.1", - "acceptLink": "#", - "source": "WordPress", - "date": 1654840000 - } - }, - { - "id": 10, - "message": "There is a new version of Contact Form 7 available.", - "date": 1654830000, - "icon": { - "src": "https://ps.w.org/contact-form-7/assets/icon-256x256.png" - }, - "action": { - "acceptMessage": "Update now", - "acceptLink": "#", - "source": "Plugins Updates" - } - }, - { - "id": 11, - "title": "Akismet", - "source": "Akismet", - "date": 1654820000, - "icon": { - "src": "https://ps.w.org/akismet/assets/icon-256x256.png" - }, - "action": { - "acceptMessage": "Your API key is no longer valid.", - "acceptLink": "#" - } - }, - { - "id": 12, - "title": "Default", - "acceptLink": "#", - "source": "Wordpress", - "date": 1654800000, - "icon": { - "dashicons": "paperclip" - } - }, - { - "id": 13, - "severity": "alert", - "title": "Site Health status", - "message": "Your site has critical issues that should be addressed", - "source": "Wordpress", - "date": 1654800000, - "icon": { - "dashicons": "sos" - } - }, - { - "id": 14, - "severity": "warning", - "title": "Some plugins needs to be updated", - "source": "Wordpress", - "date": 1654800000, - "icon": { - "dashicons": "admin-plugins" - } - }, - { - "id": 15, - "severity": "success", - "title": "Word Camp Europe 2023", - "message": "Word Camp was successfully updated to version 2023", - "source": "Wordpress", - "date": 1654800000, - "icon": { - "dashicons": "megaphone" - } - }, - { - "id": 16, - "message": "WordPress User has left a message on Lorem Ipsum.", - "source": "Comment", - "date": 1654400000, - "icon": { - "src": "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y" - } - }, - { - "id": 17, - "message": "WordPress User has left a message on Lorem Ipsum.", - "source": "Comment", - "date": 1654000000, - "icon": { - "src": "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y" - } - } -] diff --git a/jsconfig.eslint.json b/jsconfig.eslint.json index dc981c6b..aa1a237d 100644 --- a/jsconfig.eslint.json +++ b/jsconfig.eslint.json @@ -8,6 +8,7 @@ ".prettierrc.js", "babel.config.js", "jest.config.js", - "webpack.config.js" + "webpack.config.js", + "scripts/**/*" ] } diff --git a/package.json b/package.json index a2e92398..ec6c44c7 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ "wp-env:start": "wp-env start", "wp-env:stop": "wp-env stop", "wp-env:destroy": "wp-env destroy", - "prepare": "husky install" + "prepare": "husky install && npm run gen-demo-data", + "gen-demo-data": "node scripts/gen-demo-data.js" }, "repository": { "type": "git", diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..9ad78c75 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,12 @@ +# Scripts for the WordPress Feature Notifications Project + +## Generating demo data + +The plugin is a demo of functionality and does not currently persist data to the WordPress database. The script to generate the demo data should be executed after running `npm install`, though the data can also be regenerated. + +```sh +# to regenerate the demo data +npm run gen-demo-data +``` + + diff --git a/scripts/gen-demo-data.js b/scripts/gen-demo-data.js new file mode 100644 index 00000000..dc255ff3 --- /dev/null +++ b/scripts/gen-demo-data.js @@ -0,0 +1,81 @@ +/* eslint-disable no-console */ + +const { mkdir, readFile, stat, writeFile } = require( 'node:fs/promises' ); +const path = require( 'node:path' ); + +const { format, resolveConfig } = require( 'prettier' ); + +const TWO_WEEKS_IN_SECONDS = 60 * 60 * 24 * 14; + +const inputPath = path.join( __dirname, 'scaffold-data.json' ); +const outputPath = path.join( __dirname, '../', 'tmp', 'demo-data.json' ); + +main().catch( ( error ) => { + throw error; +} ); + +async function main() { + const prettierOptions = { + ...( await resolveConfig( process.cwd() ) ), + parser: 'json', + }; + const raw = await readFile( inputPath, { encoding: 'utf-8' } ); + const { notices } = JSON.parse( raw ); + // notices.sort( ( a, b ) => b.id - a.id); // ascending order by id + const count = notices.length; + const start = Date.now() - TWO_WEEKS_IN_SECONDS * 1000; + const dates = randomDates( new Date( start ), count ); + const result = []; + for ( let i = 0; i < count; i++ ) { + const notice = notices[ i ]; + const date = dates[ i ]; + result.push( { ...notice, date } ); + } + const stringified = JSON.stringify( result, null, 2 ); + await mkdirp( path.join( __dirname, '../', 'tmp' ) ); + await writeFile( outputPath, format( stringified, prettierOptions ) ); +} + +/** + * Generate a set of random datetime between a starting date and now. + * + * TODO check what the correct format of the notice `data` property, is it seconds? + * + * @param {Date} start The minimum value of the set of random dates. + * @param {number} count The number of dates to generate. + * @return {number[]} A set of random datetime. + */ +function randomDates( start, count ) { + const min = start.getTime(); + const max = Date.now(); + if ( min >= max ) + throw new Error( + 'The starting datetime must be less than the current time.' + ); + const diff = max - min; + const result = []; + for ( let i = 0; i < count; i++ ) { + const random = Math.random() * diff; + result.push( min + random ); + } + result.sort( ( a, b ) => b - a ); // descending order + return result.map( ( x ) => Math.floor( x / 1000 ) ); // convert to seconds +} +/** + * Make a directory if it doesn't exist. + * + * @param {string} filePath The path to the directory to possibly create. + * @return {void} + */ +async function mkdirp( filePath ) { + try { + const { isDirectory } = await stat( filePath ); + if ( ! isDirectory() ) { + throw new Error( 'expected tmp directory is not a directory' ); + } + } catch ( error ) { + if ( error.code === 'ENOENT' ) { + mkdir( filePath ); + } + } +} diff --git a/scripts/scaffold-data.json b/scripts/scaffold-data.json new file mode 100644 index 00000000..ea808976 --- /dev/null +++ b/scripts/scaffold-data.json @@ -0,0 +1,187 @@ +{ + "channels": [ + { + "id": 4, + "source": "WordPress", + "textdomain": "wordpress", + "title": "wordpress/post-delete", + "description": "Post edit events." + }, + { + "id": 3, + "source": "WordPress", + "textdomain": "wordpress", + "title": "wordpress/post-edit", + "description": "Post edit events." + }, + { + "id": 2, + "source": "WordPress", + "textdomain": "wordpress", + "title": "wordpress/post-new", + "description": "Newly created post events." + }, + { + "id": 1, + "source": "WordPress", + "textdomain": "wordpress", + "title": "wordpress/update", + "description": "Core WordPress update events." + } + ], + "notices": [ + { + "id": 15, + "context": "dashboard", + "title": "Try this new Notification feature", + "source": "#WP-Notify", + "message": "👋 Hello from the WP Feature Notifications team! Thank you for testing out the plugin. You might want to give it a try so click on the bell icon on the right side of the adminbar.", + "dismissible": false, + "icon": { + "src": "https://raw.githubusercontent.com/erikyo/wp-notify/design_implementation/src/images/i.svg" + }, + "action": { + "acceptMessage": "Check out the source", + "acceptLink": "https://github.com/WordPress/wp-feature-notifications" + } + }, + { + "id": 14, + "title": "Message variant #1 (copy)", + "action": { + "acceptMessage": "TEST", + "acceptLink": "#" + } + }, + { + "id": 13, + "context": "adminbar", + "title": "Message variant #2", + "source": "#WP-Notify", + "message": "This is an example of on-page message variant #2. It has a title, a message, a custom date, an action button with a URL, is dismissable, but has no images.", + "dismissible": true, + "unread": true, + "action": { + "acceptMessage": "OK", + "acceptLink": "#" + } + }, + { + "id": 12, + "title": "WordPress", + "message": "WordPress was successfully updated to version 6.1", + "source": "WordPress", + "unread": true, + "action": { + "acceptMessage": "Read what's new in 6.1", + "acceptLink": "#" + } + }, + { + "id": 11, + "message": "WordPress was successfully updated to version 5.9.", + "source": "WordPress", + "image": { + "svg": "" + } + }, + { + "id": 10, + "title": "WordPress", + "message": "WordPress was successfully updated to version 6.1", + "source": "WordPress", + "action": { + "acceptMessage": "Read what's new in 6.1", + "acceptLink": "#" + } + }, + { + "id": 9, + "title": "WordPress", + "message": "WordPress was successfully updated to version 6.1", + "source": "WordPress", + "action": { + "acceptMessage": "Read what's new in 6.1", + "acceptLink": "#" + } + }, + { + "id": 8, + "message": "There is a new version of Contact Form 7 available.", + "source": "Plugins Updates", + "icon": { + "src": "https://ps.w.org/contact-form-7/assets/icon-256x256.png" + }, + "action": { + "acceptMessage": "Update now", + "acceptLink": "#" + } + }, + { + "id": 7, + "title": "Akismet", + "source": "Akismet", + "icon": { + "src": "https://ps.w.org/akismet/assets/icon-256x256.png" + }, + "action": { + "acceptMessage": "Your API key is no longer valid.", + "acceptLink": "#" + } + }, + { + "id": 6, + "title": "Default", + "acceptLink": "#", + "source": "Wordpress", + "icon": { + "dashicons": "paperclip" + } + }, + { + "id": 5, + "severity": "alert", + "title": "Site Health status", + "message": "Your site has critical issues that should be addressed", + "source": "Wordpress", + "icon": { + "dashicons": "sos" + } + }, + { + "id": 4, + "severity": "warning", + "title": "Some plugins needs to be updated", + "source": "Wordpress", + "icon": { + "dashicons": "admin-plugins" + } + }, + { + "id": 3, + "severity": "success", + "title": "Word Camp Europe 2023", + "message": "Word Camp was successfully updated to version 2023", + "source": "Wordpress", + "icon": { + "dashicons": "megaphone" + } + }, + { + "id": 2, + "message": "WordPress User has left a message on Lorem Ipsum.", + "source": "Comment", + "icon": { + "src": "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y" + } + }, + { + "id": 1, + "message": "WordPress User has left a message on Lorem Ipsum.", + "source": "Comment", + "icon": { + "src": "https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y" + } + } + ] +}