From 043f49c784bc007ca0fa756ca4ed2d3b08843ad9 Mon Sep 17 00:00:00 2001 From: Yassine Doghri Date: Thu, 27 Aug 2020 10:05:44 +0000 Subject: [PATCH] feat: add platforms form in podcast settings - set and remove platform links for a podcast - remove unnecessary fields from platforms and platform_links tables - add platforms svg icons to show in form - update platform and auth seeders - update svgo config for images --- .svgo.yml | 5 +- app/Config/Routes.php | 24 ++ app/Controllers/Admin/PodcastSettings.php | 98 ++++++ .../2020-06-05-190000_add_platforms.php | 38 +-- .../2020-06-08-160000_add_platform_links.php | 13 +- app/Database/Seeds/AuthSeeder.php | 5 + app/Database/Seeds/PlatformSeeder.php | 304 ++++-------------- app/Entities/Platform.php | 24 ++ app/Helpers/svg_helper.php | 27 ++ app/Language/en/AdminNavigation.php | 1 + app/Language/en/Breadcrumb.php | 2 + app/Language/en/Platforms.php | 22 ++ app/Models/PlatformLinkModel.php | 33 -- app/Models/PlatformModel.php | 51 +++ app/Views/_assets/icons/delete-bin.svg | 6 + app/Views/_assets/icons/upload.svg | 6 + .../_assets/images/platforms/_default.svg | 7 + .../images/platforms/apple-podcasts.svg | 14 + .../_assets/images/platforms/blubrry.svg | 6 + .../_assets/images/platforms/castbox.svg | 17 + app/Views/_assets/images/platforms/castro.svg | 17 + app/Views/_assets/images/platforms/deezer.svg | 54 ++++ .../images/platforms/google-podcasts.svg | 14 + app/Views/_assets/images/platforms/ivoox.svg | 7 + .../_assets/images/platforms/listennotes.svg | 10 + .../_assets/images/platforms/overcast.svg | 6 + .../_assets/images/platforms/playerfm.svg | 9 + .../_assets/images/platforms/pocketcasts.svg | 6 + .../_assets/images/platforms/podbean.svg | 9 + .../images/platforms/podcast-addict.svg | 13 + .../_assets/images/platforms/podchaser.svg | 8 + .../_assets/images/platforms/podtail.svg | 13 + .../_assets/images/platforms/radiopublic.svg | 8 + .../_assets/images/platforms/spotify.svg | 6 + .../_assets/images/platforms/spreaker.svg | 6 + .../_assets/images/platforms/stitcher.svg | 10 + app/Views/_assets/images/platforms/tunein.svg | 8 + app/Views/admin/_header.php | 2 +- app/Views/admin/_sidenav.php | 2 +- .../admin/podcast/settings/dashboard.php | 9 + .../admin/podcast/settings/platforms.php | 99 ++++++ app/Views/admin/podcast/view.php | 4 + app/Views/auth/_layout.php | 5 +- package.json | 2 +- 44 files changed, 700 insertions(+), 330 deletions(-) create mode 100644 app/Controllers/Admin/PodcastSettings.php create mode 100644 app/Entities/Platform.php create mode 100644 app/Language/en/Platforms.php delete mode 100644 app/Models/PlatformLinkModel.php create mode 100644 app/Views/_assets/icons/delete-bin.svg create mode 100644 app/Views/_assets/icons/upload.svg create mode 100644 app/Views/_assets/images/platforms/_default.svg create mode 100644 app/Views/_assets/images/platforms/apple-podcasts.svg create mode 100644 app/Views/_assets/images/platforms/blubrry.svg create mode 100644 app/Views/_assets/images/platforms/castbox.svg create mode 100644 app/Views/_assets/images/platforms/castro.svg create mode 100644 app/Views/_assets/images/platforms/deezer.svg create mode 100644 app/Views/_assets/images/platforms/google-podcasts.svg create mode 100644 app/Views/_assets/images/platforms/ivoox.svg create mode 100644 app/Views/_assets/images/platforms/listennotes.svg create mode 100644 app/Views/_assets/images/platforms/overcast.svg create mode 100644 app/Views/_assets/images/platforms/playerfm.svg create mode 100644 app/Views/_assets/images/platforms/pocketcasts.svg create mode 100644 app/Views/_assets/images/platforms/podbean.svg create mode 100644 app/Views/_assets/images/platforms/podcast-addict.svg create mode 100644 app/Views/_assets/images/platforms/podchaser.svg create mode 100644 app/Views/_assets/images/platforms/podtail.svg create mode 100644 app/Views/_assets/images/platforms/radiopublic.svg create mode 100644 app/Views/_assets/images/platforms/spotify.svg create mode 100644 app/Views/_assets/images/platforms/spreaker.svg create mode 100644 app/Views/_assets/images/platforms/stitcher.svg create mode 100644 app/Views/_assets/images/platforms/tunein.svg create mode 100644 app/Views/admin/podcast/settings/dashboard.php create mode 100644 app/Views/admin/podcast/settings/platforms.php diff --git a/.svgo.yml b/.svgo.yml index 562727d8..b4177b4f 100644 --- a/.svgo.yml +++ b/.svgo.yml @@ -1,8 +1,5 @@ plugins: - removeXMLNS: true - removeDimensions: true - - addAttributesToSVGElement: - attributes: - - width: "1em" - - height: "1em" - sortAttrs: true + - prefixIds: true diff --git a/app/Config/Routes.php b/app/Config/Routes.php index be223070..2472310c 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -196,6 +196,30 @@ $routes->group( ]); }); }); + + $routes->group('settings', function ($routes) { + $routes->get('/', 'PodcastSettings/$1', [ + 'as' => 'podcast-settings', + ]); + $routes->get('platforms', 'PodcastSettings::platforms/$1', [ + 'as' => 'platforms', + 'filter' => 'permission:podcast-manage_platforms', + ]); + $routes->post( + 'platforms', + 'PodcastSettings::attemptPlatformsUpdate/$1', + ['filter' => 'permission:podcast-manage_platforms'] + ); + + $routes->get( + 'platforms/(:num)/remove-link', + 'PodcastSettings::removePlatformLink/$1/$2', + [ + 'as' => 'platforms-remove', + 'filter' => 'permission:podcast-manage_platforms', + ] + ); + }); }); }); diff --git a/app/Controllers/Admin/PodcastSettings.php b/app/Controllers/Admin/PodcastSettings.php new file mode 100644 index 00000000..012128b0 --- /dev/null +++ b/app/Controllers/Admin/PodcastSettings.php @@ -0,0 +1,98 @@ +podcast = (new PodcastModel())->find($params[0]))) { + throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound(); + } + unset($params[0]); + + return $this->$method(...$params); + } + + public function index() + { + return view('admin/podcast/settings/dashboard'); + } + + public function platforms() + { + helper('form'); + + $data = [ + 'podcast' => $this->podcast, + 'platforms' => (new PlatformModel())->getPlatformsWithLinks(), + ]; + + replace_breadcrumb_params([0 => $this->podcast->title]); + return view('admin/podcast/settings/platforms', $data); + } + + public function attemptPlatformsUpdate() + { + $platformModel = new PlatformModel(); + $validation = Services::validation(); + + $platformLinksData = []; + foreach ( + $this->request->getPost('platforms') + as $platformName => $platformLink + ) { + $platformLinkUrl = $platformLink['url']; + if ( + !empty($platformLinkUrl) && + $validation->check($platformLinkUrl, 'valid_url') + ) { + $platformId = $platformModel->getPlatformId($platformName); + array_push($platformLinksData, [ + 'platform_id' => $platformId, + 'podcast_id' => $this->podcast->id, + 'link_url' => $platformLinkUrl, + 'visible' => array_key_exists('visible', $platformLink) + ? $platformLink['visible'] == 'yes' + : false, + ]); + } + } + + $platformModel->savePlatformLinks( + $this->podcast->id, + $platformLinksData + ); + + return redirect() + ->back() + ->with('message', lang('Platforms.messages.updateSuccess')); + } + + public function removePlatformLink($platformId) + { + (new PlatformModel())->removePlatformLink( + $this->podcast->id, + $platformId + ); + + return redirect() + ->back() + ->with('message', lang('Platforms.messages.removeLinkSuccess')); + } +} diff --git a/app/Database/Migrations/2020-06-05-190000_add_platforms.php b/app/Database/Migrations/2020-06-05-190000_add_platforms.php index c012efd6..d24750f4 100644 --- a/app/Database/Migrations/2020-06-05-190000_add_platforms.php +++ b/app/Database/Migrations/2020-06-05-190000_add_platforms.php @@ -29,6 +29,10 @@ class AddPlatforms extends Migration 'constraint' => 191, 'unique' => true, ], + 'label' => [ + 'type' => 'VARCHAR', + 'constraint' => 191, + ], 'home_url' => [ 'type' => 'VARCHAR', 'constraint' => 191, @@ -37,39 +41,9 @@ class AddPlatforms extends Migration 'type' => 'VARCHAR', 'constraint' => 191, 'null' => true, + 'default' => null, ], - 'iosapp_url' => [ - 'type' => 'VARCHAR', - 'constraint' => 191, - 'null' => true, - ], - 'androidapp_url' => [ - 'type' => 'VARCHAR', - 'constraint' => 191, - 'null' => true, - ], - 'comment' => [ - 'type' => 'TEXT', - 'null' => true, - ], - 'display_by_default' => [ - 'type' => 'TINYINT', - 'constraint' => 1, - 'default' => 0, - ], - 'ios_deeplink' => [ - 'type' => 'TINYINT', - 'constraint' => 1, - 'default' => 0, - ], - 'android_deeplink' => [ - 'type' => 'TINYINT', - 'constraint' => 1, - 'default' => 0, - 'comment' => - 'Android deeplinking for this platform: 0=No, 1=Manual, 2=Automatic.', - ], - 'logo_file_name' => [ + 'icon_filename' => [ 'type' => 'VARCHAR', 'constraint' => 1024, ], diff --git a/app/Database/Migrations/2020-06-08-160000_add_platform_links.php b/app/Database/Migrations/2020-06-08-160000_add_platform_links.php index bc44741f..cf0a3be0 100644 --- a/app/Database/Migrations/2020-06-08-160000_add_platform_links.php +++ b/app/Database/Migrations/2020-06-08-160000_add_platform_links.php @@ -18,12 +18,6 @@ class AddPlatformLinks extends Migration public function up() { $this->forge->addField([ - 'id' => [ - 'type' => 'BIGINT', - 'constraint' => 20, - 'unsigned' => true, - 'auto_increment' => true, - ], 'podcast_id' => [ 'type' => 'BIGINT', 'constraint' => 20, @@ -38,11 +32,6 @@ class AddPlatformLinks extends Migration 'type' => 'VARCHAR', 'constraint' => 191, ], - 'comment' => [ - 'type' => 'TEXT', - 'comment' => 'Comment.', - 'null' => true, - ], 'visible' => [ 'type' => 'TINYINT', 'constraint' => 1, @@ -55,7 +44,7 @@ class AddPlatformLinks extends Migration 'type' => 'TIMESTAMP', ], ]); - $this->forge->addKey('id', true); + $this->forge->addPrimaryKey(['podcast_id', 'platform_id']); $this->forge->addForeignKey('podcast_id', 'podcasts', 'id'); $this->forge->addForeignKey('platform_id', 'platforms', 'id'); $this->forge->createTable('platform_links'); diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php index 06286125..ddeac94b 100644 --- a/app/Database/Seeds/AuthSeeder.php +++ b/app/Database/Seeds/AuthSeeder.php @@ -203,6 +203,11 @@ class AuthSeeder extends Seeder 'description' => 'Publish / unpublish a podcast', 'has_permission' => ['podcast_admin'], ], + [ + 'name' => 'manage_platforms', + 'description' => 'Set / remove platform links of a podcast', + 'has_permission' => ['podcast_admin'], + ], ], 'podcast_episodes' => [ [ diff --git a/app/Database/Seeds/PlatformSeeder.php b/app/Database/Seeds/PlatformSeeder.php index c46a0e62..11e6b96b 100644 --- a/app/Database/Seeds/PlatformSeeder.php +++ b/app/Database/Seeds/PlatformSeeder.php @@ -19,328 +19,148 @@ class PlatformSeeder extends Seeder { $data = [ [ - 'name' => 'Apple Podcasts', + 'name' => 'apple-podcasts', + 'label' => 'Apple Podcasts', 'home_url' => 'https://www.apple.com/itunes/podcasts/', 'submit_url' => 'https://podcastsconnect.apple.com/my-podcasts/new-feed', - 'iosapp_url' => - 'https://apps.apple.com/app/apple-podcasts/id525463029', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 1, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'ApplePodcasts.png', + 'icon_filename' => 'apple-podcasts.svg', ], [ - 'name' => 'Blubrry', + 'name' => 'blubrry', + 'label' => 'Blubrry', 'home_url' => 'https://www.blubrry.com/', 'submit_url' => 'https://www.blubrry.com/addpodcast.php', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'blubrry.png', + 'icon_filename' => 'blubrry.svg', ], [ - 'name' => 'Castbox', + 'name' => 'castbox', + 'label' => 'Castbox', 'home_url' => 'https://castbox.fm/', 'submit_url' => 'https://helpcenter.castbox.fm/portal/kb/articles/submit-my-podcast', - 'iosapp_url' => - 'https://apps.apple.com/app/castbox-the-podcast-app/id1243410543', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=fm.castbox.audiobook.radio.podcast&hl=fr', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'Castbox.png', + 'icon_filename' => 'castbox.svg', ], [ - 'name' => 'Castro', + 'name' => 'castro', + 'label' => 'Castro', 'home_url' => 'http://castro.fm/', - 'submit_url' => '', - 'iosapp_url' => - 'https://apps.apple.com/app/apple-store/id1080840241?ign-mpt=uo%3D4', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'Castro.png', + 'submit_url' => null, + 'icon_filename' => 'castro.svg', ], [ - 'name' => 'Chartable', - 'home_url' => 'https://chartable.com/', - 'submit_url' => 'https://chartable.com/podcasts/submit', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'Chartable.png', - ], - [ - 'name' => 'Deezer', + 'name' => 'deezer', + 'label' => 'Deezer', 'home_url' => 'https://www.deezer.com/', 'submit_url' => 'https://podcasters.deezer.com/submission', - 'iosapp_url' => - 'https://apps.apple.com/app/deezer-music-podcast-player/id292738169', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=deezer.android.app', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'Deezer.png', + 'icon_filename' => 'deezer.svg', ], [ - 'name' => 'Google Podcasts', + 'name' => 'google-podcasts', + 'label' => 'Google Podcasts', 'home_url' => 'https://podcasts.google.com/about', 'submit_url' => 'https://search.google.com/search-console/about', - 'iosapp_url' => '', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.google.android.apps.podcasts', - 'comment' => '', - 'display_by_default' => 1, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'GooglePodcasts.png', + 'icon_filename' => 'google-podcasts.svg', ], [ - 'name' => 'Ivoox', + 'name' => 'ivoox', + 'label' => 'Ivoox', 'home_url' => 'https://www.ivoox.com/', - 'submit_url' => '', - 'iosapp_url' => - 'https://apps.apple.com/app/apple-store/id542673545', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.ivoox.app', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'ivoox.png', + 'submit_url' => null, + 'icon_filename' => 'ivoox.svg', ], [ - 'name' => 'ListenNotes', + 'name' => 'listennotes', + 'label' => 'ListenNotes', 'home_url' => 'https://www.listennotes.com/', 'submit_url' => 'https://www.listennotes.com/submit/', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'ListenNotes.png', - ], - //array('name' => 'Majelan', 'home_url' => 'https://www.majelan.com/', 'submit_url' => 'https://support.majelan.com/article/64-how-to-add-my-podcast-on-majelan', 'iosapp_url' => 'https://apps.apple.com/app/majelan-best-audio-stories/id1443711081', 'androidapp_url' => 'https://play.google.com/store/apps/details?id=com.majelanapp', 'comment' => 'Uses public podcasts indexes. Send a DM if you are not listed.', 'display_by_default' => 0, 'ios_deeplink' => 0, 'android_deeplink' => 2, 'logo_file_name' => 'Majelan.png'), // https://aide.majelan.com/article/130-pourquoi-nouvelle-application-7-juillet - [ - 'name' => 'Mytuner', - 'home_url' => 'https://mytuner-radio.com/', - 'submit_url' => 'https://mytuner-radio.com/broadcasters/', - 'iosapp_url' => - 'https://apps.apple.com/app/apple-store/id520502858', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.appgeneration.itunerfree', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'myTuner.png', + 'icon_filename' => 'listennotes.svg', ], [ - 'name' => 'Overcast', + 'name' => 'overcast', + 'label' => 'Overcast', 'home_url' => 'https://overcast.fm/', 'submit_url' => 'https://overcast.fm/podcasterinfo', - 'iosapp_url' => - 'https://apps.apple.com/us/app/overcast-podcast-player/id888422857', - 'androidapp_url' => '', - 'comment' => - 'Overcast uses Apple Podcasts index, no podcast submission needed.', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'Overcast.png', + 'icon_filename' => 'overcast.svg', ], [ - 'name' => 'Player.Fm', + 'name' => 'playerfm', + 'label' => 'Player.Fm', 'home_url' => 'https://player.fm/', 'submit_url' => 'https://player.fm/importer/feed', - 'iosapp_url' => - 'https://apps.apple.com/app/podcast-app-by-player-fm/id940568467', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=fm.player', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'PlayerFM.png', + 'icon_filename' => 'playerfm.svg', ], [ - 'name' => 'Pocketcasts', + 'name' => 'pocketcasts', + 'label' => 'Pocketcasts', 'home_url' => 'https://www.pocketcasts.com/', 'submit_url' => 'https://www.pocketcasts.com/submit/', - 'iosapp_url' => - 'https://apps.apple.com/app/pocket-casts/id414834813', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=au.com.shiftyjelly.pocketcasts', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'PocketCasts.png', + 'icon_filename' => 'pocketcasts.svg', ], [ - 'name' => 'Podbean', + 'name' => 'podbean', + 'label' => 'Podbean', 'home_url' => 'https://www.podbean.com/', 'submit_url' => 'https://www.podbean.com/site/submitPodcast', - 'iosapp_url' => - 'https://apps.apple.com/app/apple-store/id973361050', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.podbean.app.podcast', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'Podbean.png', + 'icon_filename' => 'podbean.svg', ], [ - 'name' => 'Podcast Addict', + 'name' => 'podcast-addict', + 'label' => 'Podcast Addict', 'home_url' => 'https://podcastaddict.com/', 'submit_url' => 'https://podcastaddict.com/submit', - 'iosapp_url' => '', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.bambuna.podcastaddict', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'podcastaddict.svg', + 'icon_filename' => 'podcast-addict.svg', ], [ - 'name' => 'Podcastland', - 'home_url' => 'https://podcastland.com/', - 'submit_url' => '', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => 'Uses Apple Podcasts index.', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'PodcastLand.png', - ], - [ - 'name' => 'Podcastrepublic', - 'home_url' => 'https://www.podcastrepublic.net/', - 'submit_url' => - 'https://www.podcastrepublic.net/for-podcast-publisher', - 'iosapp_url' => '', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.itunestoppodcastplayer.app', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'PodcastRepublic.png', - ], - [ - 'name' => 'Podchaser', + 'name' => 'podchaser', + 'label' => 'Podchaser', 'home_url' => 'https://www.podchaser.com/', 'submit_url' => 'https://www.podchaser.com/creators/edit', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'Podchaser.png', + 'icon_filename' => 'podchaser.svg', ], [ - 'name' => 'Podtail', + 'name' => 'podtail', + 'label' => 'Podtail', 'home_url' => 'https://podtail.com/', 'submit_url' => 'https://podtail.com/about/faq/', - 'iosapp_url' => '', - 'androidapp_url' => '', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 0, - 'logo_file_name' => 'Podtail.png', + 'icon_filename' => 'podtail.svg', ], [ - 'name' => 'Radiopublic', + 'name' => 'radiopublic', + 'label' => 'Radiopublic', 'home_url' => 'https://radiopublic.com/', 'submit_url' => 'https://podcasters.radiopublic.com/signup', - 'iosapp_url' => - 'https://apps.apple.com/app/radiopublic-free-podcasts/id1113752736', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.radiopublic.android', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'RadioPublic.png', + 'icon_filename' => 'radiopublic.svg', ], [ - 'name' => 'Spotify', + 'name' => 'spotify', + 'label' => 'Spotify', 'home_url' => 'https://www.spotify.com/', 'submit_url' => 'https://podcasters.spotify.com/submit', - 'iosapp_url' => - 'https://apps.apple.com/app/spotify-music/id324684580', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.spotify.music', - 'comment' => '', - 'display_by_default' => 1, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'Spotify.png', + 'icon_filename' => 'spotify.svg', ], [ - 'name' => 'Spreaker', + 'name' => 'spreaker', + 'label' => 'Spreaker', 'home_url' => 'https://www.spreaker.com/', 'submit_url' => 'https://www.spreaker.com/cms/shows/rss-import', - 'iosapp_url' => - 'https://apps.apple.com/app/spreaker-podcast-radio/id388449677', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.spreaker.android', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'Spreaker.png', + 'icon_filename' => 'spreaker.svg', ], [ - 'name' => 'Stitcher', + 'name' => 'stitcher', + 'label' => 'Stitcher', 'home_url' => 'https://www.stitcher.com/', 'submit_url' => 'https://www.stitcher.com/content-providers', - 'iosapp_url' => 'https://apps.apple.com/app/id288087905', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=com.stitcher.app', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 1, - 'logo_file_name' => 'Stitcher.png', + 'icon_filename' => 'stitcher.svg', ], [ - 'name' => 'TuneIn', + 'name' => 'tunein', + 'label' => 'TuneIn', 'home_url' => 'https://tunein.com/', 'submit_url' => 'https://help.tunein.com/contact/add-podcast-S19TR3Sdf', - 'iosapp_url' => - 'https://apps.apple.com/app/tunein-radio/id418987775', - 'androidapp_url' => - 'https://play.google.com/store/apps/details?id=tunein.player', - 'comment' => '', - 'display_by_default' => 0, - 'ios_deeplink' => 0, - 'android_deeplink' => 2, - 'logo_file_name' => 'TuneIn.png', + 'icon_filename' => 'tunein.svg', ], ]; $this->db->table('platforms')->insertBatch($data); diff --git a/app/Entities/Platform.php b/app/Entities/Platform.php new file mode 100644 index 00000000..cd51209e --- /dev/null +++ b/app/Entities/Platform.php @@ -0,0 +1,24 @@ + 'integer', + 'name' => 'string', + 'label' => 'string', + 'home_url' => 'string', + 'submit_url' => '?string', + 'link_url' => '?string', + 'visible' => '?boolean', + ]; +} diff --git a/app/Helpers/svg_helper.php b/app/Helpers/svg_helper.php index 87d9f787..a3b353d7 100644 --- a/app/Helpers/svg_helper.php +++ b/app/Helpers/svg_helper.php @@ -45,3 +45,30 @@ function svg($name, $class = null) } return $svg_contents; } + +/** + * Returns the inline svg platform icon. Returns the default icon if not found. + * + * @param string $name name of the image file without the .svg extension + * @param string $class to be added to the svg string + * @return string svg contents + */ +function platform_icon($name, $class = null) +{ + try { + $svg_contents = file_get_contents('assets/images/platforms/' . $name); + } catch (\Exception $e) { + $svg_contents = file_get_contents( + 'assets/images/platforms/_default.svg' + ); + } + + if ($class) { + $svg_contents = str_replace( + ' 'Home', 'podcast-list' => 'All podcasts', 'podcast-create' => 'New podcast', + 'podcast-import' => 'Import a podcast', 'user-list' => 'All users', 'user-create' => 'New user', 'page-list' => 'All pages', diff --git a/app/Language/en/Breadcrumb.php b/app/Language/en/Breadcrumb.php index d434287b..70e5beb9 100644 --- a/app/Language/en/Breadcrumb.php +++ b/app/Language/en/Breadcrumb.php @@ -20,4 +20,6 @@ return [ 'my-account' => 'my account', 'change-password' => 'change password', 'import' => 'feed import', + 'settings' => 'settings', + 'platforms' => 'platforms', ]; diff --git a/app/Language/en/Platforms.php b/app/Language/en/Platforms.php new file mode 100644 index 00000000..d0367524 --- /dev/null +++ b/app/Language/en/Platforms.php @@ -0,0 +1,22 @@ + 'Platforms', + 'home_url' => 'Go to {platformName} website', + 'submit_url' => 'Submit your podcast on {platformName}', + 'visible' => 'Display in podcast homepage?', + 'remove' => 'Remove {platformName}', + 'submit' => 'Save', + 'messages' => [ + 'updateSuccess' => 'Platform links have been successfully updated!', + 'removeLinkSuccess' => 'The platform link has been removed.', + 'removeLinkError' => + 'The platform link could not be removed. Try again.', + ], +]; diff --git a/app/Models/PlatformLinkModel.php b/app/Models/PlatformLinkModel.php deleted file mode 100644 index fbddcc46..00000000 --- a/app/Models/PlatformLinkModel.php +++ /dev/null @@ -1,33 +0,0 @@ -select( + 'platforms.*, platform_links.link_url, platform_links.visible' + ) + ->join( + 'platform_links', + 'platform_links.platform_id = platforms.id', + 'left' + ) + ->findAll(); + } + + public function savePlatformLinks($podcastId, $platformLinksData) + { + // Remove already previously set platforms to overwrite them + $this->db + ->table('platform_links') + ->delete(['podcast_id' => $podcastId]); + + // Set platformLinks + return $this->db + ->table('platform_links') + ->insertBatch($platformLinksData); + } + + public function getPlatformId($platform) + { + if (is_numeric($platform)) { + return (int) $platform; + } + + $p = $this->where('name', $platform)->first(); + + if (!$p) { + $this->error = lang('Platform.platformNotFound', [$platform]); + + return false; + } + + return (int) $p->id; + } + + public function removePlatformLink($podcastId, $platformId) + { + return $this->db->table('platform_links')->delete([ + 'podcast_id' => $podcastId, + 'platform_id' => $platformId, + ]); + } } diff --git a/app/Views/_assets/icons/delete-bin.svg b/app/Views/_assets/icons/delete-bin.svg new file mode 100644 index 00000000..91a963dd --- /dev/null +++ b/app/Views/_assets/icons/delete-bin.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/icons/upload.svg b/app/Views/_assets/icons/upload.svg new file mode 100644 index 00000000..ad478afc --- /dev/null +++ b/app/Views/_assets/icons/upload.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/_default.svg b/app/Views/_assets/images/platforms/_default.svg new file mode 100644 index 00000000..b7c7127f --- /dev/null +++ b/app/Views/_assets/images/platforms/_default.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/Views/_assets/images/platforms/apple-podcasts.svg b/app/Views/_assets/images/platforms/apple-podcasts.svg new file mode 100644 index 00000000..db1d3e86 --- /dev/null +++ b/app/Views/_assets/images/platforms/apple-podcasts.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/blubrry.svg b/app/Views/_assets/images/platforms/blubrry.svg new file mode 100644 index 00000000..56becf31 --- /dev/null +++ b/app/Views/_assets/images/platforms/blubrry.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/castbox.svg b/app/Views/_assets/images/platforms/castbox.svg new file mode 100644 index 00000000..48543373 --- /dev/null +++ b/app/Views/_assets/images/platforms/castbox.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/castro.svg b/app/Views/_assets/images/platforms/castro.svg new file mode 100644 index 00000000..a1f7c73c --- /dev/null +++ b/app/Views/_assets/images/platforms/castro.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/deezer.svg b/app/Views/_assets/images/platforms/deezer.svg new file mode 100644 index 00000000..4dbfbabf --- /dev/null +++ b/app/Views/_assets/images/platforms/deezer.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/google-podcasts.svg b/app/Views/_assets/images/platforms/google-podcasts.svg new file mode 100644 index 00000000..5903413a --- /dev/null +++ b/app/Views/_assets/images/platforms/google-podcasts.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/ivoox.svg b/app/Views/_assets/images/platforms/ivoox.svg new file mode 100644 index 00000000..36299c87 --- /dev/null +++ b/app/Views/_assets/images/platforms/ivoox.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/Views/_assets/images/platforms/listennotes.svg b/app/Views/_assets/images/platforms/listennotes.svg new file mode 100644 index 00000000..9d01f6bb --- /dev/null +++ b/app/Views/_assets/images/platforms/listennotes.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/overcast.svg b/app/Views/_assets/images/platforms/overcast.svg new file mode 100644 index 00000000..db0bdb49 --- /dev/null +++ b/app/Views/_assets/images/platforms/overcast.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/playerfm.svg b/app/Views/_assets/images/platforms/playerfm.svg new file mode 100644 index 00000000..502b7343 --- /dev/null +++ b/app/Views/_assets/images/platforms/playerfm.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/pocketcasts.svg b/app/Views/_assets/images/platforms/pocketcasts.svg new file mode 100644 index 00000000..7cefa63c --- /dev/null +++ b/app/Views/_assets/images/platforms/pocketcasts.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/podbean.svg b/app/Views/_assets/images/platforms/podbean.svg new file mode 100644 index 00000000..ab371093 --- /dev/null +++ b/app/Views/_assets/images/platforms/podbean.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/podcast-addict.svg b/app/Views/_assets/images/platforms/podcast-addict.svg new file mode 100644 index 00000000..9544f550 --- /dev/null +++ b/app/Views/_assets/images/platforms/podcast-addict.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/podchaser.svg b/app/Views/_assets/images/platforms/podchaser.svg new file mode 100644 index 00000000..b875da9d --- /dev/null +++ b/app/Views/_assets/images/platforms/podchaser.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/Views/_assets/images/platforms/podtail.svg b/app/Views/_assets/images/platforms/podtail.svg new file mode 100644 index 00000000..acbeb47f --- /dev/null +++ b/app/Views/_assets/images/platforms/podtail.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/radiopublic.svg b/app/Views/_assets/images/platforms/radiopublic.svg new file mode 100644 index 00000000..99f072d1 --- /dev/null +++ b/app/Views/_assets/images/platforms/radiopublic.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/Views/_assets/images/platforms/spotify.svg b/app/Views/_assets/images/platforms/spotify.svg new file mode 100644 index 00000000..ed4f435a --- /dev/null +++ b/app/Views/_assets/images/platforms/spotify.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/spreaker.svg b/app/Views/_assets/images/platforms/spreaker.svg new file mode 100644 index 00000000..7cce4d10 --- /dev/null +++ b/app/Views/_assets/images/platforms/spreaker.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Views/_assets/images/platforms/stitcher.svg b/app/Views/_assets/images/platforms/stitcher.svg new file mode 100644 index 00000000..327075ac --- /dev/null +++ b/app/Views/_assets/images/platforms/stitcher.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/app/Views/_assets/images/platforms/tunein.svg b/app/Views/_assets/images/platforms/tunein.svg new file mode 100644 index 00000000..7e0f073c --- /dev/null +++ b/app/Views/_assets/images/platforms/tunein.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/Views/admin/_header.php b/app/Views/admin/_header.php index 6f3605a1..274f52dc 100644 --- a/app/Views/admin/_header.php +++ b/app/Views/admin/_header.php @@ -3,7 +3,7 @@ - + Admin diff --git a/app/Views/admin/_sidenav.php b/app/Views/admin/_sidenav.php index 6fea0a1c..5e0b205e 100644 --- a/app/Views/admin/_sidenav.php +++ b/app/Views/admin/_sidenav.php @@ -3,7 +3,7 @@ $navigation = [ 'dashboard' => ['icon' => 'dashboard', 'items' => ['admin']], 'podcasts' => [ 'icon' => 'mic', - 'items' => ['podcast-list', 'podcast-create'], + 'items' => ['podcast-list', 'podcast-create', 'podcast-import'], ], 'users' => ['icon' => 'group', 'items' => ['user-list', 'user-create']], 'pages' => ['icon' => 'pages', 'items' => ['page-list', 'page-create']], diff --git a/app/Views/admin/podcast/settings/dashboard.php b/app/Views/admin/podcast/settings/dashboard.php new file mode 100644 index 00000000..f7a742fd --- /dev/null +++ b/app/Views/admin/podcast/settings/dashboard.php @@ -0,0 +1,9 @@ +extend('admin/_layout') ?> + +section('title') ?> + +endSection() ?> + +section('content') ?> + +endSection() ?> diff --git a/app/Views/admin/podcast/settings/platforms.php b/app/Views/admin/podcast/settings/platforms.php new file mode 100644 index 00000000..5137eed9 --- /dev/null +++ b/app/Views/admin/podcast/settings/platforms.php @@ -0,0 +1,99 @@ +extend('admin/_layout') ?> + +section('title') ?> + +endSection() ?> + +section('content') ?> + +id), [ + 'class' => 'flex flex-col max-w-md', +]) ?> + + + + +
+
+ icon_filename, 'w-full mb-1') ?> +
+ home_url, icon('external-link', 'mx-auto'), [ + 'class' => 'flex-1 text-gray-600 hover:text-gray-900', + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + 'data-toggle' => 'tooltip', + 'data-placement' => 'bottom', + 'title' => lang('Platforms.home_url', [ + 'platformName' => $platform->label, + ]), + ]) ?> + submit_url + ? anchor($platform->submit_url, icon('upload', 'mx-auto'), [ + 'class' => 'flex-1 text-gray-600 hover:text-gray-900', + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + 'data-toggle' => 'tooltip', + 'data-placement' => 'bottom', + 'title' => lang('Platforms.submit_url', [ + 'platformName' => $platform->label, + ]), + ]) + : '' ?> +
+
+
+ link_url + ? anchor( + route_to('platforms-remove', $podcast->id, $platform->id), + icon('delete-bin', 'mx-auto'), + [ + 'class' => + 'absolute right-0 p-1 bg-red-200 rounded-full text-red-700 hover:text-red-900', + 'data-toggle' => 'tooltip', + 'data-placement' => 'bottom', + 'title' => lang('Platforms.remove', [ + 'platformName' => $platform->label, + ]), + ] + ) + : '' ?> + label, $platform->name, [ + 'class' => 'font-semibold mb-2', + ]) ?> + $platform->name, + 'name' => 'platforms[' . $platform->name . '][url]', + 'class' => 'form-input mb-1 w-full', + 'value' => old($platform->name, $platform->link_url), + 'type' => 'url', + 'placeholder' => 'https://...', + ]) ?> + +
+
+ + + + lang('Platforms.submit'), + 'type' => 'submit', + 'class' => 'self-end px-4 py-2 bg-gray-200', +]) ?> + + + +endSection() ?> diff --git a/app/Views/admin/podcast/view.php b/app/Views/admin/podcast/view.php index 013e22aa..52eea1a5 100644 --- a/app/Views/admin/podcast/view.php +++ b/app/Views/admin/podcast/view.php @@ -23,6 +23,10 @@ 'contributor-list', $podcast->id ) ?>"> +
- Castopod + Castopod
diff --git a/package.json b/package.json index e4d85539..f15cb530 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "watch:css": "postcss app/Views/_assets/styles/index.css -o public/assets/index.css -w", "build:css": "postcss app/Views/_assets/styles/index.css -o public/assets/index.css", "build:icons": "svgo -f app/Views/_assets/icons -o public/assets/icons --config=./.svgo.icons.yml", - "build:svg": "svgo -f app/Views/_assets/images -o public/assets/images --config=./.svgo.yml", + "build:svg": "svgo -f app/Views/_assets/images -o public/assets/images -r --config=./.svgo.yml", "lint": "eslint --ext js,ts app/Views/_assets", "lint:fix": "eslint --ext js,ts app/Views/_assets --fix", "lint:css": "stylelint \"app/Views/_assets/**/*.css\"",