From 671bbf3fa493e432e8091daf70c19bc71659f3c9 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 21 Oct 2023 04:19:44 -0500 Subject: [PATCH 01/13] Implement hiding of videos with user-inputted text --- .../distraction-settings/distraction-settings.js | 9 ++++++++- .../distraction-settings/distraction-settings.vue | 11 +++++++++++ .../ft-community-post/ft-community-post.js | 13 +++++++++++++ .../ft-community-post/ft-community-post.scss | 6 ++++++ .../ft-community-post/ft-community-post.vue | 7 +++++++ .../components/ft-element-list/ft-element-list.js | 4 ++++ .../components/ft-element-list/ft-element-list.vue | 1 + .../components/ft-input-tags/ft-input-tags.js | 11 +++++++++++ .../ft-list-lazy-wrapper/ft-list-lazy-wrapper.js | 11 +++++++++++ .../ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue | 1 + .../ft-list-video-lazy/ft-list-video-lazy.js | 13 +++++++++++-- .../components/ft-video-player/ft-video-player.js | 2 +- .../subscriptions-tab-ui/subscriptions-tab-ui.vue | 1 + .../watch-video-recommendations.vue | 1 + src/renderer/store/modules/settings.js | 1 + src/renderer/views/Channel/Channel.vue | 7 +++++++ src/renderer/views/History/History.vue | 1 + src/renderer/views/UserPlaylists/UserPlaylists.vue | 1 + static/locales/en-US.yaml | 6 ++++++ 19 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/distraction-settings/distraction-settings.js b/src/renderer/components/distraction-settings/distraction-settings.js index 7f5e3741fc962..7d03126956949 100644 --- a/src/renderer/components/distraction-settings/distraction-settings.js +++ b/src/renderer/components/distraction-settings/distraction-settings.js @@ -107,13 +107,16 @@ export default defineComponent({ channelsHidden: function () { return JSON.parse(this.$store.getters.getChannelsHidden) }, + forbiddenVideoTitleText: function() { + return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + }, hideSubscriptionsLiveTooltip: function () { return this.$t('Tooltips.Distraction Free Settings.Hide Subscriptions Live', { appWideSetting: this.$t('Settings.Distraction Free Settings.Hide Live Streams'), subsection: this.$t('Settings.Distraction Free Settings.Sections.General'), settingsSection: this.$t('Settings.Distraction Free Settings.Distraction Free Settings') }) - } + }, }, methods: { handleHideRecommendedVideos: function (value) { @@ -126,6 +129,9 @@ export default defineComponent({ handleChannelsHidden: function (value) { this.updateChannelsHidden(JSON.stringify(value)) }, + handleForbiddenVideoTitleText: function (value) { + this.updateForbiddenVideoTitleText(JSON.stringify(value)) + }, ...mapActions([ 'updateHideVideoViews', @@ -148,6 +154,7 @@ export default defineComponent({ 'updateHideSharingActions', 'updateHideChapters', 'updateChannelsHidden', + 'updateForbiddenVideoTitleText', 'updateShowDistractionFreeTitles', 'updateHideFeaturedChannels', 'updateHideChannelShorts', diff --git a/src/renderer/components/distraction-settings/distraction-settings.vue b/src/renderer/components/distraction-settings/distraction-settings.vue index 5b6f06db4a4a1..2250d4a987e4f 100644 --- a/src/renderer/components/distraction-settings/distraction-settings.vue +++ b/src/renderer/components/distraction-settings/distraction-settings.vue @@ -245,6 +245,17 @@ @change="handleChannelsHidden" /> + + + diff --git a/src/renderer/components/ft-community-post/ft-community-post.js b/src/renderer/components/ft-community-post/ft-community-post.js index ddd1d714b0a65..a574aea0f2dd4 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.js +++ b/src/renderer/components/ft-community-post/ft-community-post.js @@ -27,6 +27,10 @@ export default defineComponent({ appearance: { type: String, required: true + }, + hideVideosWithForbiddenTextInTitle: { + type: Boolean, + default: true } }, data: function () { @@ -57,6 +61,15 @@ export default defineComponent({ listType: function () { return this.$store.getters.getListType + }, + + forbiddenVideoTitleText() { + if (!this.hideVideosWithForbiddenTextInTitle) { return [] } + return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + }, + + hideVideo() { + return this.forbiddenVideoTitleText.some((text) => this.data.postContent.content.title?.toLowerCase().includes(text.toLowerCase())) } }, created: function () { diff --git a/src/renderer/components/ft-community-post/ft-community-post.scss b/src/renderer/components/ft-community-post/ft-community-post.scss index 7c7a6a8470ac4..0f7d9de65cc0f 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.scss +++ b/src/renderer/components/ft-community-post/ft-community-post.scss @@ -13,6 +13,12 @@ box-sizing: border-box; } +.hiddenVideo { + font-style: italic; + opacity: 0.85; + text-align: center; +} + .communityImage { block-size: 100%; inline-size: 100%; diff --git a/src/renderer/components/ft-community-post/ft-community-post.vue b/src/renderer/components/ft-community-post/ft-community-post.vue index 986591cf6f23c..e6feedf70f67f 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.vue +++ b/src/renderer/components/ft-community-post/ft-community-post.vue @@ -82,9 +82,16 @@ v-if="type === 'video'" > +

+ {{ '[' + $t('Channel.Community.Video hidden by FreeTube') + ']' }} +

diff --git a/src/renderer/components/ft-input-tags/ft-input-tags.js b/src/renderer/components/ft-input-tags/ft-input-tags.js index a621b47216757..c43cf6b6884af 100644 --- a/src/renderer/components/ft-input-tags/ft-input-tags.js +++ b/src/renderer/components/ft-input-tags/ft-input-tags.js @@ -1,6 +1,7 @@ import { defineComponent } from 'vue' import FtInput from '../ft-input/ft-input.vue' import FtTooltip from '../ft-tooltip/ft-tooltip.vue' +import { showToast } from '../../helpers/utils' export default defineComponent({ name: 'FtInputTags', @@ -17,6 +18,10 @@ export default defineComponent({ type: String, required: true }, + minTagLength: { + type: Number, + default: 1 + }, showActionButton: { type: Boolean, default: true @@ -34,6 +39,12 @@ export default defineComponent({ updateTags: function (text, e) { // text entered add tag and update tag list const trimmedText = text.trim() + + if (trimmedText && trimmedText.length < this.minTagLength) { + showToast(this.$t('Global.Input Tags.Length Requirement', { number: this.minTagLength })) + return + } + if (!this.tagList.includes(trimmedText)) { const newList = this.tagList.slice(0) newList.push(trimmedText) diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js index 5d65aa2c8ded0..11e0ff6da4b9b 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -39,6 +39,10 @@ export default defineComponent({ type: Boolean, default: true, }, + hideVideosWithForbiddenTextInTitle: { + type: Boolean, + default: true + }, }, data: function () { return { @@ -55,6 +59,10 @@ export default defineComponent({ return JSON.parse(this.$store.getters.getChannelsHidden) }, + forbiddenVideoTitleText: function() { + if (!this.hideVideosWithForbiddenTextInTitle) { return [] } + return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + }, hideUpcomingPremieres: function () { return this.$store.getters.getHideUpcomingPremieres }, @@ -91,6 +99,9 @@ export default defineComponent({ // hide videos by author return false } + if (this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { + return false + } } else if (data.type === 'channel') { const attrsToCheck = [ // Local API diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue index 65fbd2b6be595..471ec0b9a22e8 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue @@ -31,6 +31,7 @@ /> diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index c255110b4b3a8..b04b2496050dd 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -47,6 +47,10 @@ export default defineComponent({ type: Boolean, default: false, }, + hideVideosWithForbiddenTextInTitle: { + type: Boolean, + default: false + } }, data: function () { return { @@ -57,13 +61,18 @@ export default defineComponent({ channelsHidden() { // Some component users like channel view will have this disabled if (!this.useChannelsHiddenPreference) { return [] } - return JSON.parse(this.$store.getters.getChannelsHidden) }, + forbiddenVideoTitleText() { + if (!this.hideVideosWithForbiddenTextInTitle) { return [] } + return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + }, + shouldBeVisible() { return !(this.channelsHidden.includes(this.data.authorId) || - this.channelsHidden.includes(this.data.author)) + this.channelsHidden.includes(this.data.author) || + this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) } }, created() { diff --git a/src/renderer/components/ft-video-player/ft-video-player.js b/src/renderer/components/ft-video-player/ft-video-player.js index d3ca362bd8716..a36004d6b8356 100644 --- a/src/renderer/components/ft-video-player/ft-video-player.js +++ b/src/renderer/components/ft-video-player/ft-video-player.js @@ -771,7 +771,7 @@ export default defineComponent({ let newTime = null let skippedCategory = null skipSegments.forEach(({ category, segment: [startTime, endTime] }) => { - if (startTime <= currentTime && currentTime < endTime) { + if (startTime <= currentTime && currentTime <= endTime) { newTime = endTime skippedCategory = category } diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue index cd54567ad14e0..df6459ddda5fb 100644 --- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue +++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue @@ -43,6 +43,7 @@ v-if="!isLoading && activeVideoList.length > 0" :data="activeVideoList" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="true" :display="isCommunity ? 'list' : ''" /> diff --git a/src/renderer/store/modules/settings.js b/src/renderer/store/modules/settings.js index ba2ff912b1218..582d9eead1d44 100644 --- a/src/renderer/store/modules/settings.js +++ b/src/renderer/store/modules/settings.js @@ -204,6 +204,7 @@ const state = { hideComments: false, hideFeaturedChannels: false, channelsHidden: '[]', + forbiddenVideoTitleText: '[]', hideVideoDescription: false, hideLiveChat: false, hideLiveStreams: false, diff --git a/src/renderer/views/Channel/Channel.vue b/src/renderer/views/Channel/Channel.vue index f8cfb0b5c6ed8..0e35c934c173c 100644 --- a/src/renderer/views/Channel/Channel.vue +++ b/src/renderer/views/Channel/Channel.vue @@ -280,6 +280,7 @@ id="videoPanel" :data="latestVideos" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="videosTab" /> @@ -295,6 +296,7 @@ id="shortPanel" :data="latestShorts" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="shortsTab" /> @@ -311,6 +313,7 @@ id="livePanel" :data="latestLive" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="liveTab" /> @@ -326,6 +329,7 @@ id="podcastPanel" :data="latestPodcasts" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="podcastsTab" /> @@ -341,6 +345,7 @@ id="releasePanel" :data="latestReleases" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="releasesTab" /> @@ -371,6 +376,7 @@ id="communityPanel" :data="latestCommunityPosts" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="communityTab" display="list" @@ -386,6 +392,7 @@ v-show="currentTab === 'search'" :data="searchResults" :use-channels-hidden-preference="false" + :hide-videos-with-forbidden-text-in-title="false" /> diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js index c00174dc8e006..1787ec3023ad9 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -123,6 +123,9 @@ export default defineComponent({ return false } } else if (data.type === 'playlist') { + if (this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { + return false + } const attrsToCheck = [ // Local API data.channelId, diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 9dcd1c9ee776f..e64f8314ff328 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -377,8 +377,8 @@ Settings: Hide Channel Shorts: Hide Channel Shorts Hide Channel Podcasts: Hide Channel Podcasts Hide Channel Releases: Hide Channel Releases - Hide Videos Containing Text: Hide Videos Containing Text - Hide Videos Containing Text Placeholder: Word, Word Fragment, or Phrase + Hide Videos and Playlists Containing Text: Hide Videos and Playlists Containing Text + Hide Videos and Playlists Containing Text Placeholder: Word, Word Fragment, or Phrase Hide Subscriptions Videos: Hide Subscriptions Videos Hide Subscriptions Shorts: Hide Subscriptions Shorts Hide Subscriptions Live: Hide Subscriptions Live @@ -877,7 +877,7 @@ Tooltips: Hide Channels: Enter a channel ID to hide all videos, playlists and the channel itself from appearing in search, trending, most popular and recommended. The channel ID entered must be a complete match and is case sensitive. Hide Subscriptions Live: 'This setting is overridden by the app-wide "{appWideSetting}" setting, in the "{subsection}" section of the "{settingsSection}"' - Hide Videos Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos with titles containing it in subscriptions, trending, most popular, recommended, and searches. + Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it in subscriptions, trending, most popular, recommended, and searches. Subscription Settings: Fetch Feeds from RSS: When enabled, FreeTube will use RSS instead of its default method for grabbing your subscription feed. RSS is faster and prevents IP blocking, From ee7501135c0abdfe19bd7479036b4d9a09246cfd Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 18 Nov 2023 06:09:49 -0600 Subject: [PATCH 04/13] Enable feature on channel pages The premise for this change is that users would not want to see that forbidden content anywhere, as opposed to hidden channels, where you're clearly on a channel page to see things from that channel. --- .../components/ft-list-video-lazy/ft-list-video-lazy.js | 2 +- .../subscriptions-tab-ui/subscriptions-tab-ui.vue | 1 - .../watch-video-recommendations.vue | 1 - src/renderer/views/Channel/Channel.vue | 7 ------- src/renderer/views/History/History.vue | 1 - src/renderer/views/UserPlaylists/UserPlaylists.vue | 1 - static/locales/en-US.yaml | 2 +- 7 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index 7a2f846b9f4d5..6fa634d57459d 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -49,7 +49,7 @@ export default defineComponent({ }, hideVideosWithForbiddenTextInTitle: { type: Boolean, - default: false + default: true } }, data: function () { diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue index df6459ddda5fb..cd54567ad14e0 100644 --- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue +++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue @@ -43,7 +43,6 @@ v-if="!isLoading && activeVideoList.length > 0" :data="activeVideoList" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="true" :display="isCommunity ? 'list' : ''" /> diff --git a/src/renderer/views/Channel/Channel.vue b/src/renderer/views/Channel/Channel.vue index 0e35c934c173c..f8cfb0b5c6ed8 100644 --- a/src/renderer/views/Channel/Channel.vue +++ b/src/renderer/views/Channel/Channel.vue @@ -280,7 +280,6 @@ id="videoPanel" :data="latestVideos" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="videosTab" /> @@ -296,7 +295,6 @@ id="shortPanel" :data="latestShorts" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="shortsTab" /> @@ -313,7 +311,6 @@ id="livePanel" :data="latestLive" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="liveTab" /> @@ -329,7 +326,6 @@ id="podcastPanel" :data="latestPodcasts" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="podcastsTab" /> @@ -345,7 +341,6 @@ id="releasePanel" :data="latestReleases" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="releasesTab" /> @@ -376,7 +371,6 @@ id="communityPanel" :data="latestCommunityPosts" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" role="tabpanel" aria-labelledby="communityTab" display="list" @@ -392,7 +386,6 @@ v-show="currentTab === 'search'" :data="searchResults" :use-channels-hidden-preference="false" - :hide-videos-with-forbidden-text-in-title="false" /> Date: Mon, 20 Nov 2023 19:27:26 -0600 Subject: [PATCH 05/13] Fix 'Play Next Video' playing forbiddenTitle videos and hidden channel videos --- .../ft-community-post/ft-community-post.js | 1 - .../ft-list-lazy-wrapper.js | 1 - .../ft-list-video-lazy/ft-list-video-lazy.js | 1 - src/renderer/views/Watch/Watch.js | 32 ++++++++++++++++++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/ft-community-post/ft-community-post.js b/src/renderer/components/ft-community-post/ft-community-post.js index a574aea0f2dd4..58a686f5c2ecf 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.js +++ b/src/renderer/components/ft-community-post/ft-community-post.js @@ -64,7 +64,6 @@ export default defineComponent({ }, forbiddenVideoTitleText() { - if (!this.hideVideosWithForbiddenTextInTitle) { return [] } return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) }, diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js index 1787ec3023ad9..f405041c2ef79 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -66,7 +66,6 @@ export default defineComponent({ }) }, forbiddenVideoTitleText: function() { - if (!this.hideVideosWithForbiddenTextInTitle) { return [] } return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) }, hideUpcomingPremieres: function () { diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index 6fa634d57459d..b817673eb6bbe 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -72,7 +72,6 @@ export default defineComponent({ }, forbiddenVideoTitleText() { - if (!this.hideVideosWithForbiddenTextInTitle) { return [] } return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) }, diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index 7a8412793d1a6..f47b9b0b3f02a 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -213,6 +213,18 @@ export default defineComponent({ allowDashAv1Formats: function () { return this.$store.getters.getAllowDashAv1Formats }, + channelsHidden() { + return JSON.parse(this.$store.getters.getChannelsHidden).map((ch) => { + // Legacy support + if (typeof ch === 'string') { + return { name: ch, preferredName: '', icon: '' } + } + return ch + }) + }, + forbiddenVideoTitleText() { + return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + }, }, watch: { $route() { @@ -1248,6 +1260,19 @@ export default defineComponent({ this.$refs.watchVideoPlaylist.playNextVideo() return } + + let nextVideoId = null + if (!this.watchingPlaylist) { + const forbiddenVideoTitleText = this.forbiddenVideoTitleText + const channelsHidden = this.channelsHidden + nextVideoId = this.recommendedVideos.find((video) => + !this.isHiddenVideo(forbiddenVideoTitleText, channelsHidden, video) + )?.videoId + if (!nextVideoId) { + return + } + } + const nextVideoInterval = this.defaultInterval this.playNextTimeout = setTimeout(() => { const player = this.$refs.videoPlayer.player @@ -1255,7 +1280,6 @@ export default defineComponent({ if (this.watchingPlaylist) { this.$refs.watchVideoPlaylist.playNextVideo() } else { - const nextVideoId = this.recommendedVideos[0].videoId this.$router.push({ path: `/watch/${nextVideoId}` }) @@ -1703,6 +1727,12 @@ export default defineComponent({ document.title = `${this.videoTitle} - FreeTube` }, + isHiddenVideo: function (forbiddenVideoTitleText, channelsHidden, video) { + return channelsHidden.some(ch => ch.name === video.authorId) || + channelsHidden.some(ch => ch.name === video.author) || + forbiddenVideoTitleText.some((text) => video.title?.toLowerCase().includes(text.toLowerCase())) + }, + ...mapActions([ 'updateHistory', 'updateWatchProgress', From d239ddfcb96a6db7b251d10d1f9234d1764d46e3 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 20 Nov 2023 20:19:50 -0600 Subject: [PATCH 06/13] Fix issue of hidden recommended videos taking up vertical space --- .../components/ft-list-video-lazy/ft-list-video-lazy.js | 5 ++++- .../components/ft-list-video-lazy/ft-list-video-lazy.vue | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index b817673eb6bbe..20f8ad7ae7dc8 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -54,7 +54,8 @@ export default defineComponent({ }, data: function () { return { - visible: false + visible: false, + display: 'block' } }, computed: { @@ -88,6 +89,8 @@ export default defineComponent({ onVisibilityChanged: function (visible) { if (visible && this.shouldBeVisible) { this.visible = visible + } else if (visible) { + this.display = 'none' } } } diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.vue b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.vue index 590ca9e78e76a..5bb073ea2a271 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.vue +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.vue @@ -4,6 +4,7 @@ callback: onVisibilityChanged, once: true, }" + :style="{ display }" > Date: Mon, 20 Nov 2023 20:38:40 -0600 Subject: [PATCH 07/13] Rename variables to better match non-video-specific function, and remove blocks from History and videos in playlists --- .../distraction-settings/distraction-settings.js | 10 +++++----- .../distraction-settings/distraction-settings.vue | 4 ++-- .../ft-community-post/ft-community-post.js | 8 ++++---- .../components/ft-element-list/ft-element-list.js | 2 +- .../components/ft-element-list/ft-element-list.vue | 2 +- .../ft-list-lazy-wrapper/ft-list-lazy-wrapper.js | 10 +++++----- .../ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue | 2 +- .../ft-list-video-lazy/ft-list-video-lazy.js | 8 ++++---- src/renderer/store/modules/settings.js | 2 +- src/renderer/views/History/History.vue | 1 + src/renderer/views/Playlist/Playlist.vue | 1 + src/renderer/views/UserPlaylists/UserPlaylists.vue | 1 + src/renderer/views/Watch/Watch.js | 12 ++++++------ static/locales/en-US.yaml | 2 +- 14 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/renderer/components/distraction-settings/distraction-settings.js b/src/renderer/components/distraction-settings/distraction-settings.js index 66fb98321fde1..a540b94bde48b 100644 --- a/src/renderer/components/distraction-settings/distraction-settings.js +++ b/src/renderer/components/distraction-settings/distraction-settings.js @@ -120,8 +120,8 @@ export default defineComponent({ return ch }) }, - forbiddenVideoTitleText: function() { - return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + forbiddenTitles: function() { + return JSON.parse(this.$store.getters.getForbiddenTitles) }, hideSubscriptionsLiveTooltip: function () { return this.$t('Tooltips.Distraction Free Settings.Hide Subscriptions Live', { @@ -151,8 +151,8 @@ export default defineComponent({ handleChannelsHidden: function (value) { this.updateChannelsHidden(JSON.stringify(value)) }, - handleForbiddenVideoTitleText: function (value) { - this.updateForbiddenVideoTitleText(JSON.stringify(value)) + handleForbiddenTitles: function (value) { + this.updateForbiddenTitles(JSON.stringify(value)) }, handleChannelsExists: function () { showToast(this.$t('Settings.Distraction Free Settings.Hide Channels Already Exists')) @@ -212,7 +212,7 @@ export default defineComponent({ 'updateHideSharingActions', 'updateHideChapters', 'updateChannelsHidden', - 'updateForbiddenVideoTitleText', + 'updateForbiddenTitles', 'updateShowDistractionFreeTitles', 'updateHideFeaturedChannels', 'updateHideChannelShorts', diff --git a/src/renderer/components/distraction-settings/distraction-settings.vue b/src/renderer/components/distraction-settings/distraction-settings.vue index a5b5db4e3fd9e..6420d447c8916 100644 --- a/src/renderer/components/distraction-settings/distraction-settings.vue +++ b/src/renderer/components/distraction-settings/distraction-settings.vue @@ -251,10 +251,10 @@ :label="$t('Settings.Distraction Free Settings.Hide Videos and Playlists Containing Text')" :tag-name-placeholder="$t('Settings.Distraction Free Settings.Hide Videos and Playlists Containing Text Placeholder')" :show-action-button="true" - :tag-list="forbiddenVideoTitleText" + :tag-list="forbiddenTitles" :min-input-length="3" :tooltip="$t('Tooltips.Distraction Free Settings.Hide Videos and Playlists Containing Text')" - @change="handleForbiddenVideoTitleText" + @change="handleForbiddenTitles" /> diff --git a/src/renderer/components/ft-community-post/ft-community-post.js b/src/renderer/components/ft-community-post/ft-community-post.js index 58a686f5c2ecf..a0554f4d2fe40 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.js +++ b/src/renderer/components/ft-community-post/ft-community-post.js @@ -28,7 +28,7 @@ export default defineComponent({ type: String, required: true }, - hideVideosWithForbiddenTextInTitle: { + hideForbiddenTitles: { type: Boolean, default: true } @@ -63,12 +63,12 @@ export default defineComponent({ return this.$store.getters.getListType }, - forbiddenVideoTitleText() { - return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + forbiddenTitles() { + return JSON.parse(this.$store.getters.getForbiddenTitles) }, hideVideo() { - return this.forbiddenVideoTitleText.some((text) => this.data.postContent.content.title?.toLowerCase().includes(text.toLowerCase())) + return this.forbiddenTitles.some((text) => this.data.postContent.content.title?.toLowerCase().includes(text.toLowerCase())) } }, created: function () { diff --git a/src/renderer/components/ft-element-list/ft-element-list.js b/src/renderer/components/ft-element-list/ft-element-list.js index f72df0bdedf00..57f1ffe27208c 100644 --- a/src/renderer/components/ft-element-list/ft-element-list.js +++ b/src/renderer/components/ft-element-list/ft-element-list.js @@ -26,7 +26,7 @@ export default defineComponent({ type: Boolean, default: true, }, - hideVideosWithForbiddenTextInTitle: { + hideForbiddenTitles: { type: Boolean, default: true } diff --git a/src/renderer/components/ft-element-list/ft-element-list.vue b/src/renderer/components/ft-element-list/ft-element-list.vue index 6585ae2ecd319..5f9de1ee13494 100644 --- a/src/renderer/components/ft-element-list/ft-element-list.vue +++ b/src/renderer/components/ft-element-list/ft-element-list.vue @@ -11,7 +11,7 @@ :layout="displayValue" :show-video-with-last-viewed-playlist="showVideoWithLastViewedPlaylist" :use-channels-hidden-preference="useChannelsHiddenPreference" - :hide-videos-with-forbidden-text-in-title="hideVideosWithForbiddenTextInTitle" + :hide-forbidden-titles="hideForbiddenTitles" /> diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js index f405041c2ef79..3508e629026f0 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -39,7 +39,7 @@ export default defineComponent({ type: Boolean, default: true, }, - hideVideosWithForbiddenTextInTitle: { + hideForbiddenTitles: { type: Boolean, default: true }, @@ -65,8 +65,8 @@ export default defineComponent({ return ch }) }, - forbiddenVideoTitleText: function() { - return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + forbiddenTitles: function() { + return JSON.parse(this.$store.getters.getForbiddenTitles) }, hideUpcomingPremieres: function () { return this.$store.getters.getHideUpcomingPremieres @@ -104,7 +104,7 @@ export default defineComponent({ // hide videos by author return false } - if (this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { + if (this.forbiddenTitles.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { return false } } else if (data.type === 'channel') { @@ -122,7 +122,7 @@ export default defineComponent({ return false } } else if (data.type === 'playlist') { - if (this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { + if (this.forbiddenTitles.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) { return false } const attrsToCheck = [ diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue index 471ec0b9a22e8..1a3ba4c34a428 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue @@ -31,7 +31,7 @@ /> diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index 20f8ad7ae7dc8..e3963b290704b 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -47,7 +47,7 @@ export default defineComponent({ type: Boolean, default: false, }, - hideVideosWithForbiddenTextInTitle: { + hideForbiddenTitles: { type: Boolean, default: true } @@ -72,14 +72,14 @@ export default defineComponent({ }) }, - forbiddenVideoTitleText() { - return JSON.parse(this.$store.getters.getForbiddenVideoTitleText) + forbiddenTitles() { + return JSON.parse(this.$store.getters.getForbiddenTitles) }, shouldBeVisible() { return !(this.channelsHidden.some(ch => ch.name === this.data.authorId) || this.channelsHidden.some(ch => ch.name === this.data.author) || - this.forbiddenVideoTitleText.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) + this.forbiddenTitles.some((text) => this.data.title?.toLowerCase().includes(text.toLowerCase()))) } }, created() { diff --git a/src/renderer/store/modules/settings.js b/src/renderer/store/modules/settings.js index 582d9eead1d44..29b926c1bee74 100644 --- a/src/renderer/store/modules/settings.js +++ b/src/renderer/store/modules/settings.js @@ -204,7 +204,7 @@ const state = { hideComments: false, hideFeaturedChannels: false, channelsHidden: '[]', - forbiddenVideoTitleText: '[]', + forbiddenTitles: '[]', hideVideoDescription: false, hideLiveChat: false, hideLiveStreams: false, diff --git a/src/renderer/views/History/History.vue b/src/renderer/views/History/History.vue index 25a0758ca9274..5050b50117e3c 100644 --- a/src/renderer/views/History/History.vue +++ b/src/renderer/views/History/History.vue @@ -37,6 +37,7 @@ :data="activeData" :show-video-with-last-viewed-playlist="true" :use-channels-hidden-preference="false" + :hide-forbidden-titles="false" /> diff --git a/src/renderer/views/UserPlaylists/UserPlaylists.vue b/src/renderer/views/UserPlaylists/UserPlaylists.vue index 1fb061fbf6c7c..965e61d00cc02 100644 --- a/src/renderer/views/UserPlaylists/UserPlaylists.vue +++ b/src/renderer/views/UserPlaylists/UserPlaylists.vue @@ -43,6 +43,7 @@ v-if="activeData.length > 0 && !isLoading" :data="activeData" :use-channels-hidden-preference="false" + :hide-forbidden-titles="false" /> - !this.isHiddenVideo(forbiddenVideoTitleText, channelsHidden, video) + !this.isHiddenVideo(forbiddenTitles, channelsHidden, video) )?.videoId if (!nextVideoId) { return @@ -1727,10 +1727,10 @@ export default defineComponent({ document.title = `${this.videoTitle} - FreeTube` }, - isHiddenVideo: function (forbiddenVideoTitleText, channelsHidden, video) { + isHiddenVideo: function (forbiddenTitles, channelsHidden, video) { return channelsHidden.some(ch => ch.name === video.authorId) || channelsHidden.some(ch => ch.name === video.author) || - forbiddenVideoTitleText.some((text) => video.title?.toLowerCase().includes(text.toLowerCase())) + forbiddenTitles.some((text) => video.title?.toLowerCase().includes(text.toLowerCase())) }, ...mapActions([ diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 113a011fefab5..da0c11efa3fbf 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -880,7 +880,7 @@ Tooltips: Hide Channels: Enter a channel ID to hide all videos, playlists and the channel itself from appearing in search, trending, most popular and recommended. The channel ID entered must be a complete match and is case sensitive. Hide Subscriptions Live: 'This setting is overridden by the app-wide "{appWideSetting}" setting, in the "{subsection}" section of the "{settingsSection}"' - Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it throughout all of FreeTube. + Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it throughout all of FreeTube, excluding only History and videos inside of playlists. Subscription Settings: Fetch Feeds from RSS: When enabled, FreeTube will use RSS instead of its default method for grabbing your subscription feed. RSS is faster and prevents IP blocking, From 6d0833788411194be9c12099203bad6d1a7d97ce Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Tue, 21 Nov 2023 17:59:12 -0600 Subject: [PATCH 08/13] Fix to respect hideForbiddenTitles value --- src/renderer/components/ft-community-post/ft-community-post.js | 1 + .../components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js | 1 + src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js | 1 + .../components/watch-video-playlist/watch-video-playlist.vue | 1 + 4 files changed, 4 insertions(+) diff --git a/src/renderer/components/ft-community-post/ft-community-post.js b/src/renderer/components/ft-community-post/ft-community-post.js index a0554f4d2fe40..9eeba1859329e 100644 --- a/src/renderer/components/ft-community-post/ft-community-post.js +++ b/src/renderer/components/ft-community-post/ft-community-post.js @@ -64,6 +64,7 @@ export default defineComponent({ }, forbiddenTitles() { + if (!this.hideForbiddenTitles) { return [] } return JSON.parse(this.$store.getters.getForbiddenTitles) }, diff --git a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js index 3508e629026f0..d32f6d90a723e 100644 --- a/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js +++ b/src/renderer/components/ft-list-lazy-wrapper/ft-list-lazy-wrapper.js @@ -66,6 +66,7 @@ export default defineComponent({ }) }, forbiddenTitles: function() { + if (!this.hideForbiddenTitles) { return [] } return JSON.parse(this.$store.getters.getForbiddenTitles) }, hideUpcomingPremieres: function () { diff --git a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js index e3963b290704b..1df86efa713f0 100644 --- a/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js +++ b/src/renderer/components/ft-list-video-lazy/ft-list-video-lazy.js @@ -73,6 +73,7 @@ export default defineComponent({ }, forbiddenTitles() { + if (!this.hideForbiddenTitles) { return [] } return JSON.parse(this.$store.getters.getForbiddenTitles) }, diff --git a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue index 57050e0c03b62..20a2a87ad10e5 100644 --- a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue +++ b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue @@ -138,6 +138,7 @@ :playlist-reverse="reversePlaylist" :playlist-shuffle="shuffleEnabled" :playlist-loop="loopEnabled" + :hide-forbidden-titles="false" appearance="watchPlaylistItem" force-list-type="list" :initial-visible-state="index < ((currentVideoIndex - 1) + 4) && index > ((currentVideoIndex - 1) - 4)" From b9bc0000c6f9f6eb831753acc43871b9a9b248e4 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Thu, 23 Nov 2023 06:53:19 -0600 Subject: [PATCH 09/13] Modify label --- static/locales/en-US.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index da0c11efa3fbf..df86e80446047 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -880,7 +880,7 @@ Tooltips: Hide Channels: Enter a channel ID to hide all videos, playlists and the channel itself from appearing in search, trending, most popular and recommended. The channel ID entered must be a complete match and is case sensitive. Hide Subscriptions Live: 'This setting is overridden by the app-wide "{appWideSetting}" setting, in the "{subsection}" section of the "{settingsSection}"' - Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it throughout all of FreeTube, excluding only History and videos inside of playlists. + Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it throughout all of FreeTube, excluding only History, Your Playlists, and videos inside of playlists. Subscription Settings: Fetch Feeds from RSS: When enabled, FreeTube will use RSS instead of its default method for grabbing your subscription feed. RSS is faster and prevents IP blocking, From 44a7a0c24741c0d7d33109a6a424fcfe05ea92b9 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Fri, 24 Nov 2023 14:38:34 -0600 Subject: [PATCH 10/13] Clarify restriction affecting original titles --- static/locales/en-US.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index df86e80446047..bc2190bff4046 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -880,7 +880,7 @@ Tooltips: Hide Channels: Enter a channel ID to hide all videos, playlists and the channel itself from appearing in search, trending, most popular and recommended. The channel ID entered must be a complete match and is case sensitive. Hide Subscriptions Live: 'This setting is overridden by the app-wide "{appWideSetting}" setting, in the "{subsection}" section of the "{settingsSection}"' - Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists with titles containing it throughout all of FreeTube, excluding only History, Your Playlists, and videos inside of playlists. + Hide Videos and Playlists Containing Text: Enter a word, word fragment, or phrase (case insensitive) to hide all videos & playlists whose original titles contain it throughout all of FreeTube, excluding only History, Your Playlists, and videos inside of playlists. Subscription Settings: Fetch Feeds from RSS: When enabled, FreeTube will use RSS instead of its default method for grabbing your subscription feed. RSS is faster and prevents IP blocking, From 1b4f4aac4081b199644fbdaef462d6f4f16fe24b Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Fri, 24 Nov 2023 21:25:15 -0600 Subject: [PATCH 11/13] Add toast for entered input of length below min input length --- .../components/ft-input-tags/ft-input-tags.js | 7 +++++++ src/renderer/components/ft-input/ft-input.js | 13 ++++++------- static/locales/en-US.yaml | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/renderer/components/ft-input-tags/ft-input-tags.js b/src/renderer/components/ft-input-tags/ft-input-tags.js index 1cf2f71b61e07..de4769f29a0ea 100644 --- a/src/renderer/components/ft-input-tags/ft-input-tags.js +++ b/src/renderer/components/ft-input-tags/ft-input-tags.js @@ -1,5 +1,6 @@ import { defineComponent } from 'vue' import FtInput from '../ft-input/ft-input.vue' +import { showToast } from '../../helpers/utils' export default defineComponent({ name: 'FtInputTags', @@ -60,6 +61,12 @@ export default defineComponent({ } // add tag and update tag list const trimmedText = text.trim() + + if (this.minInputLength > trimmedText.length) { + showToast(this.$tc('Trimmed input must be at least N characters long', this.minInputLength, { length: this.minInputLength })) + return + } + if (!this.tagList.includes(trimmedText)) { const newList = this.tagList.slice(0) newList.push(trimmedText) diff --git a/src/renderer/components/ft-input/ft-input.js b/src/renderer/components/ft-input/ft-input.js index e18cb1c943a85..091b7ee27efde 100644 --- a/src/renderer/components/ft-input/ft-input.js +++ b/src/renderer/components/ft-input/ft-input.js @@ -1,6 +1,7 @@ import { defineComponent } from 'vue' -import FtTooltip from '../ft-tooltip/ft-tooltip.vue' import { mapActions } from 'vuex' + +import FtTooltip from '../ft-tooltip/ft-tooltip.vue' import { isKeyboardEventKeyPrintableChar, isNullOrEmpty } from '../../helpers/strings' export default defineComponent({ @@ -54,10 +55,6 @@ export default defineComponent({ type: Boolean, default: true }, - minInputLength: { - type: Number, - default: 1 - }, dataList: { type: Array, default: () => { return [] } @@ -103,7 +100,7 @@ export default defineComponent({ }, inputDataPresent: function () { - return this.inputData.length >= this.minInputLength + return this.inputData.length > 0 }, inputDataDisplayed() { if (!this.isSearch) { return this.inputData } @@ -147,7 +144,9 @@ export default defineComponent({ methods: { handleClick: function (e) { // No action if no input text - if (!this.inputDataPresent) { return } + if (!this.inputDataPresent) { + return + } this.searchState.showOptions = false this.searchState.selectedOption = -1 diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index bc2190bff4046..842c79fe329eb 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -935,6 +935,7 @@ Screenshot Success: Saved screenshot as "{filePath}" Screenshot Error: Screenshot failed. {error} Channel Hidden: '{channel} added to channel filter' Channel Unhidden: '{channel} removed from channel filter' +Trimmed input must be at least N characters long: Trimmed input must be at least 1 character long | Trimmed input must be at least {length} characters long Hashtag: Hashtag: Hashtag From 0cd02806bb8ae185fd1681ea3bf7e9b0b4e04b12 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 25 Nov 2023 10:15:14 -0600 Subject: [PATCH 12/13] Add toast for element already exists --- src/renderer/components/ft-input-tags/ft-input-tags.js | 4 +++- static/locales/en-US.yaml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/ft-input-tags/ft-input-tags.js b/src/renderer/components/ft-input-tags/ft-input-tags.js index de4769f29a0ea..b56aa98de16be 100644 --- a/src/renderer/components/ft-input-tags/ft-input-tags.js +++ b/src/renderer/components/ft-input-tags/ft-input-tags.js @@ -67,7 +67,9 @@ export default defineComponent({ return } - if (!this.tagList.includes(trimmedText)) { + if (this.tagList.includes(trimmedText)) { + showToast(this.$t('Tag already exists', { tagName: trimmedText })) + } else { const newList = this.tagList.slice(0) newList.push(trimmedText) this.$emit('change', newList) diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 842c79fe329eb..af6085d74d819 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -936,6 +936,7 @@ Screenshot Error: Screenshot failed. {error} Channel Hidden: '{channel} added to channel filter' Channel Unhidden: '{channel} removed from channel filter' Trimmed input must be at least N characters long: Trimmed input must be at least 1 character long | Trimmed input must be at least {length} characters long +Tag already exists: '"{tagName}" tag already exists' Hashtag: Hashtag: Hashtag From 1e4af022ed43e16b27bad9cd5d569a4dfeea07ea Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 25 Nov 2023 18:40:30 -0600 Subject: [PATCH 13/13] Update to not clear if duplicate tag is entered for Hide Forbidden feature --- src/renderer/components/ft-input-tags/ft-input-tags.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/ft-input-tags/ft-input-tags.js b/src/renderer/components/ft-input-tags/ft-input-tags.js index b56aa98de16be..e139db3b76b9e 100644 --- a/src/renderer/components/ft-input-tags/ft-input-tags.js +++ b/src/renderer/components/ft-input-tags/ft-input-tags.js @@ -69,11 +69,12 @@ export default defineComponent({ if (this.tagList.includes(trimmedText)) { showToast(this.$t('Tag already exists', { tagName: trimmedText })) - } else { - const newList = this.tagList.slice(0) - newList.push(trimmedText) - this.$emit('change', newList) + return } + + const newList = this.tagList.slice(0) + newList.push(trimmedText) + this.$emit('change', newList) // clear input box this.$refs.tagNameInput.handleClearTextClick() },