Skip to content
Snippets Groups Projects
components_helper.php 11.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * @copyright  2020 Podlibre
     * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
     * @link       https://castopod.org/
     */
    
    use App\Entities\Location;
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('hint_tooltip')) {
    
        /**
         * Hint component
         *
         * Used to produce tooltip with a question mark icon for hint texts
         *
         * @param string $hintText The hint text
         */
        function hint_tooltip(string $hintText = '', string $class = ''): string
        {
            $tooltip =
    
                '<span data-tooltip="bottom" tabindex="0" title="' .
    
                '" class="inline-block align-middle opacity-75 focus:ring-accent';
    
    
            if ($class !== '') {
                $tooltip .= ' ' . $class;
            }
    
            return $tooltip . '">' . icon('question') . '</span>';
        }
    }
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('data_table')) {
    
        /**
         * Data table component
         *
         * Creates a stylized table.
         *
    
         * @param array<array<string, mixed>> $columns array of associate arrays with `header` and `cell` keys where `cell` is a function with a row of $data as parameter
         * @param mixed[] $data data to loop through and display in rows
         * @param mixed ...$rest Any other argument to pass to the `cell` function
    
        function data_table(array $columns, array $data = [], string $class = '', ...$rest): string
    
    
            $template = [
                'table_open' => '<table class="w-full whitespace-no-wrap">',
    
                'thead_open' =>
    
                    '<thead class="text-xs font-semibold text-left uppercase text-skin-muted">',
    
    
                'heading_cell_start' => '<th class="px-4 py-2">',
                'cell_start' => '<td class="px-4 py-2">',
                'cell_alt_start' => '<td class="px-4 py-2">',
    
    
                'row_start' => '<tr class="border-t border-subtle hover:bg-base">',
                'row_alt_start' => '<tr class="border-t border-subtle hover:bg-base">',
    
            ];
    
            $table->setTemplate($template);
    
            $tableHeaders = [];
            foreach ($columns as $column) {
    
            if (($dataCount = count($data)) !== 0) {
                for ($i = 0; $i < $dataCount; ++$i) {
    
                    $row = $data[$i];
                    $rowData = [];
                    foreach ($columns as $column) {
    
                $table->addRow([
                    [
                        'colspan' => count($tableHeaders),
                        'class' => 'px-4 py-2 italic font-semibold text-center',
                        'data' => lang('Common.no_data'),
                    ],
                ]);
    
            return '<div class="overflow-x-auto rounded-lg bg-elevated border-3 border-subtle ' . $class . '" >' .
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('publication_pill')) {
    
         * Shows the stylized publication datetime in regards to current datetime.
    
        function publication_pill(?Time $publicationDate, string $publicationStatus, string $customClass = ''): string
        {
    
                'published' => 'text-pine-500 border-pine-500 bg-pine-50',
    
                'scheduled' => 'text-red-600 border-red-600 bg-red-50',
                'not_published' => 'text-gray-600 border-gray-600 bg-gray-50',
                default => 'text-gray-600 border-gray-600 bg-gray-50',
    
            $label = lang('Episode.publication_status.' . $publicationStatus);
    
            return '<span ' . ($publicationDate === null ? '' : 'title="' . $publicationDate . '"') . ' class="px-1 font-semibold border rounded ' .
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('publication_button')) {
    
         * Displays the appropriate publication button depending on the publication post.
    
        function publication_button(int $podcastId, int $episodeId, string $publicationStatus): string
        {
    
            switch ($publicationStatus) {
                case 'not_published':
                    $label = lang('Episode.publish');
                    $route = route_to('episode-publish', $podcastId, $episodeId);
                    $variant = 'primary';
                    $iconLeft = 'upload-cloud';
                    break;
                case 'scheduled':
                    $label = lang('Episode.publish_edit');
    
                    $route = route_to('episode-publish_edit', $podcastId, $episodeId);
    
                    $iconLeft = 'upload-cloud';
                    break;
                case 'published':
                    $label = lang('Episode.unpublish');
                    $route = route_to('episode-unpublish', $podcastId, $episodeId);
                    $variant = 'danger';
                    $iconLeft = 'cloud-off';
                    break;
    
                default:
                    $label = '';
                    $route = '';
                    $variant = '';
                    $iconLeft = '';
                    break;
    
            return <<<CODE_SAMPLE
                <Button variant="{$variant}" uri="{$route}" iconLeft="{$iconLeft}" >{$label}</Button>
            CODE_SAMPLE;
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('episode_numbering')) {
    
        /**
         * Returns relevant translated episode numbering.
         *
    
         * @param bool $isAbbr component will show abbreviated numbering if true
    
            ?int $episodeNumber = null,
            ?int $seasonNumber = null,
            string $class = '',
    
            if (! $episodeNumber && ! $seasonNumber) {
    
            if ($episodeNumber !== null) {
    
                $args['episodeNumber'] = sprintf('%02d', $episodeNumber);
    
                $args['seasonNumber'] = sprintf('%02d', $seasonNumber);
    
            }
    
            if ($episodeNumber !== null && $seasonNumber !== null) {
    
            } elseif ($episodeNumber !== null && $seasonNumber === null) {
    
            } elseif ($episodeNumber === null && $seasonNumber !== null) {
    
                    lang($transKey . '_abbr', $args) .
                    '</abbr>';
            }
    
            return '<span class="' .
                $class .
                '">' .
                lang($transKey, $args) .
                '</span>';
        }
    }
    
    
    // ------------------------------------------------------------------------
    
    
    if (! function_exists('location_link')) {
    
        /**
         * Returns link to display from location info
         */
    
        function location_link(?Location $location, string $class = ''): string
        {
            if ($location === null) {
    
                $location->url,
                icon('map-pin', 'mr-2') . $location->name,
    
                        'inline-flex items-baseline hover:underline focus:ring-accent' .
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('audio_player')) {
        /**
         * Returns audio player
         */
        function audio_player(string $source, string $mediaType, string $class = ''): string
        {
            $language = service('request')
                ->getLocale();
    
            return <<<CODE_SAMPLE
                <vm-player
                    id="castopod-vm-player"
                    theme="light"
    
                    language="{$language}"
    
                    class="{$class} relative z-0"
                    style="--vm-player-box-shadow:0; --vm-player-theme: hsl(var(--color-accent-base)); --vm-control-focus-color: hsl(var(--color-accent-contrast)); --vm-control-spacing: 4px; --vm-menu-item-focus-bg: hsl(var(--color-background-highlight));"
    
                        <source src="{$source}" type="{$mediaType}" />
    
                    </vm-audio>
                    <vm-ui>
                        <vm-icon-library name="castopod-icons"></vm-icon-library>
                        <vm-controls full-width>
                            <vm-playback-control></vm-playback-control>
                            <vm-volume-control></vm-volume-control>
                            <vm-current-time></vm-current-time>
                            <vm-scrubber-control></vm-scrubber-control>
                            <vm-end-time></vm-end-time>
                            <vm-settings-control></vm-settings-control>
                            <vm-default-settings></vm-default-settings>
                        </vm-controls>
                    </vm-ui>
                </vm-player>
            CODE_SAMPLE;
        }
    }
    
    // ------------------------------------------------------------------------
    
    if (! function_exists('relative_time')) {
        function relative_time(Time $time, string $class = ''): string
        {
    
            $formatter = new IntlDateFormatter(service(
                'request'
            )->getLocale(), IntlDateFormatter::MEDIUM, IntlDateFormatter::NONE);
            $translatedDate = $time->toLocalizedString($formatter->getPattern());
    
            $datetime = $time->format(DateTime::ISO8601);
    
                <time-ago class="{$class}" datetime="{$datetime}">
    
                        datetime="{$datetime}"
                        title="{$time}">{$translatedDate}</time>
    
    
    // ------------------------------------------------------------------------
    
    
    if (! function_exists('explicit_badge')) {
        function explicit_badge(bool $isExplicit, string $class = ''): string
        {
            if (! $isExplicit) {
                return '';
            }
    
            $explicitLabel = lang('Common.explicit');
            return <<<CODE_SAMPLE
                <span class="px-1 text-xs font-semibold leading-tight tracking-wider uppercase border md:border-white/50 {$class}">{$explicitLabel}</span>
            CODE_SAMPLE;
        }
    }
    
    // ------------------------------------------------------------------------
    
    
    
    if (! function_exists('category_label')) {
        function category_label(Category $category): string
        {
            $categoryLabel = '';
            if ($category->parent_id !== null) {
                $categoryLabel .= lang('Podcast.category_options.' . $category->parent->code) . ' › ';
            }
    
            return $categoryLabel . lang('Podcast.category_options.' . $category->code);
        }
    }
    
    // ------------------------------------------------------------------------