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 164 additions and 106 deletions
import ClientTimezone from "./modules/ClientTimezone";
import DateTimePicker from "./modules/DateTimePicker";
import Dropdown from "./modules/Dropdown"; import Dropdown from "./modules/Dropdown";
import MarkdownEditor from "./modules/MarkdownEditor"; import MarkdownEditor from "./modules/MarkdownEditor";
import MultiSelect from "./modules/MultiSelect"; import MultiSelect from "./modules/MultiSelect";
import SidebarToggler from "./modules/SidebarToggler"; import SidebarToggler from "./modules/SidebarToggler";
import Slugify from "./modules/Slugify"; import Slugify from "./modules/Slugify";
import Time from "./modules/Time";
import Tooltip from "./modules/Tooltip"; import Tooltip from "./modules/Tooltip";
Dropdown(); Dropdown();
...@@ -11,3 +14,6 @@ MarkdownEditor(); ...@@ -11,3 +14,6 @@ MarkdownEditor();
MultiSelect(); MultiSelect();
Slugify(); Slugify();
SidebarToggler(); SidebarToggler();
ClientTimezone();
DateTimePicker();
Time();
...@@ -68,7 +68,10 @@ const drawXYChart = (chartDivId: string, dataUrl: string | null): void => { ...@@ -68,7 +68,10 @@ const drawXYChart = (chartDivId: string, dataUrl: string | null): void => {
chart.scrollbarX = new am4core.Scrollbar(); chart.scrollbarX = new am4core.Scrollbar();
}; };
const drawXYDurationChart = (chartDivId: string, dataUrl: string | null): void => { const drawXYDurationChart = (
chartDivId: string,
dataUrl: string | null
): void => {
// Create chart instance // Create chart instance
const chart = am4core.create(chartDivId, am4charts.XYChart); const chart = am4core.create(chartDivId, am4charts.XYChart);
am4core.percent(100); am4core.percent(100);
...@@ -203,7 +206,10 @@ const DrawCharts = (): void => { ...@@ -203,7 +206,10 @@ const DrawCharts = (): void => {
drawXYChart(chartDiv.id, chartDiv.getAttribute("data-chart-url")); drawXYChart(chartDiv.id, chartDiv.getAttribute("data-chart-url"));
break; break;
case "xy-duration-chart": case "xy-duration-chart":
drawXYDurationChart(chartDiv.id, chartDiv.getAttribute("data-chart-url")); drawXYDurationChart(
chartDiv.id,
chartDiv.getAttribute("data-chart-url")
);
break; break;
case "xy-series-chart": case "xy-series-chart":
drawXYSeriesChart(chartDiv.id, chartDiv.getAttribute("data-chart-url")); drawXYSeriesChart(chartDiv.id, chartDiv.getAttribute("data-chart-url"));
......
const ClientTimezone = (): void => {
const input: HTMLInputElement | null = document.querySelector(
"input[name='client_timezone']"
);
if (input) {
input.value = Intl.DateTimeFormat().resolvedOptions().timeZone;
}
};
export default ClientTimezone;
import flatpickr from "flatpickr";
import "flatpickr/dist/flatpickr.min.css";
/*
* Detects navigator locale 24h time preference
* It works by checking whether hour output contains AM ('1 AM' or '01 h')
*/
const isBrowserLocale24h = () =>
!new Intl.DateTimeFormat(navigator.language, { hour: "numeric" })
.format(0)
.match(/AM/);
const DateTimePicker = (): void => {
const dateTimeContainers: NodeListOf<HTMLInputElement> = document.querySelectorAll(
"input[data-picker='datetime']"
);
for (let i = 0; i < dateTimeContainers.length; i++) {
const dateTimeContainer = dateTimeContainers[i];
const flatpickrInstance = flatpickr(dateTimeContainer, {
enableTime: true,
time_24hr: isBrowserLocale24h(),
});
// convert container UTC date value to user timezone
const dateTime = new Date(dateTimeContainer.value);
const dateUTC = Date.UTC(
dateTime.getFullYear(),
dateTime.getMonth(),
dateTime.getDate(),
dateTime.getHours(),
dateTime.getMinutes()
);
// set converted date as field value
flatpickrInstance.setDate(new Date(dateUTC));
}
};
export default DateTimePicker;
const Time = (): void => {
const timeElements: NodeListOf<HTMLTimeElement> = document.querySelectorAll(
"time"
);
console.log(timeElements);
for (let i = 0; i < timeElements.length; i++) {
const timeElement = timeElements[i];
// convert UTC date value to user timezone
const timeElementDateTime = timeElement.getAttribute("datetime");
// check if timeElementDateTime is not null and not a duration
if (timeElementDateTime && !timeElementDateTime.startsWith("PT")) {
const dateTime = new Date(timeElementDateTime);
// replace <time/> title with localized datetime
timeElement.setAttribute("title", dateTime.toLocaleString());
}
}
};
export default Time;
import Time from "./modules/Time";
Time();
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<div class="container flex flex-wrap items-end justify-between px-2 py-10 mx-auto md:px-12 gap-y-6 gap-x-6"> <div class="container flex flex-wrap items-end justify-between px-2 py-10 mx-auto md:px-12 gap-y-6 gap-x-6">
<div class="flex flex-col"> <div class="flex flex-col">
<?= render_breadcrumb('text-gray-300') ?> <?= render_breadcrumb('text-gray-300') ?>
<h1 class="text-3xl leading-none"><?= $this->renderSection( <h1 class="text-3xl"><?= $this->renderSection(
'pageTitle' 'pageTitle'
) ?></h1> ) ?></h1>
</div> </div>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
'class' => 'flex flex-col', 'class' => 'flex flex-col',
]) ?> ]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_hidden('client_timezone', 'UTC') ?>
<?= form_section( <?= form_section(
lang('Episode.form.info_section_title'), lang('Episode.form.info_section_title'),
...@@ -193,35 +194,19 @@ ...@@ -193,35 +194,19 @@
lang('Episode.form.publication_section_subtitle') lang('Episode.form.publication_section_subtitle')
) ?> ) ?>
<?= form_fieldset('', ['class' => 'flex mb-4']) ?> <?= form_label(
<legend><?= lang('Episode.form.published_at.label') ?></legend> lang('Episode.form.publication_date'),
<div class="flex flex-col flex-1"> 'publication_date',
<?= form_label(lang('Episode.form.publication_date'), 'publication_date', [ [],
'class' => 'sr-only', lang('Episode.form.publication_date_hint')
]) ?> ) ?>
<?= form_input([ <?= form_input([
'id' => 'publication_date', 'id' => 'publication_date',
'name' => 'publication_date', 'name' => 'publication_date',
'class' => 'form-input', 'class' => 'form-input mb-4',
'value' => old('publication_date', date('Y-m-d')), 'value' => old('publication_date', date('Y-m-d H:i')),
'type' => 'date', 'data-picker' => 'datetime',
]) ?> ]) ?>
</div>
<div class="flex flex-col flex-1">
<?= form_label(lang('Episode.form.publication_time'), 'publication_time', [
'class' => 'sr-only',
]) ?>
<?= form_input([
'id' => 'publication_time',
'name' => 'publication_time',
'class' => 'form-input',
'value' => old('publication_time', date('H:i')),
'placeholder' => '--:--',
'type' => 'time',
]) ?>
</div>
<?= form_fieldset_close() ?>
<?= form_fieldset('', ['class' => 'flex mb-6 gap-1']) ?> <?= form_fieldset('', ['class' => 'flex mb-6 gap-1']) ?>
<legend> <legend>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
'class' => 'flex flex-col', 'class' => 'flex flex-col',
]) ?> ]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_hidden('client_timezone', 'UTC') ?>
<?= form_section( <?= form_section(
lang('Episode.form.info_section_title'), lang('Episode.form.info_section_title'),
...@@ -197,44 +198,24 @@ ...@@ -197,44 +198,24 @@
lang('Episode.form.publication_section_subtitle') lang('Episode.form.publication_section_subtitle')
) ?> ) ?>
<?= form_fieldset('', ['class' => 'flex mb-4']) ?> <?= form_label(
<legend><?= lang('Episode.form.published_at.label') ?></legend> lang('Episode.form.publication_date'),
<div class="flex flex-col flex-1"> 'publication_date',
<?= form_label(lang('Episode.form.publication_date'), 'publication_date', [ [],
'class' => 'sr-only', lang('Episode.form.publication_date_hint')
]) ?> ) ?>
<?= form_input([ <?= form_input([
'id' => 'publication_date', 'id' => 'publication_date',
'name' => 'publication_date', 'name' => 'publication_date',
'class' => 'form-input', 'class' => 'form-input mb-4',
'value' => old( 'value' => old(
'publication_date', 'publication_date',
$episode->published_at $episode->published_at
? $episode->published_at->format('Y-m-d') ? $episode->published_at->format('Y-m-d H:i')
: '' : ''
), ),
'type' => 'date', 'data-picker' => 'datetime',
]) ?> ]) ?>
</div>
<div class="flex flex-col flex-1">
<?= form_label(lang('Episode.form.publication_time'), 'publication_time', [
'class' => 'sr-only',
]) ?>
<?= form_input([
'id' => 'publication_time',
'name' => 'publication_time',
'class' => 'form-input',
'value' => old(
'publication_time',
$episode->published_at ? $episode->published_at->format('H:i') : ''
),
'placeholder' => '--:--',
'type' => 'time',
]) ?>
</div>
<?= form_fieldset_close() ?>
<?= form_fieldset('', ['class' => 'mb-6']) ?> <?= form_fieldset('', ['class' => 'mb-6']) ?>
<legend> <legend>
...@@ -288,6 +269,7 @@ ...@@ -288,6 +269,7 @@
<?= form_switch( <?= form_switch(
lang('Episode.form.block') . lang('Episode.form.block') .
hint_tooltip(lang('Episode.form.block_hint'), 'ml-1'), hint_tooltip(lang('Episode.form.block_hint'), 'ml-1'),
['id' => 'block', 'name' => 'block'], ['id' => 'block', 'name' => 'block'],
'yes', 'yes',
old('block', $episode->block) old('block', $episode->block)
......
...@@ -97,19 +97,13 @@ ...@@ -97,19 +97,13 @@
</div> </div>
</div> </div>
<div class="mb-2 text-xs"> <div class="mb-2 text-xs">
<time <?= publication_pill(
pubdate
datetime="<?= $episode->published_at->toDateTimeString() ?>"
title="<?= $episode->published_at ?>">
<?= lang('Common.mediumDate', [
$episode->published_at, $episode->published_at,
]) ?> $episode->is_published
</time> ) ?>
<span class="mx-1"></span> <span class="mx-1"></span>
<time datetime="PT<?= $episode->enclosure_duration ?>S"> <time datetime="PT<?= $episode->enclosure_duration ?>S">
<?= lang('Common.duration', [ <?= format_duration($episode->enclosure_duration) ?>
$episode->enclosure_duration,
]) ?>
</time> </time>
</div> </div>
<audio controls preload="none" class="w-full mt-auto"> <audio controls preload="none" class="w-full mt-auto">
...@@ -126,5 +120,4 @@ ...@@ -126,5 +120,4 @@
<?= $pager->links() ?> <?= $pager->links() ?>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -5,7 +5,12 @@ ...@@ -5,7 +5,12 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('pageTitle') ?> <?= $this->section('pageTitle') ?>
<?= $episode->title ?> <?= $episode->title .
publication_pill(
$episode->published_at,
$episode->is_published,
'text-sm ml-2 align-middle'
) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
......
...@@ -44,5 +44,4 @@ ...@@ -44,5 +44,4 @@
<?= form_close() ?> <?= form_close() ?>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -13,5 +13,4 @@ ...@@ -13,5 +13,4 @@
<?= view('admin/_partials/_user_info.php', ['user' => user()]) ?> <?= view('admin/_partials/_user_info.php', ['user' => user()]) ?>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -238,7 +238,14 @@ ...@@ -238,7 +238,14 @@
'value' => old('publisher'), 'value' => old('publisher'),
]) ?> ]) ?>
<?= form_label(lang('Podcast.form.copyright'), 'copyright', [], '', true) ?> <?= form_label(
lang('Podcast.form.copyright'),
'copyright',
[],
'',
true
) ?>
<?= form_input([ <?= form_input([
'id' => 'copyright', 'id' => 'copyright',
'name' => 'copyright', 'name' => 'copyright',
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
</a> </a>
</header> </header>
<?php if ($episodes): ?> <?php if ($episodes): ?>
<div class="flex justify-between gap-4 overflow-x-auto"> <div class="flex p-2 space-x-4 overflow-x-auto">
<?php foreach ($episodes as $episode): ?> <?php foreach ($episodes as $episode): ?>
<article class="flex flex-col w-56 mb-4 bg-white border rounded shadow" style="min-width: 12rem;"> <article class="flex flex-col w-56 bg-white border rounded shadow" style="min-width: 12rem;">
<img <img
src="<?= $episode->image->thumbnail_url ?>" src="<?= $episode->image->thumbnail_url ?>"
alt="<?= $episode->title ?>" class="object-cover" /> alt="<?= $episode->title ?>" class="object-cover" />
...@@ -61,7 +61,9 @@ ...@@ -61,7 +61,9 @@
<span class="mx-1"></span> <span class="mx-1"></span>
<time <time
pubdate pubdate
datetime="<?= $episode->published_at->toDateTimeString() ?>" datetime="<?= $episode->published_at->format(
DateTime::ATOM
) ?>"
title="<?= $episode->published_at ?>"> title="<?= $episode->published_at ?>">
<?= lang('Common.mediumDate', [ <?= lang('Common.mediumDate', [
$episode->published_at, $episode->published_at,
......
...@@ -62,5 +62,4 @@ ...@@ -62,5 +62,4 @@
<?php endif; ?> <?php endif; ?>
</div> </div>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -50,5 +50,4 @@ ...@@ -50,5 +50,4 @@
<?= form_close() ?> <?= form_close() ?>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -85,5 +85,4 @@ ...@@ -85,5 +85,4 @@
$users $users
) ?> ) ?>
<?= $this->endSection() <?= $this->endSection() ?>
?>
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico" /> <link rel="shortcut icon" type="image/png" href="/favicon.ico" />
<link rel="stylesheet" href="/assets/index.css"/> <link rel="stylesheet" href="/assets/index.css"/>
<script src="/assets/podcast.js" type="module" defer></script>
</head> </head>
<body class="flex flex-col min-h-screen mx-auto"> <body class="flex flex-col min-h-screen mx-auto">
...@@ -85,17 +86,13 @@ ...@@ -85,17 +86,13 @@
<div class="text-sm"> <div class="text-sm">
<time <time
pubdate pubdate
datetime="<?= $episode->published_at->toDateTimeString() ?>" datetime="<?= $episode->published_at->format(DateTime::ATOM) ?>"
title="<?= $episode->published_at ?>"> title="<?= $episode->published_at ?>">
<?= lang('Common.mediumDate', [$episode->published_at]) ?> <?= lang('Common.mediumDate', [$episode->published_at]) ?>
</time> </time>
<span class="mx-1"></span> <span class="mx-1"></span>
<time datetime="PT<?= $episode->enclosure_duration ?>S"> <time datetime="PT<?= $episode->enclosure_duration ?>S">
<?= lang( <?= format_duration($episode->enclosure_duration) ?>
'Common.duration',
[$episode->enclosure_duration],
'en'
) ?>
</time> </time>
</div> </div>
<audio controls preload="none" class="w-full mt-auto"> <audio controls preload="none" class="w-full mt-auto">
...@@ -110,9 +107,9 @@ ...@@ -110,9 +107,9 @@
</section> </section>
</main> </main>
<footer class="px-2 py-4 border-t "> <footer class="px-2 py-4 border-t ">
<div class="container flex flex-col items-center justify-between mx-auto text-sm md:flex-row "> <div class="container flex flex-col items-center justify-between mx-auto text-xs md:flex-row ">
<?= render_page_links('inline-flex mb-4 md:mb-0') ?> <?= render_page_links('inline-flex mb-4 md:mb-0') ?>
<div class="flex flex-col items-end text-xs"> <div class="flex flex-col items-end">
<p><?= $podcast->copyright ?></p> <p><?= $podcast->copyright ?></p>
<p><?= lang('Common.powered_by', [ <p><?= lang('Common.powered_by', [
'castopod' => 'castopod' =>
......
...@@ -20,4 +20,5 @@ Line Number: <?= $exception->getLine() ?> ...@@ -20,4 +20,5 @@ Line Number: <?= $exception->getLine() ?>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif;
?>