FreeTube/src/renderer/views/Channel/Channel.vue

427 lines
15 KiB
Vue

<template>
<div
ref="search"
>
<ft-loader
v-if="isLoading && !errorMessage"
:fullscreen="true"
/>
<ft-card
v-else-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
class="card channelDetails"
>
<div
class="channelBannerContainer"
:class="{
default: !bannerUrl
}"
:style="{ '--banner-url': `url('${bannerUrl}')` }"
/>
<div
class="channelInfoContainer"
>
<div
class="channelInfo"
:class="{ channelInfoHasError: errorMessage }"
>
<div
class="thumbnailContainer"
>
<img
v-if="thumbnailUrl"
class="channelThumbnail"
:src="thumbnailUrl"
alt=""
>
<font-awesome-icon
v-else
class="channelThumbnail"
:icon="['fas', 'circle-user']"
/>
<div
class="channelLineContainer"
>
<h1
class="channelName"
>
{{ channelName }}
</h1>
<p
v-if="subCount !== null && !hideChannelSubscriptions"
class="channelSubCount"
>
{{ $tc('Global.Counts.Subscriber Count', subCount, { count: formattedSubCount }) }}
</p>
</div>
</div>
<div class="channelInfoActionsContainer">
<ft-share-button
v-if="!hideSharingActions && showShareMenu"
:id="id"
share-target-type="Channel"
class="shareIcon"
/>
<ft-subscribe-button
v-if="!hideUnsubscribeButton && (!errorMessage || isSubscribed)"
:channel-id="id"
:channel-name="channelName"
:channel-thumbnail="thumbnailUrl"
/>
</div>
</div>
<ft-flex-box
v-if="!errorMessage"
class="channelInfoTabs"
>
<div
class="tabs"
role="tablist"
:aria-label="$t('Channel.Channel Tabs')"
>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('videos')"
id="videosTab"
class="tab"
:class="(currentTab==='videos')?'selectedTab':''"
role="tab"
:aria-selected="String(currentTab === 'videos')"
aria-controls="videoPanel"
:tabindex="(currentTab === 'videos' || currentTab === 'search') ? 0 : -1"
@click="changeTab('videos')"
@keydown.left.right.enter.space="changeTab('videos', $event)"
>
{{ $t("Channel.Videos.Videos").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('shorts') && !hideChannelShorts"
id="shortsTab"
class="tab"
:class="(currentTab==='shorts')?'selectedTab':''"
role="tab"
:aria-selected="String(currentTab === 'shorts')"
aria-controls="shortPanel"
:tabindex="currentTab === 'shorts' ? 0 : -1"
@click="changeTab('shorts')"
@keydown.left.right.enter.space="changeTab('shorts', $event)"
>
{{ $t("Global.Shorts").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('live') && !hideLiveStreams"
id="liveTab"
class="tab"
:class="(currentTab==='live')?'selectedTab':''"
role="tab"
:aria-selected="String(currentTab === 'live')"
aria-controls="livePanel"
:tabindex="currentTab === 'live' ? 0 : -1"
@click="changeTab('live')"
@keydown.left.right.enter.space="changeTab('live', $event)"
>
{{ $t("Channel.Live.Live").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('releases') && !hideChannelReleases"
id="releasesTab"
class="tab"
role="tab"
:aria-selected="String(currentTab === 'releases')"
aria-controls="releasePanel"
:tabindex="currentTab === 'releases' ? 0 : -1"
:class="(currentTab==='releases')?'selectedTab':''"
@click="changeTab('releases')"
@keydown.left.right.enter.space="changeTab('releases', $event)"
>
{{ $t("Channel.Releases.Releases").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('podcasts') && !hideChannelPodcasts"
id="podcastsTab"
class="tab"
role="tab"
:aria-selected="String(currentTab === 'podcasts')"
aria-controls="podcastPanel"
:tabindex="currentTab === 'podcasts' ? 0 : -1"
:class="(currentTab==='podcasts')?'selectedTab':''"
@click="changeTab('podcasts')"
@keydown.left.right.enter.space="changeTab('podcasts', $event)"
>
{{ $t("Channel.Podcasts.Podcasts").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('playlists') && !hideChannelPlaylists"
id="playlistsTab"
class="tab"
role="tab"
:aria-selected="String(currentTab === 'playlists')"
aria-controls="playlistPanel"
:tabindex="currentTab === 'playlists' ? 0 : -1"
:class="(currentTab==='playlists')?'selectedTab':''"
@click="changeTab('playlists')"
@keydown.left.right.enter.space="changeTab('playlists', $event)"
>
{{ $t("Channel.Playlists.Playlists").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
v-if="tabInfoValues.includes('community') && !hideChannelCommunity"
id="communityTab"
class="tab"
role="tab"
:aria-selected="String(currentTab === 'community')"
aria-controls="communityPanel"
:tabindex="currentTab === 'community' ? 0 : -1"
:class="(currentTab==='community')?'selectedTab':''"
@click="changeTab('community')"
@keydown.left.right.enter.space="changeTab('community', $event)"
>
{{ $t("Global.Community").toUpperCase() }}
</div>
<!-- eslint-disable-next-line vuejs-accessibility/interactive-supports-focus -->
<div
id="aboutTab"
class="tab"
role="tab"
:aria-selected="String(currentTab === 'about')"
aria-controls="aboutPanel"
:tabindex="currentTab === 'about' ? 0 : -1"
:class="(currentTab==='about')?'selectedTab':''"
@click="changeTab('about')"
@keydown.left.right.enter.space="changeTab('about', $event)"
>
{{ $t("Channel.About.About").toUpperCase() }}
</div>
</div>
<ft-input
v-if="showSearchBar"
:placeholder="$t('Channel.Search Channel')"
:show-clear-text-button="true"
class="channelSearch"
@click="newSearch"
/>
</ft-flex-box>
</div>
</ft-card>
<ft-card
v-if="!isLoading && !errorMessage && (isFamilyFriendly || !showFamilyFriendlyOnly)"
class="card"
>
<channel-about
v-if="currentTab === 'about'"
id="aboutPanel"
:description="description"
:joined="joined"
:views="viewCount"
:videos="videoCount"
:location="location"
:tags="tags"
:related-channels="relatedChannels"
/>
<div class="select-container">
<ft-select
v-if="showVideoSortBy"
v-show="currentTab === 'videos' && latestVideos.length > 0"
:value="videoLiveSelectValues[0]"
:select-names="videoLiveSelectNames"
:select-values="videoLiveSelectValues"
:placeholder="$t('Search Filters.Sort By.Sort By')"
@change="videoSortBy = $event"
/>
<ft-select
v-if="!hideChannelShorts && showShortSortBy"
v-show="currentTab === 'shorts' && latestShorts.length > 0"
:value="shortSelectValues[0]"
:select-names="shortSelectNames"
:select-values="shortSelectValues"
:placeholder="$t('Search Filters.Sort By.Sort By')"
@change="shortSortBy = $event"
/>
<ft-select
v-if="!hideLiveStreams && showLiveSortBy"
v-show="currentTab === 'live' && latestLive.length > 0"
:value="videoLiveSelectValues[0]"
:select-names="videoLiveSelectNames"
:select-values="videoLiveSelectValues"
:placeholder="$t('Search Filters.Sort By.Sort By')"
@change="liveSortBy = $event"
/>
<ft-select
v-if="!hideChannelPlaylists && showPlaylistSortBy"
v-show="currentTab === 'playlists' && latestPlaylists.length > 0"
:value="playlistSelectValues[0]"
:select-names="playlistSelectNames"
:select-values="playlistSelectValues"
:placeholder="$t('Search Filters.Sort By.Sort By')"
@change="playlistSortBy = $event"
/>
</div>
<ft-loader
v-if="isElementListLoading"
/>
<div
v-if="currentTab !== 'about' && !isElementListLoading"
class="elementList"
>
<ft-element-list
v-show="currentTab === 'videos'"
id="videoPanel"
:data="latestVideos"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="videosTab"
/>
<ft-flex-box
v-if="currentTab === 'videos' && latestVideos.length === 0"
>
<p class="message">
{{ $t("Channel.Videos.This channel does not currently have any videos") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideChannelShorts && currentTab === 'shorts'"
id="shortPanel"
:data="latestShorts"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="shortsTab"
/>
<ft-flex-box
v-if="!hideChannelShorts && currentTab === 'shorts' && latestShorts.length === 0"
>
<p class="message">
{{ $t("Channel.Shorts.This channel does not currently have any shorts") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideLiveStreams"
v-show="currentTab === 'live'"
id="livePanel"
:data="latestLive"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="liveTab"
/>
<ft-flex-box
v-if="!hideLiveStreams && currentTab === 'live' && latestLive.length === 0"
>
<p class="message">
{{ $t("Channel.Live.This channel does not currently have any live streams") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideChannelPodcasts && currentTab === 'podcasts'"
id="podcastPanel"
:data="latestPodcasts"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="podcastsTab"
/>
<ft-flex-box
v-if="!hideChannelPodcasts && currentTab === 'podcasts' && latestPodcasts.length === 0"
>
<p class="message">
{{ $t("Channel.Podcasts.This channel does not currently have any podcasts") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideChannelReleases && currentTab === 'releases'"
id="releasePanel"
:data="latestReleases"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="releasesTab"
/>
<ft-flex-box
v-if="!hideChannelReleases && currentTab === 'releases' && latestReleases.length === 0"
>
<p class="message">
{{ $t("Channel.Releases.This channel does not currently have any releases") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideChannelPlaylists && currentTab === 'playlists'"
id="playlistPanel"
:data="latestPlaylists"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="playlistsTab"
/>
<ft-flex-box
v-if="!hideChannelPlaylists && currentTab === 'playlists' && latestPlaylists.length === 0"
>
<p class="message">
{{ $t("Channel.Playlists.This channel does not currently have any playlists") }}
</p>
</ft-flex-box>
<ft-element-list
v-if="!hideChannelCommunity && currentTab === 'community'"
id="communityPanel"
:data="latestCommunityPosts"
:use-channels-hidden-preference="false"
role="tabpanel"
aria-labelledby="communityTab"
display="list"
/>
<ft-flex-box
v-if="!hideChannelCommunity && currentTab === 'community' && latestCommunityPosts.length === 0"
>
<p class="message">
{{ $t("Channel.Community.This channel currently does not have any posts") }}
</p>
</ft-flex-box>
<ft-element-list
v-show="currentTab === 'search'"
:data="searchResults"
:use-channels-hidden-preference="false"
/>
<ft-flex-box
v-if="currentTab === 'search' && searchResults.length === 0"
>
<p class="message">
{{ $t("Channel.Your search results have returned 0 results") }}
</p>
</ft-flex-box>
<div
v-if="showFetchMoreButton"
class="getNextPage"
role="button"
tabindex="0"
@click="handleFetchMore"
@keydown.space.prevent="handleFetchMore"
@keydown.enter.prevent="handleFetchMore"
>
<font-awesome-icon :icon="['fas', 'search']" /> {{ $t("Search Filters.Fetch more results") }}
</div>
</div>
</ft-card>
<ft-card
v-if="errorMessage"
class="card"
>
<p>
{{ errorMessage }}
</p>
</ft-card>
<ft-age-restricted
v-else-if="!isLoading && (!isFamilyFriendly && showFamilyFriendlyOnly)"
class="ageRestricted"
:is-channel="true"
/>
</div>
</template>
<script src="./Channel.js" />
<style scoped src="./Channel.css" />