diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index 58f80a3a7a258009bde7c4d14da1e05e2521da4d..fc61c0cadafc2fc7b2398eecbfd3ac2168954966 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -514,3 +514,24 @@ if (! function_exists('audio_player')) { CODE_SAMPLE; } } + +// ------------------------------------------------------------------------ + +if (! function_exists('relative_time')) { + function relative_time(Time $time, string $class = ''): string + { + $translatedDate = lang('Common.mediumDate', [$time]); + $datetime = $time->toDateTimeString(); + + return <<<CODE_SAMPLE + <time-ago class="${class}" datetime="${datetime}"> + <time + itemprop="published" + datetime="${datetime}" + title="${time}">${translatedDate}</time> + </time-ago> + CODE_SAMPLE; + } +} + +// ------------------------------------------------------------------------ diff --git a/app/Resources/js/admin.ts b/app/Resources/js/admin.ts index 79f83272161367a9b5ff9139995b35bf47964eaf..9f9522cb3d82b80f6fd6c773ea9ede0b5b5eed43 100644 --- a/app/Resources/js/admin.ts +++ b/app/Resources/js/admin.ts @@ -1,4 +1,5 @@ import "@github/markdown-toolbar-element"; +import "@github/time-elements"; import ClientTimezone from "./modules/ClientTimezone"; import Clipboard from "./modules/Clipboard"; import DateTimePicker from "./modules/DateTimePicker"; diff --git a/app/Resources/js/podcast.ts b/app/Resources/js/podcast.ts index 67235fe7829d31ec8d0f3a9136c9dececd17c0cf..f3036ec29722eb51b69344ec5eeececbb1f3dd64 100644 --- a/app/Resources/js/podcast.ts +++ b/app/Resources/js/podcast.ts @@ -1,3 +1,4 @@ +import "@github/time-elements"; import Dropdown from "./modules/Dropdown"; import Time from "./modules/Time"; import Toggler from "./modules/Toggler"; diff --git a/app/Views/admin/episode/publish_edit.php b/app/Views/admin/episode/publish_edit.php index d71485ddf86a941829e412b1369b2952d2c91640..8d273db3f0665747b4eb03f30c410ec184357b1a 100644 --- a/app/Views/admin/episode/publish_edit.php +++ b/app/Views/admin/episode/publish_edit.php @@ -42,12 +42,7 @@ <span class="text-sm text-gray-500 truncate">@<?= $podcast ->actor->username ?></span> </p> - <time class="text-xs text-gray-500" itemprop="published" datetime="<?= $status->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $status->published_at ?>"><?= lang( - 'Common.mediumDate', - [$status->published_at], - ) ?></time> + <?= relative_time($status->published_at, 'text-xs text-gray-500') ?> </div> </div> <div class="px-4 mb-2"> @@ -78,13 +73,7 @@ ) ?> </div> <div class="text-xs text-gray-600"> - <time itemprop="published" datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> + <?= relative_time($episode->published_at) ?> <span class="mx-1">•</span> <time datetime="PT<?= $episode->audio_file_duration ?>S"> <?= format_duration($episode->audio_file_duration) ?> diff --git a/app/Views/podcast/_partials/episode_card.php b/app/Views/podcast/_partials/episode_card.php index 9da514f0ecd1a91af9d33c99ce5a06d926755dc2..1aff9de6b664e8b8e9766715e7d6cd23a64730c8 100644 --- a/app/Views/podcast/_partials/episode_card.php +++ b/app/Views/podcast/_partials/episode_card.php @@ -21,11 +21,7 @@ <span class="mx-1">-</span> <?= $episode->title ?> </h2> - <time class="text-xs whitespace-nowrap" itemprop="published" datetime="<?= $episode->published_at->format(DateTime::ATOM,) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> + <?= relative_time($episode->published_at, 'text-xs whitespace-nowrap') ?> </a> <div class="flex mt-auto gap-x-4"> <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?> diff --git a/app/Views/podcast/_partials/episode_preview_card.php b/app/Views/podcast/_partials/episode_preview_card.php index 15b5292c043d185cee1d75f7d9dcccc56c829fd4..25650339d231d9bc75de4d1cd695946c82f68e3d 100644 --- a/app/Views/podcast/_partials/episode_preview_card.php +++ b/app/Views/podcast/_partials/episode_preview_card.php @@ -19,13 +19,7 @@ <span class="mx-1">-</span> <?= $episode->title ?> </div> - <time - class="text-xs" - itemprop="published" - datetime="<?= $episode->published_at->format(DateTime::ATOM) ?>" - title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [$episode->published_at]) ?> - </time> + <?= relative_time($episode->published_at, 'text-xs whitespace-nowrap') ?> </a> <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?> </div> diff --git a/app/Views/podcast/_partials/reblog.php b/app/Views/podcast/_partials/reblog.php index bcf979ea74664bd8f2ad4bb3113f5d7d6d1c3507..2abc307e99b62a17b21cc2304b586adbb533cd86 100644 --- a/app/Views/podcast/_partials/reblog.php +++ b/app/Views/podcast/_partials/reblog.php @@ -25,11 +25,7 @@ </a> <a href="<?= route_to('status', $podcast->handle, $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> + <?= relative_time($status->published_at) ?> </a> </div> </header> diff --git a/app/Views/podcast/_partials/reblog_authenticated.php b/app/Views/podcast/_partials/reblog_authenticated.php index a4d12387654693b6d0656ec314f58a16c005488d..11c5d3012e7931ee6b1cbfd83184aa81fccacfb1 100644 --- a/app/Views/podcast/_partials/reblog_authenticated.php +++ b/app/Views/podcast/_partials/reblog_authenticated.php @@ -25,11 +25,7 @@ </a> <a href="<?= route_to('status', $podcast->handle, $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> + <?= relative_time($status->published_at) ?> </a> </div> </header> diff --git a/app/Views/podcast/_partials/reply.php b/app/Views/podcast/_partials/reply.php index 8fb48bf8b2d2faf5c6539d82310fdfee3329eb6f..12977a3608ae68821ce6d8e972f3e1fcba34e71a 100644 --- a/app/Views/podcast/_partials/reply.php +++ b/app/Views/podcast/_partials/reply.php @@ -11,12 +11,7 @@ ->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> + <?= relative_time($status->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?> </header> <p class="mb-2 status-content"><?= $reply->message_html ?></p> <?php if ($reply->has_preview_card): ?> diff --git a/app/Views/podcast/_partials/reply_authenticated.php b/app/Views/podcast/_partials/reply_authenticated.php index ab264ce53d1693adeb2b6d9c287ec6b28b7af998..1d85461cc949be7cec42e70d7922765ee37a58d0 100644 --- a/app/Views/podcast/_partials/reply_authenticated.php +++ b/app/Views/podcast/_partials/reply_authenticated.php @@ -11,12 +11,7 @@ ->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> + <?= relative_time($status->published_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?> </header> <p class="mb-2 status-content"><?= $reply->message_html ?></p> <?php if ($reply->has_preview_card): ?> diff --git a/app/Views/podcast/_partials/status.php b/app/Views/podcast/_partials/status.php index 9d3b0f186ecb7d36185466d4da4e51526ef743b3..21d3d0807ce7399410d6bb66786405d786dc012d 100644 --- a/app/Views/podcast/_partials/status.php +++ b/app/Views/podcast/_partials/status.php @@ -18,11 +18,7 @@ </a> <a href="<?= route_to('status', $podcast->handle, $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> + <?= relative_time($status->published_at) ?> </a> </div> </header> diff --git a/app/Views/podcast/_partials/status_authenticated.php b/app/Views/podcast/_partials/status_authenticated.php index 3a1771c900cb6fe66b865d49920aaa6bf87aa88d..143be143fcc614e91ed46084ffd1cc53263bcd00 100644 --- a/app/Views/podcast/_partials/status_authenticated.php +++ b/app/Views/podcast/_partials/status_authenticated.php @@ -18,11 +18,7 @@ </a> <a href="<?= route_to('status', $podcast->handle, $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> + <?= relative_time($status->published_at) ?> </a> </div> </header> diff --git a/app/Views/podcast/episode.php b/app/Views/podcast/episode.php index 834de56a3418380291c52eab49f05a667d6b9d14..5d7fb5550ef248c235bbd6014c59b5baab53e848 100644 --- a/app/Views/podcast/episode.php +++ b/app/Views/podcast/episode.php @@ -59,13 +59,7 @@ 'text-gray-700', ) ?> <div class="mb-4 text-xs"> - <time pubdate datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> + <?= relative_time($episode->published_at) ?> <span class="mx-1">•</span> <time datetime="PT<?= $episode->audio_file_duration ?>S"> <?= format_duration($episode->audio_file_duration) ?> diff --git a/app/Views/podcast/episode_authenticated.php b/app/Views/podcast/episode_authenticated.php index 695cddd0cf36567595d6178ac9e2c54f8d792ed4..743230cce4258cb9107cf33bb030a2de965f514b 100644 --- a/app/Views/podcast/episode_authenticated.php +++ b/app/Views/podcast/episode_authenticated.php @@ -59,13 +59,7 @@ 'text-gray-700', ) ?> <div class="mb-4 text-xs"> - <time pubdate datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> + <?= relative_time($episode->published_at) ?> <span class="mx-1">•</span> <time datetime="PT<?= $episode->audio_file_duration ?>S"> <?= format_duration($episode->audio_file_duration) ?> diff --git a/package-lock.json b/package-lock.json index 098dd27692248b52a27aec8e730299812165145d..605508c75853537e5d1475925d2169c4354ea46a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@amcharts/amcharts4": "^4.10.20", "@amcharts/amcharts4-geodata": "^4.1.21", "@github/markdown-toolbar-element": "^1.5.1", + "@github/time-elements": "^3.1.2", "@popperjs/core": "^2.9.2", "@vime/core": "^5.0.33", "choices.js": "^9.0.1", @@ -1039,6 +1040,11 @@ "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz", "integrity": "sha512-fNgAuHBWWzqxMvkTMM7ijqPryLmnPVOi4OWp8YyUC74YgtJCRvQyL7gl9SzNLMXmGQxiRVIYbUJxa61X1oRObw==" }, + "node_modules/@github/time-elements": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@github/time-elements/-/time-elements-3.1.2.tgz", + "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", @@ -20246,6 +20252,11 @@ "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz", "integrity": "sha512-fNgAuHBWWzqxMvkTMM7ijqPryLmnPVOi4OWp8YyUC74YgtJCRvQyL7gl9SzNLMXmGQxiRVIYbUJxa61X1oRObw==" }, + "@github/time-elements": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@github/time-elements/-/time-elements-3.1.2.tgz", + "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==" + }, "@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", diff --git a/package.json b/package.json index 077fcc0173c22fb9d1b313c57caf0758b53ba1c6..005821c76719d75867ff6eb36db6dfd3edd279d4 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@amcharts/amcharts4-geodata": "^4.1.21", "@amcharts/amcharts4": "^4.10.20", "@github/markdown-toolbar-element": "^1.5.1", + "@github/time-elements": "^3.1.2", "@popperjs/core": "^2.9.2", "@vime/core": "^5.0.33", "choices.js": "^9.0.1",