Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Select Git revision
Show changes
Showing
with 12 additions and 1040 deletions
<?= helper('page') ?>
<!DOCTYPE html>
<html lang="<?= service('request')->getLocale() ?>">
<head>
<meta charset="UTF-8"/>
<title>Castopod</title>
<meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/assets/index.css"/>
</head>
<body class="flex flex-col min-h-screen mx-auto bg-pine-50">
<header class="py-8 text-white border-b bg-pine-900">
<div class="container flex items-center justify-between px-2 py-4 mx-auto">
<a href="<?= route_to(
'home',
) ?>" class="inline-flex items-baseline text-3xl font-semibold font-display"><?= 'castopod' .
svg('castopod-logo', 'h-6 ml-2') ?></a>
</div>
</header>
<main class="container flex-1 px-4 py-10 mx-auto">
<h1 class="mb-2 text-xl"><?= lang('Home.all_podcasts') ?> (<?= count(
$podcasts,
) ?>)</h1>
<section class="grid gap-4 grid-cols-podcasts">
<?php if ($podcasts): ?>
<?php foreach ($podcasts as $podcast): ?>
<a href="<?= $podcast->link ?>" class="w-full">
<article class="w-full h-full overflow-hidden bg-white border shadow rounded-xl hover:bg-gray-100 hover:shadow">
<img alt="<?= $podcast->title ?>"
src="<?= $podcast->image->medium_url ?>"
class="object-cover w-full h-48 mb-2" />
<h2 class="px-2 font-semibold leading-tight truncate"><?= $podcast->title ?></h2>
<p class="px-2 pb-2 text-gray-600">@<?= $podcast->name ?></p>
</article>
</a>
<?php endforeach; ?>
<?php else: ?>
<p class="italic"><?= lang('Home.no_podcast') ?></p>
<?php endif; ?>
</section>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="underline hover:no-underline" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod</a>',
]) ?></small>
</footer>
</body>
<?= $this->extend('install/_layout') ?>
<?= $this->section('content') ?>
<?= form_open(route_to('cache-config'), [
'class' => 'flex flex-col max-w-sm w-full',
]) ?>
<?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700 font-body">3/4</span><?= lang(
'Install.form.cache_config',
) ?></h1>
<p class="mb-4 text-sm text-gray-600"><?= lang(
'Install.form.cache_config_hint',
) ?></p>
<?= form_label(lang('Install.form.cache_handler'), 'db_prefix') ?>
<?= form_dropdown(
'cache_handler',
[
'file' => lang('Install.form.cacheHandlerOptions.file'),
'redis' => lang('Install.form.cacheHandlerOptions.redis'),
'predis' => lang('Install.form.cacheHandlerOptions.predis'),
],
old('cache_handler', 'file'),
[
'id' => 'cache_handler',
'name' => 'cache_handler',
'class' => 'form-select mb-6',
'value' => config('Database')->default['DBPrefix'],
],
) ?>
<?= button(
lang('Install.form.next') . icon('arrow-right', 'ml-2'),
'',
['variant' => 'primary'],
['type' => 'submit', 'class' => 'self-end'],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?>
<?= $this->extend('install/_layout') ?>
<?= $this->section('content') ?>
<?= form_open(route_to('create-superadmin'), [
'class' => 'flex flex-col max-w-sm w-full',
]) ?>
<?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700 font-body">4/4</span><?= lang(
'Install.form.create_superadmin',
) ?></h1>
<?= form_label(lang('Install.form.email'), 'email') ?>
<?= form_input([
'id' => 'email',
'name' => 'email',
'class' => 'form-input mb-4',
'type' => 'email',
'required' => 'required',
'value' => old('email'),
]) ?>
<?= form_label(lang('Install.form.username'), 'username') ?>
<?= form_input([
'id' => 'username',
'name' => 'username',
'class' => 'form-input mb-4',
'required' => 'required',
'value' => old('username'),
]) ?>
<?= form_label(lang('Install.form.password'), 'password') ?>
<?= form_input([
'id' => 'password',
'name' => 'password',
'class' => 'form-input mb-4',
'type' => 'password',
'required' => 'required',
'autocomplete' => 'new-password',
]) ?>
<?= button(
icon('check', 'mr-2') . lang('Install.form.submit'),
'',
['variant' => 'primary'],
['type' => 'submit', 'class' => 'self-end'],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?>
<?= $this->extend('install/_layout') ?>
<?= $this->section('content') ?>
<?= form_open(route_to('database-config'), [
'class' => 'flex flex-col max-w-sm w-full',
'autocomplete' => 'off',
]) ?>
<?= csrf_field() ?>
<h1 class="mb-2 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700 font-body">2/4</span><?= lang(
'Install.form.database_config',
) ?></h1>
<p class="mb-4 text-sm text-gray-600"><?= lang(
'Install.form.database_config_hint',
) ?></p>
<?= form_label(lang('Install.form.db_hostname'), 'db_hostname') ?>
<?= form_input([
'id' => 'db_hostname',
'name' => 'db_hostname',
'class' => 'form-input mb-4',
'value' => old('db_hostname', config('Database')->default['hostname']),
'required' => 'required',
]) ?>
<?= form_label(lang('Install.form.db_name'), 'db_name') ?>
<?= form_input([
'id' => 'db_name',
'name' => 'db_name',
'class' => 'form-input mb-4',
'value' => old('db_name', config('Database')->default['database']),
'required' => 'required',
]) ?>
<?= form_label(lang('Install.form.db_username'), 'db_username') ?>
<?= form_input([
'id' => 'db_username',
'name' => 'db_username',
'class' => 'form-input mb-4',
'value' => old('db_username', config('Database')->default['username']),
'required' => 'required',
'autocomplete' => 'off',
]) ?>
<?= form_label(lang('Install.form.db_password'), 'db_password') ?>
<?= form_input([
'id' => 'db_password',
'name' => 'db_password',
'class' => 'form-input mb-4',
'value' => old('db_password', config('Database')->default['password']),
'type' => 'password',
'required' => 'required',
'autocomplete' => 'off',
]) ?>
<?= form_label(
lang('Install.form.db_prefix'),
'db_prefix',
[],
lang('Install.form.db_prefix_hint'),
) ?>
<?= form_input([
'id' => 'db_prefix',
'name' => 'db_prefix',
'class' => 'form-input mb-6',
'value' => old('db_prefix', config('Database')->default['DBPrefix']),
]) ?>
<?= button(
lang('Install.form.next') . icon('arrow-right', 'ml-2'),
'',
['variant' => 'primary'],
['type' => 'submit', 'class' => 'self-end'],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?>
<?= $this->extend('install/_layout') ?>
<?= $this->section('content') ?>
<form action="<?= '/' .
config('App')->installGateway .
'/instance-config' ?>" class="flex flex-col w-full max-w-sm" method="post" accept-charset="utf-8">
<?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700 font-body">1/4</span><?= lang(
'Install.form.instance_config',
) ?></h1>
<?= form_label(lang('Install.form.hostname'), 'hostname') ?>
<?= form_input([
'id' => 'hostname',
'name' => 'hostname',
'class' => 'form-input mb-4',
'value' => old(
'hostname',
host_url() === null ? config('App')->baseURL : host_url(),
),
'required' => 'required',
]) ?>
<?= form_label(
lang('Install.form.media_base_url'),
'media_base_url',
[],
lang('Install.form.media_base_url_hint'),
true,
) ?>
<?= form_input([
'id' => 'media_base_url',
'name' => 'media_base_url',
'class' => 'form-input mb-4',
'value' => old('media_base_url', ''),
]) ?>
<?= form_label(
lang('Install.form.admin_gateway'),
'admin_gateway',
[],
lang('Install.form.admin_gateway_hint'),
) ?>
<?= form_input([
'id' => 'admin_gateway',
'name' => 'admin_gateway',
'class' => 'form-input mb-4',
'value' => old('admin_gateway', config('App')->adminGateway),
'required' => 'required',
]) ?>
<?= form_label(
lang('Install.form.auth_gateway'),
'auth_gateway',
[],
lang('Install.form.auth_gateway_hint'),
) ?>
<?= form_input([
'id' => 'auth_gateway',
'name' => 'auth_gateway',
'class' => 'form-input mb-6',
'value' => old('auth_gateway', config('App')->authGateway),
'required' => 'required',
]) ?>
<?= button(
lang('Install.form.next') . icon('arrow-right', 'ml-2'),
'',
['variant' => 'primary'],
['type' => 'submit', 'class' => 'self-end'],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?>
<?= helper('page') ?>
<!DOCTYPE html>
<html lang="<?= service('request')->getLocale() ?>">
<head>
<meta charset="UTF-8"/>
<title><?= $page->title ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/assets/index.css"/>
</head>
<body class="flex flex-col min-h-screen mx-auto">
<header class="py-8 text-white border-b bg-pine-900">
<div class="container flex flex-col px-2 py-4 mx-auto">
<a href="<?= route_to('home') ?>"
class="inline-flex items-center mb-2"><?= icon(
'arrow-left',
'mr-2',
) . lang('Page.back_to_home') ?></a>
<h1 class="text-3xl font-semibold"><?= $page->title ?></h1>
</div>
</header>
<main class="container flex-1 px-4 py-10 mx-auto">
<div class="prose">
<?= $page->content_html ?>
</div>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="underline hover:no-underline" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod</a>',
]) ?></small>
</footer>
</body>
<?php
<?php declare(strict_types=1);
use CodeIgniter\Pager\PagerRenderer;
/**
* @var PagerRenderer $pager
*/
/** @var PagerRenderer $pager */
$pager->setSurroundCount(2);
?>
......@@ -13,15 +11,15 @@ $pager->setSurroundCount(2);
<?php if ($pager->hasPreviousPage()): ?>
<li>
<a href="<?= $pager->getFirst() ?>" aria-label="<?= lang(
'Pager.first',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
'Pager.first',
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.first') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getPreviousPage() ?>" aria-label="<?= lang(
'Pager.previous',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
'Pager.previous',
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang(
'Pager.previous',
) ?></span>
......@@ -32,13 +30,11 @@ $pager->setSurroundCount(2);
<?php foreach ($pager->links() as $link): ?>
<li>
<?php if ($link['active']): ?>
<span class="block px-4 py-2 font-semibold text-white rounded-full bg-pine-600">
<span class="block px-4 py-2 font-semibold rounded-full text-accent-contrast bg-accent-base">
<?= $link['title'] ?>
</span>
<?php else: ?>
<a href="<?= $link[
'uri'
] ?>" class="block px-4 py-2 text-gray-700 rounded-full hover:bg-gray-200 hover:text-black">
<a href="<?= $link['uri'] ?>" class="block px-4 py-2 rounded-full text-skin-muted hover:bg-highlight">
<?= $link['title'] ?>
</a>
<?php endif; ?>
......@@ -48,15 +44,15 @@ $pager->setSurroundCount(2);
<?php if ($pager->hasNextPage()): ?>
<li>
<a href="<?= $pager->getNextPage() ?>" aria-label="<?= lang(
'Pager.next',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
'Pager.next',
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.next') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getLast() ?>" aria-label="<?= lang(
'Pager.last',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
'Pager.last',
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.last') ?></span>
</a>
</li>
......
<?= helper('page') ?>
<!DOCTYPE html>
<html lang="<?= service('request')->getLocale() ?>">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
<?= $this->renderSection('meta-tags') ?>
<?php if ($podcast->payment_pointer): ?>
<meta name="monetization" content="<?= $podcast->payment_pointer ?>" />
<?php endif; ?>
<link rel="stylesheet" href="/assets/index.css"/>
<script src="/assets/podcast.js" type="module"></script>
</head>
<body class="flex w-full min-h-screen pb-20 overflow-x-hidden lg:mx-auto lg:container bg-pine-50 sm:pb-0">
<?= $this->include('podcast/_partials/header') ?>
<main class="flex-shrink-0 w-full min-w-0 sm:w-auto sm:flex-1 sm:flex-shrink">
<?= $this->renderSection('content') ?>
</main>
<?= $this->include('podcast/_partials/sidebar') ?>
<nav class="fixed bottom-0 left-0 z-50 flex items-center w-full px-4 py-4 sm:hidden">
<div class="flex items-center w-full p-2 rounded-full shadow-2xl bg-pine-900">
<button
data-toggle="main-header"
data-toggle-class="sticky -translate-x-full"
class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50">
<img src="<?= $podcast->image
->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-14"/>
</button>
<p class="flex flex-col flex-1 min-w-0 mr-2 text-white">
<span class="text-sm font-semibold truncate"><?= $podcast->title ?></span>
<span class="text-xs">@<?= $podcast->name ?></span>
</p>
<?= anchor_popup(
route_to('follow', $podcast->name),
icon(
'social/castopod',
'mr-2 text-xl text-pink-200 group-hover:text-pink-50',
) . lang('Podcast.follow'),
[
'width' => 420,
'height' => 620,
'class' =>
'group inline-flex items-center px-4 py-2 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600',
],
) ?>
<button
data-toggle="main-sidebar"
data-toggle-class="translate-x-full"
data-toggle-body-class="-ml-64"
class="p-4 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon(
'menu',
) ?><span class="sr-only"><?= lang(
'Podcast.toggle_podcast_sidebar',
) ?></span></button>
</div>
</nav>
<button
data-toggle="main-sidebar"
data-toggle-class="translate-x-full"
data-toggle-body-class="-ml-64"
class="fixed z-40 hidden p-4 text-xl rounded-full shadow-2xl sm:block lg:hidden bottom-4 left-4 bg-pine-900 focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon(
'menu',
) ?><span class="sr-only"><?= lang(
'Podcast.toggle_podcast_sidebar',
) ?></span></button>
<!-- Funding links modal -->
<div id="funding-links" class="fixed top-0 left-0 z-50 flex items-center justify-center hidden w-screen h-screen">
<div
class="absolute w-full h-full bg-pine-900 bg-opacity-90"
role="button"
data-toggle="funding-links"
data-toggle-class="hidden"
aria-label="<?= lang('Common.close') ?>"></div>
<div class="z-10 w-full max-w-xl bg-white rounded-lg shadow-2xl">
<div class="flex justify-between px-4 py-2 border-b">
<h3 class="self-center text-lg"><?= lang(
'Podcast.funding_links',
['podcastTitle' => $podcast->title],
) ?></h3>
<button
data-toggle="funding-links"
data-toggle-class="hidden"
aria-label="<?= lang('Common.close') ?>"
class="self-start p-1 text-2xl"><?= icon('close') ?></button>
</div>
<div class="flex flex-col items-start p-4 space-y-4">
<?php foreach (
$podcast->fundingPlatforms
as $fundingPlatform
): ?>
<?php if ($fundingPlatform->is_visible): ?>
<a
href="<?= $fundingPlatform->link_url ?>"
title="<?= $fundingPlatform->link_content ?>"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center font-semibold text-pine-900">
<?= icon(
$fundingPlatform->type .
'/' .
$fundingPlatform->slug,
'mr-2',
) . $fundingPlatform->link_url ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
</body>
<?= helper('page') ?>
<!DOCTYPE html>
<html lang="<?= service('request')->getLocale() ?>">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
<?= $this->renderSection('meta-tags') ?>
<?php if ($podcast->payment_pointer): ?>
<meta name="monetization" content="<?= $podcast->payment_pointer ?>" />
<?php endif; ?>
<link rel="stylesheet" href="/assets/index.css" />
<script src="/assets/podcast.js" type="module"></script>
</head>
<body class="flex w-full min-h-screen pt-12 pb-20 overflow-x-hidden bg-pine-50 lg:mx-auto lg:container sm:pb-0">
<div class="fixed top-0 left-0 z-50 flex items-center justify-between w-full h-12 px-4 text-white shadow bg-pine-900">
<?= anchor(
route_to('admin'),
'castopod' . svg('castopod-logo', 'h-5 ml-1'),
[
'class' =>
'text-2xl inline-flex items-baseline font-bold font-display',
],
) ?>
<?php if (user()->podcasts !== []): ?>
<button type="button" class="inline-flex items-center px-6 py-2 mt-auto font-semibold outline-none focus:ring" id="interact-as-dropdown" data-dropdown="button" data-dropdown-target="interact-as-dropdown-menu" aria-haspopup="true" aria-expanded="false">
<img src="<?= interact_as_actor()
->avatar_image_url ?>" class="w-8 h-8 mr-2 rounded-full" />
<?= '@' . interact_as_actor()->username ?>
<?= icon('caret-down', 'ml-auto') ?>
</button>
<nav id="interact-as-dropdown-menu" class="absolute z-50 flex flex-col py-2 text-black whitespace-no-wrap bg-white border rounded shadow" aria-labelledby="my-accountDropdown" data-dropdown="menu" data-dropdown-placement="bottom-end">
<span class="px-4 text-xs tracking-wider text-gray-700 uppercase"><?= lang(
'Admin.choose_interact',
) ?></span>
<form action="<?= route_to(
'interact-as-actor',
) ?>" method="POST" class="flex flex-col">
<?= csrf_field() ?>
<?php foreach (user()->podcasts as $userPodcast): ?>
<button class="inline-flex items-center w-full px-4 py-1 hover:bg-gray-100" id="<?= "interact-as-actor-{$userPodcast->id}" ?>" name="actor_id" value="<?= $userPodcast->actor_id ?>">
<span class="inline-flex items-center flex-1">
<img src="<?= $userPodcast->image
->thumbnail_url ?>" class="w-8 h-8 mr-2 rounded-full" /><?= $userPodcast->title ?>
<?php if (
interact_as_actor()->id ===
$userPodcast->actor_id
): ?>
</span>
<?= icon(
'check',
'ml-4 bg-pine-900 text-white rounded-full',
) ?>
<?php endif; ?>
</button>
<?php endforeach; ?>
</form>
</nav>
<?php endif; ?>
</div>
<?= $this->include('podcast/_partials/header') ?>
<main class="flex-shrink-0 w-full min-w-0 sm:w-auto sm:flex-1 sm:flex-shrink">
<?= $this->renderSection('content') ?>
</main>
<?= $this->include('podcast/_partials/sidebar') ?>
<nav class="fixed bottom-0 left-0 z-50 flex items-center w-full px-4 py-4 sm:hidden">
<div class="flex items-center w-full p-2 rounded-full shadow-2xl bg-pine-900">
<button data-toggle="main-header" data-toggle-class="sticky -translate-x-full" class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50">
<img src="<?= $podcast->image
->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-14" />
</button>
<p class="flex flex-col flex-1 min-w-0 mr-2 text-white">
<span class="text-sm font-semibold truncate"><?= $podcast->title ?></span>
<span class="text-xs">@<?= $podcast->name ?></span>
</p>
<?= anchor_popup(
route_to('follow', $podcast->name),
icon(
'social/castopod',
'mr-2 text-xl text-pink-200 group-hover:text-pink-50',
) . lang('Podcast.follow'),
[
'width' => 420,
'height' => 620,
'class' =>
'group inline-flex items-center px-4 py-2 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600',
],
) ?>
<button data-toggle="main-sidebar" data-toggle-class="translate-x-full" data-toggle-body-class="-ml-64" class="p-4 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon(
'menu',
) ?><span class="sr-only"><?= lang(
'Podcast.toggle_podcast_sidebar',
) ?></span></button>
</div>
</nav>
<button data-toggle="main-sidebar" data-toggle-class="translate-x-full" data-toggle-body-class="-ml-64" class="fixed z-40 hidden p-4 text-xl rounded-full shadow-2xl sm:block lg:hidden bottom-4 left-4 bg-pine-900 focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon(
'menu',
) ?><span class="sr-only"><?= lang(
'Podcast.toggle_podcast_sidebar',
) ?></span></button>
<!-- Funding links modal -->
<div id="funding-links" class="fixed top-0 left-0 z-50 flex items-center justify-center hidden w-screen h-screen">
<div class="absolute w-full h-full bg-pine-900 bg-opacity-90" role="button" data-toggle="funding-links" data-toggle-class="hidden" aria-label="<?= lang(
'Common.close',
) ?>"></div>
<div class="z-10 w-full max-w-xl bg-white rounded-lg shadow-2xl">
<div class="flex justify-between px-4 py-2 border-b">
<h3 class="self-center text-lg"><?= lang(
'Podcast.funding_links',
['podcastTitle' => $podcast->title],
) ?></h3>
<button data-toggle="funding-links" data-toggle-class="hidden" aria-label="<?= lang(
'Common.close',
) ?>" class="self-start p-1 text-2xl">
<?= icon('close') ?>
</button>
</div>
<div class="flex flex-col items-start p-4 space-y-4">
<?php foreach (
$podcast->fundingPlatforms
as $fundingPlatform
): ?>
<?php if ($fundingPlatform->is_visible): ?>
<a href="<?= $fundingPlatform->link_url ?>" title="<?= $fundingPlatform->link_content ?>" target="_blank" rel="noopener noreferrer" class="inline-flex items-center font-semibold text-pine-900">
<?= icon(
$fundingPlatform->type .
'/' .
$fundingPlatform->slug,
'text-2xl text-gray-400 mr-2',
) . $fundingPlatform->link_url ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
</body>
<div class="flex">
<img
src="<?= $episode->image->thumbnail_url ?>"
alt="<?= $episode->title ?>" class="w-24 h-24"/>
<div class="flex flex-col flex-1">
<a href="<?= $episode->link ?>" class="flex-1 px-4 py-2 bg-gray-100">
<div class="flex items-baseline">
<span class="flex-1 w-0 mr-2 font-semibold leading-none truncate"><?= $episode->title ?></span>
<?= episode_numbering(
$episode->number,
$episode->season_number,
'text-xs font-semibold text-gray-600',
true,
) ?>
</div>
<div class="text-xs text-gray-800">
<time
itemprop="published"
datetime="<?= $episode->published_at->format(DateTime::ATOM) ?>"
title="<?= $episode->published_at ?>">
<?= lang('Common.mediumDate', [$episode->published_at]) ?>
</time>
<span class="mx-1"></span>
<time datetime="PT<?= $episode->audio_file_duration ?>S">
<?= format_duration($episode->audio_file_duration) ?>
</time>
</div>
</a>
<audio controls preload="none" class="w-full mt-auto">
<source
src="<?= $episode->audio_file_web_url ?>"
type="<?= $episode->audio_file_mimetype ?>">
Your browser does not support the audio tag.
</audio>
</div>
</div>
<header id="main-header" class="fixed top-0 left-0 flex-col flex-shrink-0 h-screen transform -translate-x-full sm:left-auto sm:-translate-x-0 sm:sticky w-80 sm:w-64 lg:w-80 xl:w-112 sm:flex">
<img src="<?= $podcast->actor
->cover_image_url ?>" alt="" class="object-cover w-full h-48 bg-pine-900"/>
<div class="flex items-center justify-between px-4 py-2 mb-4 lg:px-6 -mt-14 lg:-mt-16 xl:-mt-20">
<img src="<?= $podcast->image
->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-24 rounded-full shadow-xl xl:h-36 lg:h-28 ring-4 ring-pine-50" />
<?= anchor_popup(
route_to('follow', $podcast->name),
icon(
'social/castopod',
'mr-2 text-xl text-pink-200 group-hover:text-pink-50',
) . lang('Podcast.follow'),
[
'width' => 420,
'height' => 620,
'class' =>
'group inline-flex items-center px-4 py-2 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600',
],
) ?>
</div>
<div class="px-6">
<h1 class="inline-flex items-center text-2xl font-bold leading-none font-display"><?= $podcast->title .
($podcast->parental_advisory === 'explicit'
? '<span class="px-1 ml-2 text-xs font-semibold leading-tight tracking-wider text-gray-600 uppercase border-2 border-gray-500">' .
lang('Common.explicit') .
'</span>'
: '') ?></h1>
<p class="mb-4 font-semibold text-gray-600">@<?= $podcast->name ?></p>
<div class="mb-2"><?= $podcast->description_html ?></div>
<?= location_link($podcast->location, 'text-sm mb-4') ?>
<div class="mb-6 space-x-4">
<span class="px-2 py-1 text-sm text-gray-800 bg-gray-200">
<?= lang(
'Podcast.category_options.' . $podcast->category->code,
) ?>
</span>
<?php foreach ($podcast->other_categories as $other_category): ?>
<span class="px-2 py-1 text-sm text-gray-800 bg-gray-200">
<?= lang(
'Podcast.category_options.' . $other_category->code,
) ?>
</span>
<?php endforeach; ?>
</div>
<?= person_list($podcast->persons, 'mb-6') ?>
<div class="space-x-4">
<a href="#" class="hover:underline"><?= lang('Podcast.followers', [
'numberOfFollowers' => $podcast->actor->followers_count,
]) ?></a>
<a href="<?= route_to(
'podcast-activity',
$podcast->name,
) ?>" class="hover:underline"><?= lang('Podcast.statuses', [
'numberOfStatuses' => $podcast->actor->statuses_count,
]) ?></a>
</div>
</div>
</header>
<?php if ($preview_card->type === 'image'): ?>
<a href="<?= $preview_card->url ?>" class="flex flex-col bg-gray-100" target="_blank" rel="noopener noreferrer">
<?php if ($preview_card->image): ?>
<div class="relative group">
<?= icon(
'external-link',
'absolute inset-0 m-auto text-6xl bg-pine-800 ring-4 ring-white bg-opacity-50 group-hover:bg-opacity-75 text-white rounded-full p-2',
) ?>
<img src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" class="object-cover w-full h-80" />
</div>
<?php endif; ?>
<div class="flex flex-col flex-1 px-4 py-2">
<span class="text-xs tracking-wider text-gray-600 uppercase"><?= $preview_card->provider_name ?></span>
</div>
</a>
<?php elseif ($preview_card->type === 'video'): ?>
<a href="<?= $preview_card->url ?>" class="flex flex-col bg-gray-100" target="_blank" rel="noopener noreferrer">
<?php if ($preview_card->image): ?>
<div class="relative group">
<?= icon(
'play',
'absolute inset-0 m-auto text-6xl bg-pine-800 ring-4 ring-white bg-opacity-50 group-hover:bg-opacity-75 text-white rounded-full p-2',
) ?>
<img class="object-cover w-full h-80" src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" />
</div>
<?php endif; ?>
<div class="flex flex-col flex-1 px-4 py-2">
<span class="text-xs tracking-wider text-gray-600 uppercase"><?= $preview_card->provider_name ?></span>
<span class="mb-2 font-semibold truncate"><?= $preview_card->title ?></span>
</div>
</a>
<?php else: ?>
<a href="<?= $preview_card->url ?>" class="flex items-center bg-gray-100">
<?php if ($preview_card->image): ?>
<img src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" class="object-cover w-20 h-20" />
<?php endif; ?>
<p class="flex flex-col flex-1 px-4 py-2">
<span class="text-xs tracking-wider text-gray-600 uppercase"><?= $preview_card->provider_name ?></span>
<span class="mb-2 font-semibold truncate"><?= $preview_card->title ?></span>
</p>
</a>
<?php endif;
?>
<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
<p class="inline-flex px-6 pt-4 text-xs text-gray-700"><?= icon(
'repeat',
'text-lg mr-2 text-gray-400',
) .
lang('Status.actor_shared', [
'actor' => $status->actor->display_name,
]) ?></p>
<header class="flex px-6 py-4">
<img src="<?= $status->actor
->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
<div class="flex flex-col min-w-0">
<a href="<?= $status->actor
->uri ?>" class="flex items-baseline hover:underline" <?= $status
->actor->is_local
? ''
: 'target="_blank" rel="noopener noreferrer"' ?>>
<span class="mr-2 font-semibold truncate"><?= $status->actor
->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $status->actor
->username .
($status->actor->is_local
? ''
: '@' . $status->actor->domain) ?></span>
</a>
<a href="<?= route_to('status', $podcast->name, $status->id) ?>"
class="text-xs text-gray-500">
<time
itemprop="published"
datetime="<?= $status->published_at->format(DateTime::ATOM) ?>"
title="<?= $status->published_at ?>"
><?= lang('Common.mediumDate', [$status->published_at]) ?></time>
</a>
</div>
</header>
<div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
<?php if ($status->episode_id): ?>
<?= view('podcast/_partials/episode_card', [
'episode' => $status->episode,
]) ?>
<?php elseif ($status->has_preview_card): ?>
<?= view('podcast/_partials/preview_card', [
'preview_card' => $status->preview_card,
]) ?>
<?php endif; ?>
<?= $this->include('podcast/_partials/status_actions') ?>
</article>
<article class="relative z-10 w-full bg-white shadow-md rounded-2xl">
<p class="inline-flex px-6 pt-4 text-xs text-gray-700"><?= icon(
'repeat',
'text-lg mr-2 text-gray-400',
) .
lang('Status.actor_shared', [
'actor' => $status->actor->display_name,
]) ?></p>
<header class="flex px-6 py-4">
<img src="<?= $status->actor
->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
<div class="flex flex-col min-w-0">
<a href="<?= $status->actor
->uri ?>" class="flex items-baseline hover:underline" <?= $status
->actor->is_local
? ''
: 'target="_blank" rel="noopener noreferrer"' ?>>
<span class="mr-2 font-semibold truncate"><?= $status->actor
->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $status->actor
->username .
($status->actor->is_local
? ''
: '@' . $status->actor->domain) ?></span>
</a>
<a href="<?= route_to('status', $podcast->name, $status->id) ?>"
class="text-xs text-gray-500">
<time
itemprop="published"
datetime="<?= $status->published_at->format(DateTime::ATOM) ?>"
title="<?= $status->published_at ?>"
><?= lang('Common.mediumDate', [$status->published_at]) ?></time>
</a>
</div>
</header>
<div class="px-6 mb-4 status-content"><?= $status->message_html ?></div>
<?php if ($status->episode_id): ?>
<?= view('podcast/_partials/episode_card', [
'episode' => $status->episode,
]) ?>
<?php elseif ($status->has_preview_card): ?>
<?= view('podcast/_partials/preview_card', [
'preview_card' => $status->preview_card,
]) ?>
<?php endif; ?>
<?= $this->include('podcast/_partials/status_actions_authenticated') ?>
</article>
<article class="flex px-6 py-4 bg-gray-50">
<img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor
->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" />
<div class="flex flex-col flex-1 min-w-0">
<header class="flex items-center mb-2">
<a href="<?= $reply->actor
->uri ?>" class="mr-2 text-base font-semibold truncate hover:underline" <?= $reply
->actor->is_local
? ''
: 'target="_blank" rel="noopener noreferrer"' ?>><?= $reply->actor
->display_name ?><span class="ml-1 text-sm font-normal text-gray-600">@<?= $reply
->actor->username .
($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
<time
class="flex-shrink-0 ml-auto text-xs text-gray-600"
itemprop="published"
datetime="<?= $reply->published_at->format(DateTime::ATOM) ?>"
title="<?= $reply->published_at ?>"
><?= lang('Common.mediumDate', [$reply->published_at]) ?></time>
</header>
<p class="mb-2 status-content"><?= $reply->message_html ?></p>
<?php if ($reply->has_preview_card): ?>
<?= view('podcast/_partials/preview_card', [
'preview_card' => $reply->preview_card,
]) ?>
<?php endif; ?>
<?= $this->include('podcast/_partials/reply_actions') ?>
</div>
</article>
<footer class="mt-2 space-x-6 text-sm">
<?= anchor(
route_to('status', $podcast->name, $reply->id),
icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count,
[
'class' => 'inline-flex items-center hover:underline',
'title' => lang('Status.replies', [
'numberOfReplies' => $reply->replies_count,
]),
],
) ?>
<?= anchor_popup(
route_to('status-remote-action', $podcast->name, $reply->id, 'reblog'),
icon('repeat', 'text-xl mr-1 text-gray-400') . $reply->reblogs_count,
[
'class' => 'inline-flex items-center hover:underline',
'width' => 420,
'height' => 620,
'title' => lang('Status.reblogs', [
'numberOfReblogs' => $reply->reblogs_count,
]),
],
) ?>
<?= anchor_popup(
route_to('status-remote-action', $podcast->name, $reply->id, 'favourite'),
icon('heart', 'text-xl mr-1 text-gray-400') . $reply->favourites_count,
[
'class' => 'inline-flex items-center hover:underline',
'width' => 420,
'height' => 620,
'title' => lang('Status.favourites', [
'numberOfFavourites' => $reply->favourites_count,
]),
],
) ?>
</footer>
<footer class="mt-2 text-sm">
<form action="<?= route_to(
'status-attempt-action',
interact_as_actor()->username,
$reply->id,
) ?>" method="POST" class="flex items-start">
<?= csrf_field() ?>
<?= anchor(
route_to('status', $podcast->name, $reply->id),
icon('chat', 'text-xl mr-1 text-gray-400') . $reply->replies_count,
[
'class' => 'inline-flex items-center mr-6 hover:underline',
'title' => lang('Status.replies', [
'numberOfReplies' => $reply->replies_count,
]),
],
) ?>
<button type="submit" name="action" value="reblog" class="inline-flex items-center mr-6 hover:underline" title="<?= lang(
'Status.reblogs',
[
'numberOfReblogs' => $reply->reblogs_count,
],
) ?>"><?= icon('repeat', 'text-xl mr-1 text-gray-400') .
$reply->reblogs_count ?></button>
<button type="submit" name="action" value="favourite" class="inline-flex items-center mr-6 hover:underline" title="<?= lang(
'Status.favourites',
[
'numberOfFavourites' => $reply->favourites_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400') .
$reply->favourites_count ?></button>
<button id="<?= $reply->id .
'-more-dropdown' ?>" type="button" class="text-xl text-gray-500 outline-none focus:ring" data-dropdown="button" data-dropdown-target="<?= $reply->id .
'-more-dropdown-menu' ?>" aria-label="<?= lang(
'Common.more',
) ?>" aria-haspopup="true" aria-expanded="false"><?= icon('more') ?>
</button>
</form>
<nav id="<?= $reply->id .
'-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm bg-white border rounded-lg shadow" aria-labelledby="<?= $reply->id .
'-more-dropdown' ?>" data-dropdown="menu" data-dropdown-placement="bottom">
<?= anchor(
route_to('status', $podcast->name, $reply->id),
lang('Status.expand'),
[
'class' => 'px-4 py-1 hover:bg-gray-100',
],
) ?>
<form action="<?= route_to(
'status-attempt-block-actor',
interact_as_actor()->username,
$reply->id,
) ?>" method="POST">
<?= csrf_field() ?>
<button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
'Status.block_actor',
[
'actorUsername' => $reply->actor->username,
],
) ?></button>
</form>
<form action="<?= route_to(
'status-attempt-block-domain',
interact_as_actor()->username,
$reply->id,
) ?>" method="POST">
<?= csrf_field() ?>
<button class="w-full px-4 py-1 text-left hover:bg-gray-100"><?= lang(
'Status.block_domain',
[
'actorDomain' => $reply->actor->domain,
],
) ?></button>
</form>
<?php if ($reply->actor->is_local): ?>
<hr class="my-2" />
<form action="<?= route_to(
'status-attempt-delete',
$reply->actor->username,
$reply->id,
) ?>" method="POST">
<?= csrf_field() ?>
<button class="w-full px-4 py-1 font-semibold text-left text-red-600 hover:bg-gray-100"><?= lang(
'Status.delete',
) ?></button>
</form>
<?php endif; ?>
</nav>
</footer>
<article class="flex px-6 py-4 bg-gray-50">
<img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor
->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" />
<div class="flex flex-col flex-1 min-w-0">
<header class="flex items-center mb-2">
<a href="<?= $reply->actor
->uri ?>" class="mr-2 text-base font-semibold truncate hover:underline" <?= $reply
->actor->is_local
? ''
: 'target="_blank" rel="noopener noreferrer"' ?>><?= $reply->actor
->display_name ?><span class="ml-1 text-sm font-normal text-gray-600">@<?= $reply
->actor->username .
($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
<time
class="flex-shrink-0 ml-auto text-xs text-gray-600"
itemprop="published"
datetime="<?= $reply->published_at->format(DateTime::ATOM) ?>"
title="<?= $reply->published_at ?>"
><?= lang('Common.mediumDate', [$reply->published_at]) ?></time>
</header>
<p class="mb-2 status-content"><?= $reply->message_html ?></p>
<?php if ($reply->has_preview_card): ?>
<?= view('podcast/_partials/preview_card', [
'preview_card' => $reply->preview_card,
]) ?>
<?php endif; ?>
<?= $this->include('podcast/_partials/reply_actions_authenticated') ?>
</div>
</article>