Add Parental Controls (#1456)
* start to implement some parental controls * Hide share + Hide Unsubscribe * Hide live streams * fix hide live streams * Add "parental-control-settings" * Implement Hide Live Streams & Hide "Age Restricted" * Hide live streams from Subscriptions + fix hide live streams from search * enable safe search on showFamilyFriendlyOnly * Move some settings from parental control to distraction free * fix channel loading * make parental control settings collapsible * fix lint * dont show age restricted on videos that are loading * improve hide live videos * code refactor * grammar * nvm im dumb * use named placeholder for age restricted message * improve readability * change Hide Description to Hide Video Description * update translated strings * fix age restricted component Co-authored-by: Preston <freetubeapp@protonmail.com> Co-authored-by: peepopoggers <72892531+peepopoggers@users.noreply.github.com>
This commit is contained in:
parent
ca2799e999
commit
3321fa91e4
|
@ -45,6 +45,18 @@ export default Vue.extend({
|
|||
},
|
||||
hideActiveSubscriptions: function () {
|
||||
return this.$store.getters.getHideActiveSubscriptions
|
||||
},
|
||||
hideVideoDescription: function () {
|
||||
return this.$store.getters.getHideVideoDescription
|
||||
},
|
||||
hideComments: function () {
|
||||
return this.$store.getters.getHideComments
|
||||
},
|
||||
hideLiveStreams: function() {
|
||||
return this.$store.getters.getHideLiveStreams
|
||||
},
|
||||
hideSharingActions: function() {
|
||||
return this.$store.getters.getHideSharingActions
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -68,7 +80,11 @@ export default Vue.extend({
|
|||
'updateHideLiveChat',
|
||||
'updateHideActiveSubscriptions',
|
||||
'updatePlayNextVideo',
|
||||
'updateDefaultTheatreMode'
|
||||
'updateDefaultTheatreMode',
|
||||
'updateHideVideoDescription',
|
||||
'updateHideComments',
|
||||
'updateHideLiveStreams',
|
||||
'updateHideSharingActions'
|
||||
])
|
||||
}
|
||||
})
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
:default-value="hideActiveSubscriptions"
|
||||
@change="updateHideActiveSubscriptions"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Distraction Free Settings.Hide Video Description')"
|
||||
:compact="true"
|
||||
:default-value="hideVideoDescription"
|
||||
@change="updateHideVideoDescription"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Distraction Free Settings.Hide Sharing Actions')"
|
||||
:compact="true"
|
||||
:default-value="hideSharingActions"
|
||||
@change="updateHideSharingActions"
|
||||
/>
|
||||
</div>
|
||||
<div class="switchColumn">
|
||||
<ft-toggle-switch
|
||||
|
@ -70,6 +82,18 @@
|
|||
:default-value="hideLiveChat"
|
||||
@change="updateHideLiveChat"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Distraction Free Settings.Hide Live Streams')"
|
||||
:compact="true"
|
||||
:default-value="hideLiveStreams"
|
||||
@change="updateHideLiveStreams"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Distraction Free Settings.Hide Comments')"
|
||||
:compact="true"
|
||||
:default-value="hideComments"
|
||||
@change="updateHideComments"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'FtAgeRestricted',
|
||||
props: {
|
||||
contentTypeString: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
emoji: function () {
|
||||
const emojis = ['😵', '😦', '🙁', '☹️', '😦', '🤫', '😕']
|
||||
return emojis[Math.floor(Math.random() * emojis.length)]
|
||||
},
|
||||
|
||||
restrictedMessage: function () {
|
||||
const contentType = this.$t('Age Restricted.Type.' + this.contentTypeString)
|
||||
return this.$t('Age Restricted.This $contentType is age restricted').replace('$contentType', contentType)
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,14 @@
|
|||
.ft-age-restricted
|
||||
color: var(--primary-text-color)
|
||||
h2
|
||||
width: 100%
|
||||
text-align: center
|
||||
background-color: var(--card-bg-color)
|
||||
padding: 10px 0
|
||||
.frown
|
||||
width: 100%
|
||||
text-align: center
|
||||
background-color: var(--card-bg-color)
|
||||
font-size: 10em
|
||||
padding: 20px 0
|
||||
height: 100%
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div
|
||||
class="ft-age-restricted"
|
||||
>
|
||||
<h2>
|
||||
{{ restrictedMessage }}
|
||||
</h2>
|
||||
<div class="frown">
|
||||
{{ emoji }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./ft-age-restricted.js" />
|
||||
<style scoped lang="sass" src="./ft-age-restricted.sass" />
|
|
@ -33,6 +33,11 @@ export default Vue.extend({
|
|||
visible: this.firstScreen
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hideLiveStreams: function() {
|
||||
return this.$store.getters.getHideLiveStreams
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onVisibilityChanged: function (visible) {
|
||||
this.visible = visible
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="data.type !== undefined && (data.type === 'video' ? ((!data.liveNow && (data.lengthSeconds != null)) || (!hideLiveStreams)) : true)"
|
||||
v-observe-visibility="firstScreen ? false : {
|
||||
callback: onVisibilityChanged,
|
||||
once: true,
|
||||
|
|
|
@ -117,69 +117,76 @@ export default Vue.extend({
|
|||
return (this.watchProgress / this.data.lengthSeconds) * 100
|
||||
},
|
||||
|
||||
hideSharingActions: function() {
|
||||
return this.$store.getters.getHideSharingActions
|
||||
},
|
||||
|
||||
dropdownOptions: function () {
|
||||
const options = []
|
||||
|
||||
options.push(
|
||||
{
|
||||
label: this.watched
|
||||
? this.$t('Video.Remove From History')
|
||||
: this.$t('Video.Mark As Watched'),
|
||||
value: 'history'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Link'),
|
||||
value: 'copyYoutube'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Embedded Player Link'),
|
||||
value: 'copyYoutubeEmbed'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy Invidious Link'),
|
||||
value: 'copyInvidious'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open in YouTube'),
|
||||
value: 'openYoutube'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open YouTube Embedded Player'),
|
||||
value: 'openYoutubeEmbed'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open in Invidious'),
|
||||
value: 'openInvidious'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Channel Link'),
|
||||
value: 'copyYoutubeChannel'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy Invidious Channel Link'),
|
||||
value: 'copyInvidiousChannel'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open Channel in YouTube'),
|
||||
value: 'openYoutubeChannel'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open Channel in Invidious'),
|
||||
value: 'openInvidiousChannel'
|
||||
}
|
||||
)
|
||||
if (!this.hideSharingActions) {
|
||||
options.push(
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Link'),
|
||||
value: 'copyYoutube'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Embedded Player Link'),
|
||||
value: 'copyYoutubeEmbed'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy Invidious Link'),
|
||||
value: 'copyInvidious'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open in YouTube'),
|
||||
value: 'openYoutube'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open YouTube Embedded Player'),
|
||||
value: 'openYoutubeEmbed'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open in Invidious'),
|
||||
value: 'openInvidious'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy YouTube Channel Link'),
|
||||
value: 'copyYoutubeChannel'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Copy Invidious Channel Link'),
|
||||
value: 'copyInvidiousChannel'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open Channel in YouTube'),
|
||||
value: 'openYoutubeChannel'
|
||||
},
|
||||
{
|
||||
label: this.$t('Video.Open Channel in Invidious'),
|
||||
value: 'openInvidiousChannel'
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return options
|
||||
},
|
||||
|
@ -203,6 +210,11 @@ export default Vue.extend({
|
|||
return `${baseUrl}/vi/${this.id}/mqdefault.jpg`
|
||||
}
|
||||
},
|
||||
|
||||
hideLiveStreams: function() {
|
||||
return this.$store.getters.getHideLiveStreams
|
||||
},
|
||||
|
||||
hideVideoViews: function () {
|
||||
return this.$store.getters.getHideVideoViews
|
||||
},
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import Vue from 'vue'
|
||||
import { mapActions } from 'vuex'
|
||||
import FtCard from '../ft-card/ft-card.vue'
|
||||
import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue'
|
||||
import FtButton from '../ft-button/ft-button.vue'
|
||||
import FtSelect from '../ft-select/ft-select.vue'
|
||||
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'ParentalControlSettings',
|
||||
components: {
|
||||
'ft-card': FtCard,
|
||||
'ft-toggle-switch': FtToggleSwitch,
|
||||
'ft-button': FtButton,
|
||||
'ft-select': FtSelect,
|
||||
'ft-flex-box': FtFlexBox
|
||||
},
|
||||
computed: {
|
||||
hideSearchBar: function () {
|
||||
return this.$store.getters.getHideSearchBar
|
||||
},
|
||||
hideUnsubscribeButton: function() {
|
||||
return this.$store.getters.getHideUnsubscribeButton
|
||||
},
|
||||
showFamilyFriendlyOnly: function() {
|
||||
return this.$store.getters.getShowFamilyFriendlyOnly
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
'updateHideSearchBar',
|
||||
'updateHideUnsubscribeButton',
|
||||
'updateShowFamilyFriendlyOnly'
|
||||
])
|
||||
}
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
@use "../../sass-partials/settings"
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<details>
|
||||
<summary>
|
||||
<h3>
|
||||
{{ $t("Settings.Parental Control Settings.Parental Control Settings") }}
|
||||
</h3>
|
||||
</summary>
|
||||
<hr>
|
||||
<div class="switchColumnGrid">
|
||||
<div class="switchColumn">
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Parental Control Settings.Hide Unsubscribe Button')"
|
||||
:compact="true"
|
||||
:default-value="hideUnsubscribeButton"
|
||||
@change="updateHideUnsubscribeButton"
|
||||
/>
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Parental Control Settings.Show Family Friendly Only')"
|
||||
:compact="true"
|
||||
:default-value="showFamilyFriendlyOnly"
|
||||
@change="updateShowFamilyFriendlyOnly"
|
||||
/>
|
||||
</div>
|
||||
<div class="switchColumn">
|
||||
<ft-toggle-switch
|
||||
:label="$t('Settings.Parental Control Settings.Hide Search Bar')"
|
||||
:compact="true"
|
||||
:default-value="hideSearchBar"
|
||||
@change="updateHideSearchBar"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</template>
|
||||
|
||||
<script src="./parental-control-settings.js" />
|
||||
<style scoped lang="sass" src="./parental-control-settings.sass" />
|
|
@ -35,6 +35,10 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
hideSharingActions: function() {
|
||||
return this.$store.getters.getHideSharingActions
|
||||
},
|
||||
|
||||
currentInvidiousInstance: function () {
|
||||
return this.$store.getters.getCurrentInvidiousInstance
|
||||
},
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<br>
|
||||
|
||||
<ft-list-dropdown
|
||||
v-if="!hideSharingActions"
|
||||
:title="$t('Playlist.Share Playlist.Share Playlist')"
|
||||
:label-names="shareHeaders"
|
||||
:label-values="shareValues"
|
||||
|
|
|
@ -32,6 +32,10 @@ export default Vue.extend({
|
|||
return this.$store.getters.getUsingElectron
|
||||
},
|
||||
|
||||
hideSearchBar: function () {
|
||||
return this.$store.getters.getHideSearchBar
|
||||
},
|
||||
|
||||
enableSearchSuggestions: function () {
|
||||
return this.$store.getters.getEnableSearchSuggestions
|
||||
},
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
@keypress="historyForward"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
v-if="!hideSearchBar"
|
||||
class="navSearchIcon navIcon"
|
||||
icon="search"
|
||||
role="button"
|
||||
|
@ -66,6 +67,7 @@
|
|||
<div class="middle">
|
||||
<div class="searchContainer">
|
||||
<ft-input
|
||||
v-if="!hideSearchBar"
|
||||
ref="searchInput"
|
||||
:placeholder="$t('Search / Go to URL')"
|
||||
class="searchInput"
|
||||
|
@ -78,6 +80,7 @@
|
|||
@click="goToSearch"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
v-if="!hideSearchBar"
|
||||
class="navFilterIcon navIcon"
|
||||
:class="{ filterChanged: searchFilterValueChanged }"
|
||||
icon="filter"
|
||||
|
@ -88,6 +91,7 @@
|
|||
/>
|
||||
</div>
|
||||
<ft-search-filters
|
||||
v-if="!hideSearchBar"
|
||||
v-show="showFilters"
|
||||
class="searchFilters"
|
||||
@filterValueUpdated="handleSearchFilterValueChanged"
|
||||
|
|
|
@ -126,6 +126,14 @@ export default Vue.extend({
|
|||
return this.$store.getters.getCurrentInvidiousInstance
|
||||
},
|
||||
|
||||
hideSharingActions: function() {
|
||||
return this.$store.getters.getHideSharingActions
|
||||
},
|
||||
|
||||
hideUnsubscribeButton: function() {
|
||||
return this.$store.getters.getHideUnsubscribeButton
|
||||
},
|
||||
|
||||
currentLocale: function () {
|
||||
return this.$store.getters.getCurrentLocale
|
||||
},
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
{{ channelName }}
|
||||
</div>
|
||||
<ft-button
|
||||
v-if="!hideUnsubscribeButton"
|
||||
:label="subscribedText"
|
||||
class="subscribeButton"
|
||||
background-color="var(--primary-color)"
|
||||
|
@ -113,6 +114,7 @@
|
|||
@click="handleFormatChange"
|
||||
/>
|
||||
<ft-share-button
|
||||
v-if="!hideSharingActions"
|
||||
:id="id"
|
||||
:get-timestamp="getTimestamp"
|
||||
:playlist-id="playlistId"
|
||||
|
|
|
@ -192,11 +192,17 @@ const state = {
|
|||
hideActiveSubscriptions: false,
|
||||
hideChannelSubscriptions: false,
|
||||
hideCommentLikes: false,
|
||||
hideComments: false,
|
||||
hideVideoDescription: false,
|
||||
hideLiveChat: false,
|
||||
hideLiveStreams: false,
|
||||
hidePlaylists: false,
|
||||
hidePopularVideos: false,
|
||||
hideRecommendedVideos: false,
|
||||
hideSearchBar: false,
|
||||
hideSharingActions: false,
|
||||
hideTrendingVideos: false,
|
||||
hideUnsubscribeButton: false,
|
||||
hideVideoLikesAndDislikes: false,
|
||||
hideVideoViews: false,
|
||||
hideWatchedSubs: false,
|
||||
|
@ -213,6 +219,7 @@ const state = {
|
|||
rememberHistory: true,
|
||||
removeVideoMetaFiles: true,
|
||||
saveWatchedProgress: true,
|
||||
showFamilyFriendlyOnly: false,
|
||||
sponsorBlockShowSkippedToast: true,
|
||||
sponsorBlockUrl: 'https://sponsor.ajay.app',
|
||||
sponsorBlockSponsor: {
|
||||
|
|
|
@ -8,6 +8,7 @@ import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
|||
import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue'
|
||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
||||
import FtAgeRestricted from '../../components/ft-age-restricted/ft-age-restricted.vue'
|
||||
|
||||
import ytch from 'yt-channel-info'
|
||||
import autolinker from 'autolinker'
|
||||
|
@ -23,7 +24,8 @@ export default Vue.extend({
|
|||
'ft-flex-box': FtFlexBox,
|
||||
'ft-channel-bubble': FtChannelBubble,
|
||||
'ft-loader': FtLoader,
|
||||
'ft-element-list': FtElementList
|
||||
'ft-element-list': FtElementList,
|
||||
'ft-age-restricted': FtAgeRestricted
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
|
@ -50,6 +52,7 @@ export default Vue.extend({
|
|||
searchResults: [],
|
||||
shownElementList: [],
|
||||
apiUsed: '',
|
||||
isFamilyFriendly: false,
|
||||
errorMessage: '',
|
||||
videoSelectValues: [
|
||||
'newest',
|
||||
|
@ -75,6 +78,14 @@ export default Vue.extend({
|
|||
return this.$store.getters.getBackendFallback
|
||||
},
|
||||
|
||||
hideUnsubscribeButton: function() {
|
||||
return this.$store.getters.getHideUnsubscribeButton
|
||||
},
|
||||
|
||||
showFamilyFriendlyOnly: function() {
|
||||
return this.$store.getters.getShowFamilyFriendlyOnly
|
||||
},
|
||||
|
||||
currentInvidiousInstance: function () {
|
||||
return this.$store.getters.getCurrentInvidiousInstance
|
||||
},
|
||||
|
@ -264,6 +275,7 @@ export default Vue.extend({
|
|||
const channelThumbnailUrl = response.authorThumbnails[2].url
|
||||
this.id = channelId
|
||||
this.channelName = channelName
|
||||
this.isFamilyFriendly = response.isFamilyFriendly
|
||||
document.title = `${this.channelName} - ${process.env.PRODUCT_NAME}`
|
||||
if (this.hideChannelSubscriptions || response.subscriberCount === 0) {
|
||||
this.subCount = null
|
||||
|
@ -383,6 +395,7 @@ export default Vue.extend({
|
|||
this.channelName = channelName
|
||||
document.title = `${this.channelName} - ${process.env.PRODUCT_NAME}`
|
||||
this.id = channelId
|
||||
this.isFamilyFriendly = response.isFamilyFriendly
|
||||
if (this.hideChannelSubscriptions) {
|
||||
this.subCount = null
|
||||
} else {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
:fullscreen="true"
|
||||
/>
|
||||
<ft-card
|
||||
v-else
|
||||
v-else-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
class="card channelDetails"
|
||||
>
|
||||
<div
|
||||
|
@ -52,6 +52,7 @@
|
|||
</div>
|
||||
|
||||
<ft-button
|
||||
v-if="!hideUnsubscribeButton"
|
||||
:label="subscribedText"
|
||||
background-color="var(--primary-color)"
|
||||
text-color="var(--text-with-main-color)"
|
||||
|
@ -113,7 +114,7 @@
|
|||
</div>
|
||||
</ft-card>
|
||||
<ft-card
|
||||
v-if="!isLoading && !errorMessage"
|
||||
v-if="!isLoading && !errorMessage && (isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
class="card"
|
||||
>
|
||||
<div
|
||||
|
@ -203,6 +204,11 @@
|
|||
{{ errorMessage }}
|
||||
</p>
|
||||
</ft-card>
|
||||
<ft-age-restricted
|
||||
v-else-if="!isLoading && (!isFamilyFriendly && showFamilyFriendlyOnly)"
|
||||
class="ageRestricted"
|
||||
:content-type-string="'Channel'"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@ export default Vue.extend({
|
|||
|
||||
backendFallback: function () {
|
||||
return this.$store.getters.getBackendFallback
|
||||
},
|
||||
|
||||
hideLiveStreams: function() {
|
||||
return this.$store.getters.getHideLiveStreams
|
||||
},
|
||||
showFamilyFriendlyOnly: function() {
|
||||
return this.$store.getters.getShowFamilyFriendlyOnly
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -94,6 +101,7 @@ export default Vue.extend({
|
|||
|
||||
if (sameSearch.length > 0) {
|
||||
console.log(sameSearch)
|
||||
|
||||
// Replacing the data right away causes a strange error where the data
|
||||
// Shown is mixed from 2 different search results. So we'll wait a moment
|
||||
// Before showing the results.
|
||||
|
@ -118,6 +126,8 @@ export default Vue.extend({
|
|||
payload.options.pages = 1
|
||||
}
|
||||
|
||||
payload.options.safeSearch = this.showFamilyFriendlyOnly
|
||||
|
||||
this.ytSearch(payload).then((result) => {
|
||||
console.log(result)
|
||||
if (!result) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import DataSettings from '../../components/data-settings/data-settings.vue'
|
|||
import DistractionSettings from '../../components/distraction-settings/distraction-settings.vue'
|
||||
import ProxySettings from '../../components/proxy-settings/proxy-settings.vue'
|
||||
import SponsorBlockSettings from '../../components/sponsor-block-settings/sponsor-block-settings.vue'
|
||||
import ParentControlSettings from '../../components/parental-control-settings/parental-control-settings.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'Settings',
|
||||
|
@ -28,7 +29,8 @@ export default Vue.extend({
|
|||
'distraction-settings': DistractionSettings,
|
||||
'proxy-settings': ProxySettings,
|
||||
'sponsor-block-settings': SponsorBlockSettings,
|
||||
'download-settings': DownloadSettings
|
||||
'download-settings': DownloadSettings,
|
||||
'parental-control-settings': ParentControlSettings
|
||||
},
|
||||
computed: {
|
||||
usingElectron: function () {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
<hr>
|
||||
<download-settings v-if="usingElectron" />
|
||||
<hr>
|
||||
<parental-control-settings />
|
||||
<hr>
|
||||
<sponsor-block-settings />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -86,6 +86,10 @@ export default Vue.extend({
|
|||
|
||||
activeSubscriptionList: function () {
|
||||
return this.activeProfile.subscriptions
|
||||
},
|
||||
|
||||
hideLiveStreams: function() {
|
||||
return this.$store.getters.getHideLiveStreams
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -178,7 +182,11 @@ export default Vue.extend({
|
|||
videoList = await Promise.all(videoList.sort((a, b) => {
|
||||
return b.publishedDate - a.publishedDate
|
||||
}))
|
||||
|
||||
if (this.hideLiveStreams) {
|
||||
videoList = videoList.filter(item => {
|
||||
return (!item.liveNow && !item.isUpcoming)
|
||||
})
|
||||
}
|
||||
const profileSubscriptions = {
|
||||
activeProfile: this.activeProfile._id,
|
||||
videoList: videoList,
|
||||
|
|
|
@ -13,6 +13,7 @@ import WatchVideoComments from '../../components/watch-video-comments/watch-vide
|
|||
import WatchVideoLiveChat from '../../components/watch-video-live-chat/watch-video-live-chat.vue'
|
||||
import WatchVideoPlaylist from '../../components/watch-video-playlist/watch-video-playlist.vue'
|
||||
import WatchVideoRecommendations from '../../components/watch-video-recommendations/watch-video-recommendations.vue'
|
||||
import FtAgeRestricted from '../../components/ft-age-restricted/ft-age-restricted.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'Watch',
|
||||
|
@ -26,7 +27,8 @@ export default Vue.extend({
|
|||
'watch-video-comments': WatchVideoComments,
|
||||
'watch-video-live-chat': WatchVideoLiveChat,
|
||||
'watch-video-playlist': WatchVideoPlaylist,
|
||||
'watch-video-recommendations': WatchVideoRecommendations
|
||||
'watch-video-recommendations': WatchVideoRecommendations,
|
||||
'ft-age-restricted': FtAgeRestricted
|
||||
},
|
||||
beforeRouteLeave: function (to, from, next) {
|
||||
this.handleRouteChange(this.videoId)
|
||||
|
@ -42,6 +44,7 @@ export default Vue.extend({
|
|||
showLegacyPlayer: false,
|
||||
showYouTubeNoCookieEmbed: false,
|
||||
hidePlayer: false,
|
||||
isFamilyFriendly: false,
|
||||
isLive: false,
|
||||
isLiveContent: false,
|
||||
isUpcoming: false,
|
||||
|
@ -134,6 +137,15 @@ export default Vue.extend({
|
|||
hideLiveChat: function () {
|
||||
return this.$store.getters.getHideLiveChat
|
||||
},
|
||||
hideComments: function () {
|
||||
return this.$store.getters.getHideComments
|
||||
},
|
||||
hideVideoDescription: function () {
|
||||
return this.$store.getters.getHideVideoDescription
|
||||
},
|
||||
showFamilyFriendlyOnly: function() {
|
||||
return this.$store.getters.getShowFamilyFriendlyOnly
|
||||
},
|
||||
|
||||
youtubeNoCookieEmbeddedFrame: function () {
|
||||
return `<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/${this.videoId}?rel=0' frameborder='0' allow='autoplay; encrypted-media' allowfullscreen></iframe>`
|
||||
|
@ -300,6 +312,7 @@ export default Vue.extend({
|
|||
break
|
||||
}
|
||||
|
||||
this.isFamilyFriendly = result.videoDetails.isFamilySafe
|
||||
this.recommendedVideos = result.related_videos.map((video) => {
|
||||
video.videoId = video.id
|
||||
video.authorId = video.author.id
|
||||
|
@ -586,6 +599,7 @@ export default Vue.extend({
|
|||
return format
|
||||
})
|
||||
this.isLive = result.liveNow
|
||||
this.isFamilyFriendly = result.isFamilyFriendly
|
||||
this.captionHybridList = result.captions.map(caption => {
|
||||
caption.url = this.currentInvidiousInstance + caption.url
|
||||
caption.type = ''
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
=single-column-template
|
||||
grid-template: "video" auto "info" auto "sidebar" auto / auto
|
||||
.ageRestricted
|
||||
max-width: calc(80vh * 1.78)
|
||||
display: inline-block
|
||||
+single-column-template
|
||||
@media only screen and (min-width: 901px)
|
||||
width: 300%
|
||||
|
||||
.videoLayout
|
||||
display: grid
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
v-if="isLoading"
|
||||
:fullscreen="true"
|
||||
/>
|
||||
<div class="videoArea">
|
||||
<div
|
||||
v-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
class="videoArea"
|
||||
>
|
||||
<div class="videoAreaMargin">
|
||||
<ft-video-player
|
||||
v-if="!isLoading && !hidePlayer && !isUpcoming"
|
||||
|
@ -64,7 +67,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="infoArea">
|
||||
<ft-age-restricted
|
||||
v-if="(!isLoading && !isFamilyFriendly && showFamilyFriendlyOnly)"
|
||||
class="ageRestricted"
|
||||
:content-type-string="'Video'"
|
||||
/>
|
||||
<div
|
||||
v-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
class="infoArea"
|
||||
>
|
||||
<watch-video-info
|
||||
v-if="!isLoading"
|
||||
:id="videoId"
|
||||
|
@ -96,7 +107,7 @@
|
|||
@pause-player="pausePlayer"
|
||||
/>
|
||||
<watch-video-description
|
||||
v-if="!isLoading"
|
||||
v-if="!isLoading && !hideVideoDescription"
|
||||
:published="videoPublished"
|
||||
:description="videoDescription"
|
||||
:description-html="videoDescriptionHtml"
|
||||
|
@ -105,7 +116,7 @@
|
|||
@timestamp-event="changeTimestamp"
|
||||
/>
|
||||
<watch-video-comments
|
||||
v-if="!isLoading && !isLive"
|
||||
v-if="!isLoading && !isLive && !hideComments"
|
||||
:id="videoId"
|
||||
class="watchVideo"
|
||||
:class="{ theatreWatchVideo: useTheatreMode }"
|
||||
|
@ -114,7 +125,10 @@
|
|||
@timestamp-event="changeTimestamp"
|
||||
/>
|
||||
</div>
|
||||
<div class="sidebarArea">
|
||||
<div
|
||||
v-if="(isFamilyFriendly || !showFamilyFriendlyOnly)"
|
||||
class="sidebarArea"
|
||||
>
|
||||
<watch-video-live-chat
|
||||
v-if="!isLoading && isLive"
|
||||
:video-id="videoId"
|
||||
|
|
|
@ -289,6 +289,10 @@ Settings:
|
|||
Hide Playlists: Hide Playlists
|
||||
Hide Live Chat: Hide Live Chat
|
||||
Hide Active Subscriptions: Hide Active Subscriptions
|
||||
Hide Video Description: Hide Video Description
|
||||
Hide Comments: Hide Comments
|
||||
Hide Live Streams: Hide Live Streams
|
||||
Hide Sharing Actions: Hide Sharing Actions
|
||||
Data Settings:
|
||||
Data Settings: Data Settings
|
||||
Select Import Type: Select Import Type
|
||||
|
@ -361,6 +365,11 @@ Settings:
|
|||
Prompt To Skip: Prompt To Skip
|
||||
Do Nothing: Do Nothing
|
||||
Category Color: Category Color
|
||||
Parental Control Settings:
|
||||
Parental Control Settings: Parental Control Settings
|
||||
Hide Unsubscribe Button: Hide Unsubscribe Button
|
||||
Show Family Friendly Only: Show Family Friendly Only
|
||||
Hide Search Bar: Hide Search Bar
|
||||
Download Settings:
|
||||
Download Settings: Download Settings
|
||||
Ask Download Path: Ask for download path
|
||||
|
@ -756,6 +765,12 @@ Default Invidious instance has been set to $: Default Invidious instance has bee
|
|||
Default Invidious instance has been cleared: Default Invidious instance has been cleared
|
||||
'The playlist has ended. Enable loop to continue playing': 'The playlist has ended. Enable
|
||||
loop to continue playing'
|
||||
Age Restricted:
|
||||
# $contentType is replaced with video or channel
|
||||
This $contentType is age restricted: This $ is age restricted
|
||||
Type:
|
||||
Channel: Channel
|
||||
Video: Video
|
||||
External link opening has been disabled in the general settings: 'External link opening has been disabled in the general settings'
|
||||
Downloading has completed: '"$" has finished downloading'
|
||||
Starting download: 'Starting download of "$"'
|
||||
|
|
Loading…
Reference in New Issue