├── .nvmrc
├── .husky
├── .gitignore
└── pre-commit
├── .eslintignore
├── .wp-env.json
├── assets
├── js
│ ├── blocks
│ │ ├── podcast
│ │ │ ├── index.js
│ │ │ └── index.scss
│ │ ├── latest-episode
│ │ │ ├── index.js
│ │ │ └── index.scss
│ │ └── podcast-platforms
│ │ │ ├── index.js
│ │ │ ├── index.scss
│ │ │ └── edit.js
│ ├── onboarding.js
│ ├── transforms.js
│ ├── podcasting-edit-post.js
│ ├── deprecated.js
│ ├── podcasting-edit-term.js
│ ├── blocks.js
│ └── create-podcast-show.js
├── images
│ ├── icons
│ │ ├── RSS
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── castro
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── pandora
│ │ │ ├── black-40.png
│ │ │ ├── color-40.png
│ │ │ ├── white-40.png
│ │ │ ├── black-100.png
│ │ │ ├── color-100.png
│ │ │ └── white-100.png
│ │ ├── spotify
│ │ │ ├── black-40.png
│ │ │ ├── color-40.png
│ │ │ ├── white-40.png
│ │ │ ├── black-100.png
│ │ │ ├── color-100.png
│ │ │ └── white-100.png
│ │ ├── tunein
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── overcast
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── playerfm
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── stitcher
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ │ ├── pocket-casts
│ │ │ ├── black-40.png
│ │ │ ├── color-40.png
│ │ │ ├── white-40.png
│ │ │ ├── black-100.png
│ │ │ ├── color-100.png
│ │ │ └── white-100.png
│ │ ├── apple-podcasts
│ │ │ ├── black-40.png
│ │ │ ├── color-40.png
│ │ │ ├── white-40.png
│ │ │ ├── black-100.png
│ │ │ ├── color-100.png
│ │ │ └── white-100.png
│ │ └── google-podcasts
│ │ │ ├── black-100.png
│ │ │ ├── black-40.png
│ │ │ ├── color-100.png
│ │ │ ├── color-40.png
│ │ │ ├── white-100.png
│ │ │ └── white-40.png
│ ├── podcast-block-preview.png
│ └── podcast-block-preview@2x.png
└── css
│ ├── podcasting-transcript.css
│ ├── podcasting-editor-screen.css
│ ├── podcasting-edit-term.css
│ └── podcasting-onboarding.scss
├── .wordpress-version-checker.json
├── .prettierrc
├── .wordpress-org
├── icon-128x128.png
├── icon-256x256.png
├── screenshot-1.png
├── screenshot-2.png
├── screenshot-3.png
├── screenshot-4.png
├── screenshot-5.png
├── screenshot-6.png
├── banner-1544x500.png
├── banner-772x250.png
├── banner-772x250-rtl.png
├── banner-1544x500-rtl.png
└── blueprints
│ └── blueprint.json
├── .eslintrc
├── tests
├── cypress
│ ├── fixtures
│ │ ├── example.jpg
│ │ ├── example.mp3
│ │ └── example.json
│ ├── .eslintrc
│ ├── tsconfig.json
│ ├── integration
│ │ ├── admin.test.js
│ │ ├── onboarding.test.js
│ │ ├── block.test.js
│ │ ├── taxonomy.test.js
│ │ └── podcast-setting-panel.test.js
│ ├── support
│ │ ├── index.js
│ │ └── functions.js
│ ├── config.config.js
│ └── plugins
│ │ └── index.js
├── bin
│ └── set-wp-config.js
└── unit
│ ├── bootstrap.php
│ ├── test-transcript.php
│ ├── test-rest-external-url.php
│ ├── test-datatypes.php
│ ├── test-helpers.php
│ └── test-blocks.php
├── includes
├── blocks
│ ├── podcast-transcript
│ │ ├── styles.css
│ │ ├── index.js
│ │ ├── markup.php
│ │ ├── cite.js
│ │ ├── time.js
│ │ ├── formats.js
│ │ └── edit.js
│ └── podcast
│ │ └── markup.php
├── upgrade.php
├── admin
│ ├── views
│ │ ├── onboarding-header.php
│ │ ├── onboarding-page-two.php
│ │ └── onboarding-page-one.php
│ ├── create-podcast-component.php
│ └── onboarding.php
├── block-patterns.php
├── rest-external-url.php
├── transcripts.php
├── helpers.php
├── create-podcast.php
└── post-meta-box.php
├── .phpcs.xml.dist
├── .editorconfig
├── .distignore
├── .github
├── CODEOWNERS
└── workflows
│ ├── wordpress-version-checker.yml
│ ├── phpcs.yml
│ ├── repo-automator.yml
│ ├── push-asset-readme-update.yml
│ ├── dependency-review.yml
│ ├── push-deploy.yml
│ ├── build-release-zip.yml
│ ├── php-compatibility.yml
│ ├── phpunit.yml
│ ├── close-stale-issues.yml
│ └── cypress.yml
├── .gitignore
├── phpunit.xml.dist
├── composer.json
├── templates
└── transcript.php
├── webpack.config.js
├── package.json
├── CODE_OF_CONDUCT.md
├── CREDITS.md
├── CONTRIBUTING.md
├── simple-podcasting.php
└── README.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20
2 |
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | assets/js/frontend/vendor/*.js
2 |
--------------------------------------------------------------------------------
/.wp-env.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["."]
3 | }
4 |
--------------------------------------------------------------------------------
/assets/js/blocks/podcast/index.js:
--------------------------------------------------------------------------------
1 | import './index.scss';
2 |
--------------------------------------------------------------------------------
/assets/js/blocks/latest-episode/index.js:
--------------------------------------------------------------------------------
1 | import './index.scss';
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.wordpress-version-checker.json:
--------------------------------------------------------------------------------
1 | {
2 | "readme": "readme.txt",
3 | "channel": "rc"
4 | }
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "printWidth": 90,
4 | "tabWidth": 4,
5 | "singleQuote": true
6 | }
7 |
--------------------------------------------------------------------------------
/.wordpress-org/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/icon-128x128.png
--------------------------------------------------------------------------------
/.wordpress-org/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/icon-256x256.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-1.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-2.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-3.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-4.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-5.png
--------------------------------------------------------------------------------
/.wordpress-org/screenshot-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/screenshot-6.png
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [ "plugin:@wordpress/eslint-plugin/recommended" ],
3 | "ignorePatterns": ["**/vendor/**"]
4 | }
5 |
--------------------------------------------------------------------------------
/.wordpress-org/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/banner-1544x500.png
--------------------------------------------------------------------------------
/.wordpress-org/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/banner-772x250.png
--------------------------------------------------------------------------------
/tests/cypress/fixtures/example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/tests/cypress/fixtures/example.jpg
--------------------------------------------------------------------------------
/tests/cypress/fixtures/example.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/tests/cypress/fixtures/example.mp3
--------------------------------------------------------------------------------
/.wordpress-org/banner-772x250-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/banner-772x250-rtl.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/RSS/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/RSS/white-40.png
--------------------------------------------------------------------------------
/.wordpress-org/banner-1544x500-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/.wordpress-org/banner-1544x500-rtl.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/castro/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/castro/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/tunein/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/tunein/white-40.png
--------------------------------------------------------------------------------
/assets/images/podcast-block-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/podcast-block-preview.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/overcast/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/overcast/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/pandora/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pandora/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/playerfm/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/playerfm/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/spotify/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/spotify/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/stitcher/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/stitcher/white-40.png
--------------------------------------------------------------------------------
/assets/images/podcast-block-preview@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/podcast-block-preview@2x.png
--------------------------------------------------------------------------------
/tests/cypress/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "plugin:cypress/recommended",
3 | "rules": {
4 | "jest/expect-expect": "off",
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/white-40.png
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/pocket-casts/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/pocket-casts/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-podcasts/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/apple-podcasts/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/black-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/black-100.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/black-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/black-40.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/color-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/color-100.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/color-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/color-40.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/white-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/white-100.png
--------------------------------------------------------------------------------
/assets/images/icons/google-podcasts/white-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/10up/simple-podcasting/HEAD/assets/images/icons/google-podcasts/white-40.png
--------------------------------------------------------------------------------
/tests/cypress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "types": ["cypress"]
5 | },
6 | "include": ["**/*.*"]
7 | }
8 |
--------------------------------------------------------------------------------
/assets/css/podcasting-transcript.css:
--------------------------------------------------------------------------------
1 | .wp-block-podcasting-podcast-transcript cite,
2 | .wp-block-podcasting-podcast-transcript time {
3 | display: block;
4 | }
5 |
--------------------------------------------------------------------------------
/includes/blocks/podcast-transcript/styles.css:
--------------------------------------------------------------------------------
1 | .wp-block-podcasting-podcast-transcript cite,
2 | .wp-block-podcasting-podcast-transcript time {
3 | display: block;
4 | }
5 |
--------------------------------------------------------------------------------
/tests/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/.phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | .
5 | dist/
6 | vendor/
7 | tests/
8 |
9 |
--------------------------------------------------------------------------------
/assets/css/podcasting-editor-screen.css:
--------------------------------------------------------------------------------
1 | .components-input-control,
2 | .components-base-control {
3 | width: 100%;
4 | }
5 | .cover-art-container {
6 | display: flex;
7 | flex-direction: column;
8 | justify-content: center;
9 | align-items: center;
10 | }
11 | .cover-art-container button {
12 | margin: 10px 0;
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 | indent_style = tab
9 |
10 | [{*.json,*.yml,.babelrc,.bowerrc,.postcssrc}]
11 | indent_style = space
12 | indent_size = 2
13 |
14 | [*.txt,wp-config-sample.php]
15 | end_of_line = crlf
16 |
--------------------------------------------------------------------------------
/tests/cypress/integration/admin.test.js:
--------------------------------------------------------------------------------
1 | describe('Admin can login and make sure plugin is activated', () => {
2 | beforeEach(() => {
3 | cy.login();
4 | });
5 |
6 | it('Can activate plugin if it is deactivated', () => {
7 | cy.deactivatePlugin('simple-podcasting');
8 | cy.activatePlugin('simple-podcasting');
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/includes/blocks/podcast-transcript/index.js:
--------------------------------------------------------------------------------
1 | import { registerBlockType } from '@wordpress/blocks';
2 | import { InnerBlocks } from '@wordpress/block-editor';
3 | import './styles.css';
4 |
5 | import Edit from './edit';
6 |
7 | import './cite';
8 | import './time';
9 |
10 | registerBlockType('podcasting/podcast-transcript', {
11 | edit: Edit,
12 | save: () => ,
13 | });
14 |
--------------------------------------------------------------------------------
/.distignore:
--------------------------------------------------------------------------------
1 | # Directories
2 | /.git
3 | /.github
4 | /.husky
5 | /.wordpress-org
6 | /assets
7 | /gulp-tasks
8 | /node_modules
9 | /tests
10 | /vendor
11 |
12 | # Files
13 | .*
14 | /CHANGELOG.md
15 | /CODE_OF_CONDUCT.md
16 | /composer.json
17 | /composer.lock
18 | /CONTRIBUTING.md
19 | /CREDITS.md
20 | /gulpfile.babel.js
21 | /LICENSE.md
22 | /package.json
23 | /package-lock.json
24 | /phpunit.xml.dist
25 | /README.md
26 | /webpack.config.js
27 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These owners will be the default owners for everything in the repo. Unless a later match takes precedence, @10up/open-source-practice, as primary maintainers will be requested for review when someone opens a Pull Request.
2 | * @10up/open-source-practice
3 |
4 | # GitHub and WordPress.org specifics
5 | /.github/ @jeffpaul
6 | /.wordpress-org/ @jeffpaul
7 | CODE_OF_CONDUCT.md @jeffpaul
8 | LICENSE.md @jeffpaul
9 |
--------------------------------------------------------------------------------
/.github/workflows/wordpress-version-checker.yml:
--------------------------------------------------------------------------------
1 | name: "WordPress version checker"
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - trunk
8 | pull_request:
9 | branches:
10 | - develop
11 | schedule:
12 | - cron: '0 0 * * 1'
13 |
14 | permissions:
15 | issues: write
16 |
17 | jobs:
18 | wordpress-version-checker:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - name: WordPress version checker
22 | uses: skaut/wordpress-version-checker@9d247334f5b30202cb9c1f4aee74c52f37399f69 # v2.2.3
23 | with:
24 | repo-token: ${{ secrets.GITHUB_TOKEN }}
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 | languages
4 | release
5 | vendor
6 | phpunit.xml
7 | .idea
8 | .phpunit.result.cache
9 |
10 | # Project Files
11 | dist
12 | ruleset.xml
13 |
14 | # Editors
15 | *.esproj
16 | *.tmproj
17 | *.tmproject
18 | tmtags
19 | .*.sw[a-z]
20 | *.un~
21 | Session.vim
22 | *.swp
23 | *.csv
24 |
25 | # Mac OSX
26 | .DS_Store
27 | ._*
28 | .Spotlight-V100
29 | .Trashes
30 |
31 | # Windows
32 | Thumbs.db
33 | Desktop.ini
34 |
35 | # E2E testing
36 | .wp-env.override.json
37 | artifacts
38 | tests/cypress/downloads
39 | tests/cypress/screenshots
40 | tests/cypress/videos
41 | tests/cypress/reports
42 |
--------------------------------------------------------------------------------
/includes/upgrade.php:
--------------------------------------------------------------------------------
1 | =' ) ) {
18 | flush_rewrite_rules();
19 | update_option( 'simple_podcasting_db_version', PODCASTING_VERSION );
20 | }
21 | }
22 |
23 | add_filter( 'admin_init', __NAMESPACE__ . '\\maybe_flush_rewrite', 10, 1 );
24 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/unit
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/cypress/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | import '@10up/cypress-wp-utils';
17 | import 'cypress-file-upload';
18 |
--------------------------------------------------------------------------------
/.wordpress-org/blueprints/blueprint.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://playground.wordpress.net/blueprint-schema.json",
3 | "landingPage": "\/wp-admin\/admin.php?page=simple-podcasting-onboarding&step=1",
4 | "preferredVersions": {
5 | "php": "7.4",
6 | "wp": "latest"
7 | },
8 | "phpExtensionBundles": ["kitchen-sink"],
9 | "features": {
10 | "networking": true
11 | },
12 | "steps": [
13 | {
14 | "step": "login",
15 | "username": "admin",
16 | "password": "password"
17 | },
18 | {
19 | "step": "installPlugin",
20 | "pluginZipFile": {
21 | "resource": "wordpress.org\/plugins",
22 | "slug": "simple-podcasting"
23 | },
24 | "options": {
25 | "activate": true
26 | }
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/assets/js/onboarding.js:
--------------------------------------------------------------------------------
1 | import '../css/podcasting-onboarding.scss';
2 |
3 | ( function( $ ) {
4 | $( function() {
5 | const selectImageBtn = $( '#simple-podcasting__upload-cover-image' );
6 | const coverImage = $( 'input[name="podcast-cover-image-id"]' );
7 | const coverImagePreview = $( '#simple-podcasting__cover-image-preview' );
8 | let uploader_frame = null;
9 |
10 | /** Upload image button handler */
11 | selectImageBtn.on( 'click', function() {
12 | uploader_frame = wp.media( {
13 | multiple: false,
14 | library: {
15 | type: 'image'
16 | }
17 | } ).on( 'select', function() {
18 | const { id, url } = uploader_frame.state().get( 'selection' ).first().toJSON();
19 | coverImagePreview.html( `
` )
20 | coverImage.val( id );
21 | } );
22 |
23 | uploader_frame.open();
24 | } );
25 | } )
26 | } )( jQuery )
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "10up/simple-podcasting",
3 | "description": "A simple podcasting solution for WordPress. ",
4 | "homepage": "https://github.com/10up/simple-podcasting",
5 | "license": "GPL-2.0-or-later",
6 | "authors": [
7 | {
8 | "name": "10up",
9 | "email": "opensource@10up.com",
10 | "homepage": "https://10up.com"
11 | }
12 | ],
13 | "support": {
14 | "issues": "https://github.com/10up/simple-podcasting/issues"
15 | },
16 | "require": {
17 | "php": ">=7.3"
18 | },
19 | "require-dev": {
20 | "10up/phpcs-composer": "^3.0",
21 | "10up/wp_mock": "^0.4.2",
22 | "phpunit/phpunit": "^9.5",
23 | "phpcompatibility/php-compatibility": "dev-develop as 9.99.99"
24 | },
25 | "config": {
26 | "allow-plugins": {
27 | "dealerdirect/phpcodesniffer-composer-installer": true
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.github/workflows/phpcs.yml:
--------------------------------------------------------------------------------
1 | name: PHPCS
2 |
3 | permissions:
4 | contents: read
5 |
6 | on:
7 | push:
8 | branches:
9 | - develop
10 | - trunk
11 | paths:
12 | - "**.php"
13 | pull_request:
14 | branches:
15 | - develop
16 | paths:
17 | - "**.php"
18 |
19 | jobs:
20 | phpcs:
21 | runs-on: ubuntu-latest
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
26 |
27 | - name: Set PHP version
28 | uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
29 | with:
30 | php-version: '7.4'
31 | coverage: none
32 | tools: composer:v2
33 |
34 | - name: Install dependencies
35 | run: composer install
36 |
37 | - name: Test
38 | run: ./vendor/bin/phpcs --runtime-set testVersion 7.4 .
39 |
--------------------------------------------------------------------------------
/.github/workflows/repo-automator.yml:
--------------------------------------------------------------------------------
1 | name: 'Repo Automator'
2 |
3 | permissions:
4 | contents: read
5 | issues: write
6 |
7 | on:
8 | issues:
9 | types:
10 | - opened
11 | push:
12 | branches:
13 | - develop
14 | pull_request:
15 | types:
16 | - opened
17 | - edited
18 | - synchronize
19 | - converted_to_draft
20 | - ready_for_review
21 | branches:
22 | - develop
23 |
24 | jobs:
25 | Validate:
26 | runs-on: ubuntu-latest
27 | steps:
28 | - uses: 10up/action-repo-automator@280f5dc0b4ed1b5c50c816e08623bdefce55cdce # v2.1.3
29 | with:
30 | fail-label: needs:feedback
31 | pass-label: needs:code-review
32 | conflict-label: needs:refresh
33 | reviewers: |
34 | team:open-source-practice
35 | env:
36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37 |
--------------------------------------------------------------------------------
/.github/workflows/push-asset-readme-update.yml:
--------------------------------------------------------------------------------
1 | name: Plugin asset/readme update
2 |
3 | on:
4 | push:
5 | branches:
6 | - trunk
7 |
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | trunk:
13 | name: Push to trunk
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout code
18 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19 |
20 | - name: install node
21 | uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
22 | with:
23 | node-version-file: .nvmrc
24 |
25 | - name: Build
26 | run: |
27 | npm ci
28 | npm run build
29 |
30 | - name: WordPress.org plugin asset/readme update
31 | uses: 10up/action-wordpress-plugin-asset-update@2480306f6f693672726d08b5917ea114cb2825f7 # v2.2.0
32 | env:
33 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
34 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
35 |
--------------------------------------------------------------------------------
/assets/css/podcasting-edit-term.css:
--------------------------------------------------------------------------------
1 | .taxonomy-podcasting_podcasts .term-parent-wrap {
2 | display: none;
3 | }
4 | .podcast-image-thumbnail {
5 | max-width: 300px;
6 | max-height: 200px;
7 | }
8 |
9 | .column-podcasting_image img {
10 | height: auto;
11 | max-width: 100%;
12 | width: 75px;
13 | }
14 |
15 | .simple_podcasting__platforms img {
16 | display: block;
17 | max-width: 42px;
18 | margin: 0 auto;
19 | height: auto;
20 | }
21 |
22 | .simple_podcasting__platforms th {
23 | padding: 15px 10px;
24 | text-align: center;
25 | }
26 |
27 | .simple_podcasting__platforms td {
28 | vertical-align: middle;
29 | padding: 15px 10px;
30 | }
31 |
32 | .simple_podcasting__platforms-url {
33 | min-width: 220px;
34 | }
35 |
36 | .simple_podcasting__platforms-icon {
37 | transition: background-color 0.2s ease-out;
38 | }
39 |
40 | .simple_podcasting__platforms-icon--darken-bg {
41 | background-color: rgb(28 52 59 / 22%);
42 | transition: background-color 0.2s ease-in;
43 | }
44 |
--------------------------------------------------------------------------------
/includes/admin/views/onboarding-header.php:
--------------------------------------------------------------------------------
1 |
9 |
27 |
--------------------------------------------------------------------------------
/assets/js/blocks/podcast-platforms/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Internal block libraries
3 | */
4 | import { __ } from '@wordpress/i18n';
5 | import { registerBlockType } from '@wordpress/blocks';
6 |
7 | import Edit from './edit';
8 | import './index.scss';
9 |
10 | /**
11 | * Register Podcast Platforms block
12 | */
13 | export default registerBlockType(
14 | 'podcasting/podcast-platforms',
15 | {
16 | title: __( 'Podcast Platforms', 'simple-podcasting' ),
17 | description: __( 'Displays the list of platforms where the selected show is available.', 'simple-podcasting' ),
18 | category: 'common',
19 | icon: 'microphone',
20 | supports: {
21 | multiple: false,
22 | },
23 | attributes: {
24 | showId: {
25 | type: 'number',
26 | default: 0,
27 | },
28 | iconSize: {
29 | type: 'number',
30 | default: 48,
31 | },
32 | align: {
33 | type: 'string',
34 | default: 'center',
35 | }
36 | },
37 |
38 | edit: Edit,
39 |
40 | save: () => null,
41 | },
42 | );
43 |
--------------------------------------------------------------------------------
/assets/js/transforms.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | const { select } = wp.data;
5 | const { createBlock } = wp.blocks;
6 |
7 | /**
8 | * Transforms
9 | */
10 | const transforms = {
11 | from: [
12 | {
13 | type: 'block',
14 | blocks: [ 'core/audio' ],
15 | transform: ( attributes ) => {
16 | return createBlock( 'podcasting/podcast', {
17 | id: attributes.id,
18 | src: attributes.src
19 | } );
20 | },
21 | },
22 | ],
23 | to: [
24 | {
25 | type: 'block',
26 | blocks: [ 'core/audio' ],
27 | isMatch: ( { id } ) => {
28 | if ( ! id ) {
29 | return false;
30 | }
31 | const { getMedia } = select( 'core' );
32 | const media = getMedia( id );
33 | return !! media && media.mime_type.includes( 'audio' );
34 | },
35 | transform: ( attributes ) => {
36 | return createBlock( 'core/audio', {
37 | src: attributes.src,
38 | id: attributes.id
39 | } );
40 | },
41 | },
42 | ],
43 |
44 | };
45 |
46 | export default transforms;
47 |
--------------------------------------------------------------------------------
/includes/blocks/podcast-transcript/markup.php:
--------------------------------------------------------------------------------
1 |
16 | >
17 |
%s',
29 | esc_url( get_transcript_link_from_post( get_post() ) ),
30 | esc_html( $attributes['linkText'] )
31 | );
32 | break;
33 | }
34 | ?>
35 |
36 |
37 |
--------------------------------------------------------------------------------
/tests/bin/set-wp-config.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs');
4 |
5 | const path = `${process.cwd()}/.wp-env.override.json`;
6 |
7 | let config = fs.existsSync(path) ? require(path) : { plugins: ['.'] };
8 |
9 | const args = {};
10 | process.argv.slice(2, process.argv.length).forEach((arg) => {
11 | if (arg.slice(0, 2) === '--') {
12 | const param = arg.split('=');
13 | const paramName = param[0].slice(2, param[0].length);
14 | const paramValue = param.length > 1 ? param[1] : true;
15 | args[paramName] = paramValue;
16 | }
17 | });
18 |
19 | if (!args.core && !args.plugins) {
20 | return;
21 | }
22 |
23 | if ('latest' === args.core) {
24 | delete args.core;
25 | }
26 |
27 | if (Object.keys(args).length === 0) {
28 | return;
29 | }
30 |
31 | if (args.plugins) {
32 | args.plugins = args.plugins.split(',');
33 | }
34 |
35 | config = {
36 | ...config,
37 | ...args,
38 | };
39 |
40 | try {
41 | fs.writeFileSync(path, JSON.stringify(config));
42 | } catch (err) {
43 | console.error(err);
44 | }
45 |
--------------------------------------------------------------------------------
/assets/js/podcasting-edit-post.js:
--------------------------------------------------------------------------------
1 | /*global jQuery */
2 | jQuery( document ).ready( function( $ ) {
3 | $( '#podcasting-enclosure-button' ).click( function( e ) {
4 | e.preventDefault();
5 |
6 | var $this = $( this ),
7 | $input = $( 'input#podcasting-enclosure-url' ),
8 | mediaUploader;
9 |
10 | // If the uploader object has already been created, reopen the dialog.
11 | if ( mediaUploader ) {
12 | mediaUploader.open();
13 | return;
14 | }
15 |
16 | // eslint-disable-next-line camelcase
17 | mediaUploader = wp.media.frames.file_frame = wp.media( {
18 | title: $this.data( 'modalTitle' ),
19 | button: {
20 | text: $this.data( 'modalButton' )
21 | },
22 | library: {
23 | type: 'audio'
24 | },
25 | multiple: false
26 | });
27 |
28 | mediaUploader.off( 'select' );
29 | mediaUploader.on( 'select', function() {
30 | var attachment = mediaUploader.state().get('selection').first();
31 |
32 | $input.val( attachment.get('url') );
33 | });
34 |
35 | mediaUploader.open();
36 | } );
37 | } );
38 |
--------------------------------------------------------------------------------
/assets/js/blocks/latest-episode/index.scss:
--------------------------------------------------------------------------------
1 | .podcasting-latest-episode {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: end;
5 | min-height: 20rem;
6 | overflow: hidden;
7 | position: relative;
8 |
9 | & .wp-block-post-featured-image {
10 | height: 100%;
11 | object-fit: fill;
12 | object-position: center;
13 | position: absolute;
14 | width: 100%;
15 |
16 | &::after {
17 | background-color: rgb(0 0 0 / 75%);
18 | content: "";
19 | display: block;
20 | height: 100%;
21 | left: 0;
22 | position: absolute;
23 | top: 0;
24 | width: 100%;
25 | }
26 | }
27 | }
28 |
29 | .podcasting-latest-episode__content {
30 | color: #fff;
31 | padding: 3rem;
32 | position: relative;
33 | z-index: 1;
34 |
35 | @media (min-width: 768px) {
36 | padding: 3rem;
37 | }
38 |
39 | & .wp-block-post-excerpt,
40 | & .wp-block-post-excerpt__more-text {
41 | margin-top: 0.25rem;
42 | }
43 |
44 | & .wp-block-post-excerpt__more-link {
45 | color: #fff;
46 | }
47 | }
48 |
49 | .editor-styles-wrapper .wp-block-post-content .podcasting-latest-episode__content .wp-block-post-excerpt__more-link:where(:not(.wp-element-button)) {
50 | color: #fff;
51 | }
52 |
--------------------------------------------------------------------------------
/tests/unit/bootstrap.php:
--------------------------------------------------------------------------------
1 | {
11 | const blockProps = useBlockProps();
12 | return (
13 | setAttributes({ text: content })}
17 | allowedFormats={[]}
18 | withoutInteractiveFormatting
19 | onSplit={(value, isOriginal) => {
20 | let block;
21 |
22 | if (isOriginal || value) {
23 | block = createBlock('podcasting/podcast-transcript-cite', {
24 | ...attributes,
25 | content: value,
26 | });
27 | } else {
28 | block = createBlock('core/paragraph');
29 | }
30 |
31 | if (isOriginal) {
32 | block.clientId = clientId;
33 | }
34 |
35 | return block;
36 | }}
37 | onReplace={onReplace}
38 | {...blockProps}
39 | />
40 | );
41 | };
42 |
43 | registerBlockType('podcasting/podcast-transcript-cite', {
44 | edit: Edit,
45 | save: ({ attributes: { text } }) => {text},
46 | });
47 |
--------------------------------------------------------------------------------
/includes/blocks/podcast-transcript/time.js:
--------------------------------------------------------------------------------
1 | import { registerBlockType, createBlock } from '@wordpress/blocks';
2 | import { useBlockProps, RichText } from '@wordpress/block-editor';
3 |
4 | const Edit = ({
5 | attributes,
6 | attributes: { text },
7 | setAttributes,
8 | clientId,
9 | onReplace,
10 | }) => {
11 | const blockProps = useBlockProps();
12 | return (
13 | setAttributes({ text: content })}
17 | allowedFormats={[]}
18 | withoutInteractiveFormatting
19 | onSplit={(value, isOriginal) => {
20 | let block;
21 |
22 | if (isOriginal || value) {
23 | block = createBlock('podcasting/podcast-transcript-time', {
24 | ...attributes,
25 | content: value,
26 | });
27 | } else {
28 | block = createBlock('core/paragraph');
29 | }
30 |
31 | if (isOriginal) {
32 | block.clientId = clientId;
33 | }
34 |
35 | return block;
36 | }}
37 | onReplace={onReplace}
38 | {...blockProps}
39 | />
40 | );
41 | };
42 |
43 | registerBlockType('podcasting/podcast-transcript-time', {
44 | edit: Edit,
45 | save: ({ attributes: { text } }) => ,
46 | });
47 |
--------------------------------------------------------------------------------
/tests/cypress/config.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('cypress');
2 |
3 | module.exports = defineConfig({
4 | fixturesFolder: __dirname + '/fixtures',
5 | screenshotsFolder: __dirname + '/screenshots',
6 | videosFolder: __dirname + '/videos',
7 | downloadsFolder: __dirname + '/downloads',
8 | video: true,
9 | reporter: 'mochawesome',
10 | reporterOptions: {
11 | mochaFile: 'mochawesome-[name]',
12 | reportDir: __dirname + '/reports',
13 | overwrite: false,
14 | html: false,
15 | json: true,
16 | },
17 | chromeWebSecurity: false,
18 | env: {
19 | HAS_BLOCK_EDITOR: true,
20 | },
21 | e2e: {
22 | // We've imported your old cypress plugins here.
23 | // You may want to clean this up later by importing these.
24 | setupNodeEvents(on, config) {
25 | return require(__dirname + '/plugins/index.js')(on, config);
26 | },
27 | supportFile: __dirname + '/support/index.js',
28 | specPattern: [
29 | 'tests/cypress/integration/admin.test.js',
30 | 'tests/cypress/integration/onboarding.test.js',
31 | 'tests/cypress/integration/taxonomy.test.js',
32 | 'tests/cypress/integration/block.test.js',
33 | 'tests/cypress/integration/podcast-setting-panel.test.js',
34 | ],
35 | },
36 | });
37 |
--------------------------------------------------------------------------------
/tests/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************************
3 | // This example plugins/index.js can be used to load plugins
4 | //
5 | // You can change the location of this file or turn off loading
6 | // the plugins file with the 'pluginsFile' configuration option.
7 | //
8 | // You can read more here:
9 | // https://on.cypress.io/plugins-guide
10 | // ***********************************************************
11 |
12 | // This function is called when a project is opened or re-opened (e.g. due to
13 | // the project's config changing)
14 |
15 | const { loadConfig } = require('@wordpress/env/lib/config');
16 | const getCacheDirectory = require('@wordpress/env/lib/config/get-cache-directory');
17 |
18 | /**
19 | * @type {Cypress.PluginConfig}
20 | */
21 | // eslint-disable-next-line no-unused-vars
22 | module.exports = async (on, config) => {
23 | const cacheDirectory = await getCacheDirectory();
24 | const wpEnvConfig = await loadConfig(cacheDirectory);
25 |
26 | if (wpEnvConfig) {
27 | const port = wpEnvConfig.env.tests.port || null;
28 |
29 | if (port) {
30 | config.baseUrl = wpEnvConfig.env.tests.config.WP_SITEURL;
31 | }
32 | }
33 |
34 | return config;
35 | };
36 |
--------------------------------------------------------------------------------
/.github/workflows/dependency-review.yml:
--------------------------------------------------------------------------------
1 | # Dependency Review Action
2 | #
3 | # This Action will scan dependency manifest files that change as part of a Pull Reqest, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
4 | #
5 | # Source repository: https://github.com/actions/dependency-review-action
6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
7 | name: 'Dependency Review'
8 | on: [pull_request]
9 |
10 | permissions:
11 | contents: read
12 |
13 | jobs:
14 | dependency-review:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: 'Checkout Repository'
18 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19 |
20 | - name: Dependency Review
21 | uses: actions/dependency-review-action@72eb03d02c7872a771aacd928f3123ac62ad6d3a # v4.3.3
22 | with:
23 | license-check: true
24 | vulnerability-check: false
25 | config-file: 10up/.github/.github/dependency-review-config.yml@trunk
26 |
--------------------------------------------------------------------------------
/includes/admin/create-podcast-component.php:
--------------------------------------------------------------------------------
1 | id ) ) {
29 | return;
30 | }
31 |
32 | wp_enqueue_script(
33 | 'podcasting_create_podcast_show_plugin',
34 | PODCASTING_URL . 'dist/create-podcast-show.js',
35 | array(),
36 | PODCASTING_VERSION,
37 | true
38 | );
39 |
40 | wp_localize_script(
41 | 'podcasting_create_podcast_show_plugin',
42 | 'podcastingShowPluginVars',
43 | array(
44 | 'categories' => \tenup_podcasting\get_podcasting_categories_options(),
45 | )
46 | );
47 | }
48 | }
49 |
50 | new Create_Podcast_Component();
51 |
--------------------------------------------------------------------------------
/templates/transcript.php:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
30 |
31 |
32 |
33 | ID, 'podcast_transcript', true )
40 | )
41 | );
42 | }
43 | ?>
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.github/workflows/push-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to WordPress.org
2 |
3 | permissions:
4 | contents: write
5 | packages: read
6 | actions: write
7 |
8 | on:
9 | release:
10 | types: [published]
11 |
12 | jobs:
13 | tag:
14 | name: New release
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - name: Checkout code
19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
20 |
21 | - name: install node
22 | uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
23 | with:
24 | node-version-file: .nvmrc
25 |
26 | - name: Build
27 | run: |
28 | npm ci
29 | npm run build
30 | npm run makepot
31 |
32 | - name: WordPress Plugin Deploy
33 | id: deploy
34 | uses: 10up/action-wordpress-plugin-deploy@54bd289b8525fd23a5c365ec369185f2966529c2 # v2.3.0
35 | with:
36 | generate-zip: true
37 | env:
38 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
39 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
40 |
41 | - name: Upload release asset
42 | uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
43 | env:
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 | with:
46 | files: ${{ github.workspace }}/${{ github.event.repository.name }}.zip
47 |
--------------------------------------------------------------------------------
/.github/workflows/build-release-zip.yml:
--------------------------------------------------------------------------------
1 | name: Build release zip
2 |
3 | permissions:
4 | contents: read
5 |
6 | on:
7 | workflow_dispatch:
8 | workflow_call:
9 | push:
10 | branches:
11 | - trunk
12 |
13 | jobs:
14 | build:
15 | name: Build release zip
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
21 |
22 | - name: Cache node_modules
23 | id: cache-node-modules
24 | uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
25 | env:
26 | cache-name: cache-node-modules
27 | with:
28 | path: node_modules
29 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
30 |
31 | - name: Setup node version and npm cache
32 | uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
33 | with:
34 | node-version-file: '.nvmrc'
35 | cache: 'npm'
36 |
37 | - name: Install Node dependencies
38 | if: steps.cache-node-modules.outputs.cache-hit != 'true'
39 | run: npm ci --no-optional
40 |
41 | - name: Build plugin
42 | run: npm run build
43 |
44 | - name: Generate ZIP file
45 | uses: 10up/action-wordpress-plugin-build-zip@b9e621e1261ccf51592b6f3943e4dc4518fca0d1 # v1.0.2
46 |
--------------------------------------------------------------------------------
/tests/unit/test-transcript.php:
--------------------------------------------------------------------------------
1 | post_name = 'latest-podcast';
29 | $terms = [ new stdClass() ];
30 | $terms[0]->term_id = 100;
31 |
32 | \WP_Mock::userFunction( 'get_post' )->andReturn( $post );
33 | \WP_Mock::userFunction( 'get_the_terms' )->andReturn( $terms );
34 | \WP_Mock::userFunction( 'get_term_link' )->andReturn( 'https://simple-podcasting.test/podcasts/test-podcast/' );
35 | \WP_Mock::userFunction( 'trailingslashit' )->andReturnUsing( function( $url ) {
36 | return rtrim( $url, '/\\' ) . '/';
37 | } );
38 |
39 | $this->assertSame(
40 | tenup_podcasting\transcripts\get_transcript_link_from_post( $post ),
41 | 'https://simple-podcasting.test/podcasts/test-podcast/latest-podcast/transcript/'
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/unit/test-rest-external-url.php:
--------------------------------------------------------------------------------
1 | shouldReceive( 'offsetGet' )
32 | ->with( 'url' )
33 | ->andReturn( $url );
34 |
35 | $mock_request->shouldReceive( 'offsetExists' )
36 | ->with( 'url' )
37 | ->andReturn( true );
38 |
39 | $cache_key = 'spc_external_url_' . $url;
40 |
41 | \WP_Mock::userFunction( 'get_transient' )
42 | ->with( $cache_key )
43 | ->andReturn( 'Podcast Meta' );
44 |
45 | \WP_Mock::passthruFunction( 'rest_ensure_response' );
46 |
47 | $response = array(
48 | 'success' => true,
49 | 'data' => 'Podcast Meta',
50 | );
51 |
52 | $this->assertSame(
53 | $response,
54 | tenup_podcasting\endpoints\externalurl\handle_request( $mock_request ),
55 | 'handle_request() should return cached result'
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/.github/workflows/php-compatibility.yml:
--------------------------------------------------------------------------------
1 | name: PHP Compatibility
2 |
3 | permissions:
4 | contents: read
5 |
6 | env:
7 | COMPOSER_VERSION: "2"
8 | COMPOSER_CACHE: "${{ github.workspace }}/.composer-cache"
9 |
10 | on:
11 | push:
12 | branches:
13 | - develop
14 | - trunk
15 | pull_request:
16 | branches:
17 | - develop
18 |
19 | jobs:
20 | php_compatibility:
21 | name: PHP ${{ matrix.php }}
22 | runs-on: ubuntu-latest
23 |
24 | steps:
25 | - name: Checkout
26 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27 |
28 | - name: Set standard 10up cache directories
29 | run: |
30 | composer config -g cache-dir "${{ env.COMPOSER_CACHE }}"
31 |
32 | - name: Prepare composer cache
33 | uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
34 | with:
35 | path: ${{ env.COMPOSER_CACHE }}
36 | key: composer-${{ env.COMPOSER_VERSION }}-${{ hashFiles('**/composer.lock') }}
37 | restore-keys: |
38 | composer-${{ env.COMPOSER_VERSION }}-
39 |
40 | - name: Set PHP version
41 | uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
42 | with:
43 | php-version: '7.4'
44 | coverage: none
45 | tools: prestissimo, composer:v2
46 |
47 | - name: Install dependencies
48 | run: composer install
49 |
50 | - name: Check PHP Compatibility
51 | run: ./vendor/bin/phpcs -p simple-podcasting.php includes --standard=PHPCompatibilityWP --extensions=php --runtime-set testVersion 7.4-
52 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('@wordpress/scripts/config/webpack.config');
2 | const CopyPlugin = require('copy-webpack-plugin');
3 | const path = require('path');
4 |
5 | module.exports = {
6 | ...defaultConfig,
7 | output: {
8 | ...defaultConfig.output,
9 | path: path.resolve(process.cwd(), 'dist'),
10 | },
11 | entry: {
12 | blocks: path.resolve(process.cwd(), 'assets/js', 'blocks.js'),
13 | 'podcasting-edit-post': path.resolve(
14 | process.cwd(),
15 | 'assets/js',
16 | 'podcasting-edit-post.js'
17 | ),
18 | 'podcasting-edit-term': path.resolve(
19 | process.cwd(),
20 | 'assets/js',
21 | 'podcasting-edit-term.js'
22 | ),
23 | 'podcast-platforms-block': path.resolve(
24 | process.cwd(),
25 | 'assets/js/blocks/podcast-platforms',
26 | 'index.js'
27 | ),
28 | 'podcasting-onboarding': path.resolve(
29 | process.cwd(),
30 | 'assets/js',
31 | 'onboarding.js'
32 | ),
33 | 'podcasting-transcript': path.resolve(
34 | process.cwd(),
35 | 'includes/blocks/podcast-transcript',
36 | 'index.js'
37 | ),
38 | 'create-podcast-show': path.resolve(
39 | process.cwd(),
40 | 'assets/js',
41 | 'create-podcast-show.js'
42 | ),
43 | 'latest-episode': path.resolve(
44 | process.cwd(),
45 | 'assets/js/blocks/latest-episode',
46 | 'index.js'
47 | ),
48 | 'podcast': path.resolve(
49 | process.cwd(),
50 | 'assets/js/blocks/podcast',
51 | 'index.js'
52 | ),
53 | },
54 | plugins: [
55 | ...defaultConfig.plugins,
56 | new CopyPlugin({
57 | patterns: [
58 | { from: 'assets/images/*', to: './' },
59 | { from: 'assets/images/icons', to: './images/icons' },
60 | ],
61 | }),
62 | ],
63 | };
64 |
--------------------------------------------------------------------------------
/assets/js/blocks/podcast-platforms/index.scss:
--------------------------------------------------------------------------------
1 | .wp-block {
2 | .simple-podcasting__podcasting-platform-list {
3 | margin-bottom: 3rem;
4 | }
5 |
6 | .simple-podcasting__podcast-platforms {
7 | padding: 2.5rem 1rem 1rem 1rem;
8 | }
9 | }
10 |
11 | .simple-podcasting {
12 | &__podcast-platforms {
13 | padding: 1rem 0 1rem 0;
14 | }
15 |
16 | &__podcast-search-results {
17 | cursor: pointer;
18 | }
19 |
20 | &__select-show-popover {
21 | max-width: 400px;
22 | width: 100%;
23 |
24 | .components-popover__content {
25 | width: 100%;
26 | padding: 1rem;
27 | }
28 | }
29 |
30 | &__podcasting-platform-list {
31 | display: flex;
32 | flex-flow: row wrap;
33 |
34 | &--left {
35 | justify-content: start;
36 | }
37 |
38 | &--center {
39 | justify-content: center;
40 | }
41 |
42 | &--right {
43 | justify-content: end;
44 | }
45 |
46 | a {
47 | text-decoration: none !important;
48 | }
49 |
50 | img {
51 | display: block;
52 |
53 | @for $i from 1 through 6 {
54 | &.simple-pocasting__icon-size--#{$i * 16} {
55 | max-width: #{$i * 16}px;
56 | }
57 | }
58 | }
59 | }
60 |
61 | &__podcasting-platform-list-item {
62 | display: flex;
63 | align-self: center;
64 | padding: 0.75rem;
65 |
66 | @media screen and ( max-width: 480px ) {
67 | justify-content: center;
68 | width: 25%;
69 | }
70 | }
71 |
72 | &__podcasting-search-controls {
73 | position: relative;
74 |
75 | input[type="search"] {
76 | font-size: 1rem;
77 | }
78 | }
79 |
80 | &__podcasting-search-results {
81 | position: absolute;
82 | border: 1px solid;
83 | background-color: #fff;
84 | min-width: 200px;
85 | z-index: 10;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/assets/js/blocks/podcast/index.scss:
--------------------------------------------------------------------------------
1 | .wp-block-podcasting-podcast-outer {
2 | border: 1px solid #707070;
3 | border-radius: 4px;
4 | padding: 20px;
5 | }
6 |
7 | .wp-block-podcasting-podcast__container {
8 | margin-bottom: 10px;
9 |
10 | @media (min-width: 768px) {
11 | display: flex;
12 | }
13 | }
14 |
15 | .wp-block-podcasting-podcast__show-art {
16 | margin-bottom: 20px;
17 |
18 | @media (min-width: 768px) {
19 | flex-basis: 100px;
20 | margin-bottom: 0;
21 | margin-right: 20px;
22 | }
23 | }
24 |
25 | .wp-block-podcasting-podcast__image {
26 | aspect-ratio: 1/1;
27 | height: auto;
28 | position: relative;
29 |
30 | & img {
31 | display: block;
32 | height: 100%;
33 | object-fit: cover;
34 | width: 100%;
35 | }
36 | }
37 |
38 | .wp-block-podcasting-podcast__show-title {
39 | margin: 0;
40 | }
41 |
42 | .wp-block-podcasting-podcast__show-details {
43 | color: #575757;
44 | font-size: 0.875rem;
45 | text-transform: uppercase;
46 |
47 | & span {
48 | display: block;
49 | margin-right: 6px;
50 |
51 | @media (min-width: 768px) {
52 | display: inline;
53 | }
54 |
55 | &::after {
56 |
57 | @media (min-width: 768px) {
58 | content: '/';
59 | margin-left: 6px;
60 | }
61 | }
62 |
63 | &:last-child {
64 | margin-right: 0;
65 |
66 | &::after {
67 | display: none;
68 | }
69 | }
70 | }
71 | }
72 |
73 | .wp-block-podcasting-podcast__caption {
74 | margin-bottom: 10px;
75 | }
76 |
77 | .wp-block-podcasting-podcast {
78 | margin: 0;
79 |
80 | & audio {
81 | display: block;
82 | width: 100%;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/.github/workflows/phpunit.yml:
--------------------------------------------------------------------------------
1 | name: Unit Tests
2 |
3 | permissions:
4 | contents: read
5 |
6 | env:
7 | COMPOSER_VERSION: "2"
8 | COMPOSER_CACHE: "${{ github.workspace }}/.composer-cache"
9 |
10 | on:
11 | push:
12 | branches:
13 | - develop
14 | - trunk
15 | pull_request:
16 | branches:
17 | - develop
18 |
19 | jobs:
20 | phpunit:
21 | name: ${{ matrix.php.name }}
22 | runs-on: ubuntu-latest
23 |
24 | strategy:
25 | fail-fast: false
26 | matrix:
27 | php:
28 | - {name: 'PHP 7.4', version: '7.4'}
29 | - {name: 'PHP 8.1', version: '8.1'}
30 |
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
34 |
35 | - name: Set standard 10up cache directories
36 | run: |
37 | composer config -g cache-dir "${{ env.COMPOSER_CACHE }}"
38 |
39 | - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
40 | with:
41 | node-version-file: '.nvmrc'
42 |
43 | - name: Prepare composer cache
44 | uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
45 | with:
46 | path: ${{ env.COMPOSER_CACHE }}
47 | key: composer-${{ env.COMPOSER_VERSION }}-${{ hashFiles('**/composer.lock') }}
48 | restore-keys: |
49 | composer-${{ env.COMPOSER_VERSION }}-
50 |
51 | - name: Set PHP version
52 | uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
53 | with:
54 | php-version: '${{ matrix.php.version }}'
55 | coverage: none
56 | tools: composer:v2
57 |
58 | - name: Install dependencies
59 | run: composer install && npm install
60 |
61 | - name: Build
62 | run: npm run build
63 |
64 | - name: Test
65 | run: ./vendor/bin/phpunit -v
66 |
--------------------------------------------------------------------------------
/.github/workflows/close-stale-issues.yml:
--------------------------------------------------------------------------------
1 | name: 'Close stale issues'
2 |
3 | # **What it does**: Closes issues where the original author doesn't respond to a request for information.
4 | # **Why we have it**: To remove the need for maintainers to remember to check back on issues periodically to see if contributors have responded.
5 |
6 | on:
7 | schedule:
8 | # Schedule for every day at 1:30am UTC
9 | - cron: '30 1 * * *'
10 |
11 | permissions:
12 | issues: write
13 |
14 | jobs:
15 | stale:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
19 | with:
20 | days-before-stale: 7
21 | days-before-close: 7
22 | stale-issue-message: >
23 | It has been 7 days since more information was requested from you in this issue and we have not heard back. This issue is now marked as stale and will be closed in 7 days, but if you have more information to add then please comment and the issue will stay open.
24 | close-issue-message: >
25 | This issue has been automatically closed because there has been no response
26 | to our request for more information. With only the
27 | information that is currently in the issue, we don't have enough information
28 | to take action. Please reach out if you have or find the answers we need so
29 | that we can investigate further. See [this blog post on bug reports and the
30 | importance of repro steps](https://www.lee-dohm.com/2015/01/04/writing-good-bug-reports/)
31 | for more information about the kind of information that may be helpful.
32 | stale-issue-label: 'stale'
33 | close-issue-reason: 'not_planned'
34 | any-of-labels: 'needs:feedback'
35 | remove-stale-when-updated: true
36 |
--------------------------------------------------------------------------------
/assets/js/deprecated.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | attributes: {
4 | id: {
5 | type: 'number',
6 | },
7 | src: {
8 | type: 'string',
9 | source: 'attribute',
10 | selector: 'audio',
11 | attribute: 'src',
12 | },
13 | url: {
14 | type: 'string',
15 | source: 'meta',
16 | meta: 'podcast_url',
17 | },
18 | filesize: {
19 | type: 'number',
20 | source: 'meta',
21 | meta: 'podcast_filesize',
22 | },
23 | duration: {
24 | type: 'string',
25 | source: 'meta',
26 | meta: 'podcast_duration',
27 | },
28 | mime: {
29 | type: 'string',
30 | source: 'meta',
31 | meta: 'podcast_mime',
32 | },
33 | caption: {
34 | type: 'array',
35 | source: 'children',
36 | selector: 'figcaption',
37 | },
38 | captioned: {
39 | type: 'boolean',
40 | source: 'meta',
41 | meta: 'podcast_captioned',
42 | default: false,
43 | },
44 | explicit: {
45 | type: 'string',
46 | source: 'meta',
47 | meta: 'podcast_explicit',
48 | default: 'no',
49 | },
50 | enclosure: {
51 | type: 'string',
52 | source: 'meta',
53 | meta: 'enclosure',
54 | },
55 | seasonNumber: {
56 | type: 'string',
57 | source: 'meta',
58 | meta: 'podcast_season_number',
59 | },
60 | episodeNumber: {
61 | type: 'string',
62 | source: 'meta',
63 | meta: 'podcast_episode_number',
64 | },
65 | episodeType: {
66 | type: 'string',
67 | source: 'meta',
68 | meta: 'podcast_episode_type',
69 | }
70 | },
71 | supports: {
72 | multiple: false,
73 | },
74 | save: props => {
75 | const {
76 | id,
77 | src,
78 | caption
79 | } = props.attributes;
80 |
81 | return (
82 |
83 |
84 | { caption && caption.length > 0 && { caption } }
85 |
86 | );
87 | },
88 | },
89 | ];
90 |
--------------------------------------------------------------------------------
/tests/cypress/support/functions.js:
--------------------------------------------------------------------------------
1 | export const randomName = () => Math.random().toString(16).substring(7);
2 |
3 | export const getFirstImage = () => {
4 | cy.get('#menu-item-browse').click();
5 | cy.get('ul.attachments li:first-of-type').click();
6 | cy.get('.media-button-select').click();
7 | };
8 |
9 | /**
10 | * Populates a podcast taxonomy.
11 | * @param {Object} args The podcast data to populate.
12 | * @param {string} args.typeOfShowName The type of show.
13 | * @param {string} args.author The author of the podcast.
14 | * @param {string} args.summary The summary of the podcast.
15 | * @param {string} args.category The category of the podcast.
16 | * @param {boolean} args.onboarding Whether this is onboarding or not.
17 | */
18 | export const populatePodcast = (args) => {
19 | for (const [key, value] of Object.entries(args)) {
20 | switch (key) {
21 | case 'typeOfShowName':
22 | cy.get('#podcasting_type_of_show').select(value);
23 | break;
24 | case 'author':
25 | if (args.onboarding) {
26 | cy.get('input[name="podcast-artist"]').type(value);
27 | } else {
28 | cy.get('#podcasting_talent_name').type(value);
29 | }
30 | break;
31 | case 'summary':
32 | if (args.onboarding) {
33 | cy.get('textarea[name="podcast-description"]').type(value);
34 | } else {
35 | cy.get('#podcasting_summary').type(value);
36 | }
37 | break;
38 | case 'category':
39 | if (args.onboarding) {
40 | cy.get('select[name=podcast-category]').select(value);
41 | } else {
42 | cy.get('#podcasting_category_1').select(value);
43 | }
44 | break;
45 | }
46 | }
47 | // Get first image from media library.
48 | if (args.onboarding) {
49 | cy.get('#simple-podcasting__upload-cover-image').click();
50 | } else {
51 | cy.get('#image-podcasting_image').click();
52 | }
53 | getFirstImage();
54 | };
55 |
56 | export const deleteAllTerms = () => {
57 | cy.get('body').then(($body) => {
58 | if ($body.find('#doaction').length > 0) {
59 | cy.get('#cb-select-all-1').click({ force: true });
60 | cy.get('#bulk-action-selector-top').select('delete');
61 | cy.get('#doaction').click();
62 | }
63 | });
64 | };
65 |
--------------------------------------------------------------------------------
/includes/blocks/podcast-transcript/formats.js:
--------------------------------------------------------------------------------
1 | import { registerFormatType, toggleFormat } from '@wordpress/rich-text';
2 | import { BlockControls } from '@wordpress/block-editor';
3 | import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
4 | import { useSelect } from '@wordpress/data';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | const Cite = ({ isActive, onChange, value }) => {
8 | const selectedBlock = useSelect((select) => {
9 | return select('core/block-editor').getSelectedBlock();
10 | }, []);
11 |
12 | if (
13 | selectedBlock &&
14 | selectedBlock.name !== 'podcasting/podcast-transcript'
15 | ) {
16 | return null;
17 | }
18 |
19 | return (
20 |
21 |
22 | {
26 | onChange(
27 | toggleFormat(value, {
28 | type: 'podcasting/transcript-cite',
29 | })
30 | );
31 | }}
32 | isActive={isActive}
33 | />
34 |
35 |
36 | );
37 | };
38 |
39 | registerFormatType('podcasting/transcript-cite', {
40 | title: __('Cite', 'simple-podcasting'),
41 | tagName: 'cite',
42 | className: null,
43 | edit: Cite,
44 | });
45 |
46 | const Time = ({ isActive, onChange, value }) => {
47 | const selectedBlock = useSelect((select) => {
48 | return select('core/block-editor').getSelectedBlock();
49 | }, []);
50 |
51 | if (
52 | selectedBlock &&
53 | selectedBlock.name !== 'podcasting/podcast-transcript'
54 | ) {
55 | return null;
56 | }
57 |
58 | return (
59 |
60 |
61 | {
65 | onChange(
66 | toggleFormat(value, {
67 | type: 'podcasting/transcript-time',
68 | })
69 | );
70 | }}
71 | isActive={isActive}
72 | />
73 |
74 |
75 | );
76 | };
77 |
78 | registerFormatType('podcasting/transcript-time', {
79 | title: __('Time', 'simple-podcasting'),
80 | tagName: 'time',
81 | className: null,
82 | edit: Time,
83 | });
84 |
--------------------------------------------------------------------------------
/tests/cypress/integration/onboarding.test.js:
--------------------------------------------------------------------------------
1 | const {
2 | randomName,
3 | populatePodcast,
4 | deleteAllTerms,
5 | } = require('../support/functions');
6 |
7 | describe('Onboarding tests', () => {
8 | beforeEach(() => {
9 | cy.login();
10 | cy.uploadMedia('tests/cypress/fixtures/example.jpg');
11 | cy.activatePlugin('simple-podcasting');
12 | cy.visit(
13 | '/wp-admin/edit-tags.php?taxonomy=podcasting_podcasts&podcasts=true'
14 | );
15 | deleteAllTerms();
16 | cy.deactivatePlugin('simple-podcasting');
17 | cy.visit('/wp-admin/options.php');
18 | cy.get('body').then(($body) => {
19 | if ($body.find('#simple_podcasting_onboarding').length !== 0) {
20 | cy.get('#simple_podcasting_onboarding')
21 | .click()
22 | .type('{selectAll}no');
23 | cy.get('.submit input[type=submit]').click();
24 | }
25 | });
26 | cy.activatePlugin('simple-podcasting');
27 | });
28 |
29 | it('Should indicate errors', () => {
30 | cy.url().should('include', 'simple-podcasting-onboarding');
31 | cy.url().should('include', 'step=1');
32 |
33 | cy.get('#simple-podcasting__create-podcast-button')
34 | .closest('form')
35 | .submit();
36 |
37 | cy.get('.notice-error').should(
38 | 'contain',
39 | 'A podcast name is required.'
40 | );
41 | });
42 |
43 | it('Should pass onboarding', () => {
44 | cy.url().should('include', 'simple-podcasting-onboarding');
45 | cy.url().should('include', 'step=1');
46 |
47 | const podcastName = 'Onboarding ' + randomName();
48 | cy.get('input[name=podcast-name]').click().type(podcastName);
49 | populatePodcast({
50 | author: 'Person Doe',
51 | summary: 'Lorem ipsum dolor',
52 | category: 'Arts',
53 | onboarding: true,
54 | });
55 | cy.get('#simple-podcasting__create-podcast-button')
56 | .closest('form')
57 | .submit();
58 |
59 | cy.url().should('include', 'step=2');
60 |
61 | cy.visit(
62 | '/wp-admin/edit-tags.php?taxonomy=podcasting_podcasts&podcasts=true'
63 | );
64 |
65 | // Podcast was created.
66 | cy.contains(podcastName);
67 |
68 | // Option was saved.
69 | cy.visit('/wp-admin/options.php');
70 | cy.get('#simple_podcasting_onboarding').should(
71 | 'have.value',
72 | 'completed'
73 | );
74 | });
75 | });
76 |
--------------------------------------------------------------------------------
/includes/block-patterns.php:
--------------------------------------------------------------------------------
1 | PODCASTING_TAXONOMY_NAME,
17 | 'fields' => 'ids',
18 | ]
19 | );
20 |
21 | if ( empty( $podcast_terms ) ) {
22 | return;
23 | }
24 |
25 | register_block_pattern(
26 | 'podcasting/podcast-grid',
27 | array(
28 | 'title' => __( 'Podcast Grid', 'simple-podcasting' ),
29 | 'description' => _x( 'Podcast Grid', 'This block pattern is used to display podcast in a grid structure.', 'simple-podcasting' ),
30 | 'categories' => [ 'query' ],
31 | 'content' => '
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ',
47 | )
48 | );
49 | }
50 | add_action( 'init', __NAMESPACE__ . '\init' );
51 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@10up/simple-podcasting",
3 | "version": "1.9.1",
4 | "description": "A simple podcasting solution for WordPress. ",
5 | "homepage": "https://github.com/10up/simple-podcasting",
6 | "bugs": {
7 | "url": "https://github.com/10up/simple-podcasting/issues"
8 | },
9 | "license": "GPL-2.0-or-later",
10 | "author": {
11 | "name": "10up",
12 | "email": "opensource@10up.com",
13 | "url": "https://10up.com",
14 | "role": "developer"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/10up/simple-podcasting"
19 | },
20 | "scripts": {
21 | "start": "wp-scripts start",
22 | "build": "wp-scripts build",
23 | "deploy": "npm install && npm run build",
24 | "makepot": "wpi18n makepot --domain-path languages --pot-file simple-podcasting.pot --type plugin --main-file simple-podcasting.php --exclude node_modules,tests,docs,vendor",
25 | "prepare": "husky install",
26 | "wp-env": "wp-env",
27 | "env:start": "wp-env start",
28 | "env:stop": "wp-env stop",
29 | "cypress:open": "cypress open --browser chrome --config-file tests/cypress/config.config.js",
30 | "cypress:run": "cypress run --browser chrome --config-file tests/cypress/config.config.js"
31 | },
32 | "lint-staged": {
33 | "*.php": [
34 | "./vendor/bin/phpcs --standard=10up-Default --extensions=php --warning-severity=8 -s --runtime-set testVersion 7.4"
35 | ],
36 | "tests/**/*.js": [
37 | "./node_modules/.bin/wp-scripts format"
38 | ]
39 | },
40 | "devDependencies": {
41 | "@10up/cypress-wp-utils": "^0.3.0",
42 | "@wordpress/plugins": "^6.2.0",
43 | "@wordpress/prettier-config": "^2.2.0",
44 | "ansi-regex": ">=6.0.1",
45 | "@wordpress/env": "^10.28.0",
46 | "@wordpress/scripts": "^30.6.0",
47 | "copy-webpack-plugin": "^11.0.0",
48 | "cypress": "^13.2.0",
49 | "cypress-file-upload": "^5.0.8",
50 | "cypress-localstorage-commands": "^2.2.4",
51 | "cypress-mochawesome-reporter": "^3.6.0",
52 | "husky": "^8.0.1",
53 | "json-schema": ">=0.4.0",
54 | "lint-staged": "^13.0.3",
55 | "markdown-it": "^13.0.1",
56 | "mochawesome-json-to-md": "^0.7.2",
57 | "node-wp-i18n": "^1.2.6"
58 | },
59 | "prettier": "@wordpress/prettier-config",
60 | "dependencies": {
61 | "use-debounce": "^8.0.4"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/includes/rest-external-url.php:
--------------------------------------------------------------------------------
1 | \WP_REST_Server::READABLE,
37 | 'callback' => __NAMESPACE__ . '\handle_request',
38 | 'permission_callback' => function () {
39 | return true;
40 | },
41 | 'args' => array(
42 | 'url' => array(
43 | 'required' => true,
44 | 'sanitize_callback' => 'sanitize_text_field',
45 | ),
46 | ),
47 | )
48 | );
49 | }
50 |
51 | /**
52 | * Callbakc for the external-url endpoint.
53 | *
54 | * @param \WP_REST_Request $request The API request
55 | *
56 | * @return mixed|\WP_REST_Response
57 | */
58 | function handle_request( \WP_REST_Request $request ) {
59 |
60 | $url = $request['url'];
61 | $cache_key = 'spc_external_url_' . $url;
62 | $podcast_meta = get_transient( $cache_key );
63 | if ( false === $podcast_meta ) {
64 | if ( filter_var( $url, FILTER_VALIDATE_URL ) ) {
65 | $podcast_meta = \tenup_podcasting\helpers\get_podcast_meta_from_url( $url );
66 | if ( $podcast_meta ) {
67 | $response = array(
68 | 'success' => true,
69 | 'data' => $podcast_meta,
70 | );
71 | set_transient( $cache_key, $podcast_meta, MONTH_IN_SECONDS ); // We add the long expiry so we don't autoload the option in a non-object-cached env.
72 | }
73 | } else {
74 | $response = array(
75 | 'success' => false,
76 | 'message' => 'Invalid URL parameter passed',
77 | );
78 | }
79 | } else {
80 | $response = array(
81 | 'success' => true,
82 | 'data' => $podcast_meta,
83 | );
84 | }
85 | return rest_ensure_response( $response );
86 | }
87 |
--------------------------------------------------------------------------------
/includes/transcripts.php:
--------------------------------------------------------------------------------
1 | term_id ) ) . $post->post_name . '/transcript/';
73 | }
74 |
75 | /**
76 | * Adds