From a7cfd3d9d983c37f1a44dd482d7ae5ff218cdaad Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:45:27 -0700 Subject: [PATCH 1/2] Simplify channel sorting functions --- .../ft-profile-channel-list.js | 40 +++++++------------ .../ft-profile-filter-channels-list.js | 15 +++---- .../ft-video-player/ft-video-player.js | 6 +-- src/renderer/components/side-nav/side-nav.js | 13 ++---- src/renderer/store/modules/profiles.js | 9 +++-- .../SubscribedChannels/SubscribedChannels.js | 2 +- 6 files changed, 33 insertions(+), 52 deletions(-) diff --git a/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js b/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js index 799251819e437..f26eecc1a7675 100644 --- a/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js +++ b/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js @@ -64,48 +64,38 @@ export default defineComponent({ this.$t('Yes'), this.$t('No') ] - } + }, + locale: function () { + return this.$i18n.locale.replace('_', '-') + }, }, watch: { profile: function () { - this.subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { - const nameA = a.name.toLowerCase() - const nameB = b.name.toLowerCase() - if (nameA < nameB) { - return -1 - } - if (nameA > nameB) { - return 1 - } - return 0 - }).map((channel) => { + const subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) + }) + subscriptions.forEach((channel) => { if (this.backendPreference === 'invidious') { channel.thumbnail = youtubeImageUrlToInvidious(channel.thumbnail, this.currentInvidiousInstance) } channel.selected = false - return channel }) + + this.subscriptions = subscriptions } }, mounted: function () { if (typeof this.profile.subscriptions !== 'undefined') { - this.subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { - const nameA = a.name.toLowerCase() - const nameB = b.name.toLowerCase() - if (nameA < nameB) { - return -1 - } - if (nameA > nameB) { - return 1 - } - return 0 - }).map((channel) => { + const subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) + }) + subscriptions.forEach((channel) => { if (this.backendPreference === 'invidious') { channel.thumbnail = youtubeImageUrlToInvidious(channel.thumbnail, this.currentInvidiousInstance) } channel.selected = false - return channel }) + this.subscriptions = subscriptions } }, methods: { diff --git a/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js b/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js index ece62f7ac5218..6f878aed8ae1a 100644 --- a/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js +++ b/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js @@ -46,7 +46,10 @@ export default defineComponent({ }, selectedText: function () { return this.$t('Profile.{number} selected', { number: this.selectedLength }) - } + }, + locale: function () { + return this.$i18n.locale.replace('_', '-') + }, }, watch: { profile: 'updateChannelList', @@ -55,15 +58,7 @@ export default defineComponent({ mounted: function () { if (typeof this.profile.subscriptions !== 'undefined') { this.channels = JSON.parse(JSON.stringify(this.profileList[this.filteredProfileIndex].subscriptions)).sort((a, b) => { - const nameA = a.name.toLowerCase() - const nameB = b.name.toLowerCase() - if (nameA < nameB) { - return -1 - } - if (nameA > nameB) { - return 1 - } - return 0 + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }).filter((channel) => { const index = this.profile.subscriptions.findIndex((sub) => { return sub.id === channel.id 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 365237a0176d1..f0271f264d978 100644 --- a/src/renderer/components/ft-video-player/ft-video-player.js +++ b/src/renderer/components/ft-video-player/ft-video-player.js @@ -179,7 +179,7 @@ export default defineComponent({ }, computed: { currentLocale: function () { - return this.$i18n.locale + return this.$i18n.locale.replace('_', '-') }, defaultPlayback: function () { @@ -1755,7 +1755,7 @@ export default defineComponent({ const bCode = captionB.language_code.split('-') const aName = (captionA.label) // ex: english (auto-generated) const bName = (captionB.label) - const userLocale = this.currentLocale.split(/-|_/) // ex. [en,US] + const userLocale = this.currentLocale.split('-') // ex. [en,US] if (aCode[0] === userLocale[0]) { // caption a has same language as user's locale if (bCode[0] === userLocale[0]) { // caption b has same language as user's locale if (bName.search('auto') !== -1) { @@ -1786,7 +1786,7 @@ export default defineComponent({ return 1 } // sort alphabetically - return aName.localeCompare(bName) + return aName.localeCompare(bName, this.currentLocale) }) }, diff --git a/src/renderer/components/side-nav/side-nav.js b/src/renderer/components/side-nav/side-nav.js index 967b6b5e9cfd7..b0d355ad42f07 100644 --- a/src/renderer/components/side-nav/side-nav.js +++ b/src/renderer/components/side-nav/side-nav.js @@ -28,19 +28,14 @@ export default defineComponent({ activeProfile: function () { return this.$store.getters.getActiveProfile }, + locale: function () { + return this.$i18n.locale.replace('_', '-') + }, activeSubscriptions: function () { const subscriptions = JSON.parse(JSON.stringify(this.activeProfile.subscriptions)) subscriptions.sort((a, b) => { - const nameA = a.name.toLowerCase() - const nameB = b.name.toLowerCase() - if (nameA < nameB) { - return -1 - } - if (nameA > nameB) { - return 1 - } - return 0 + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }) if (this.backendPreference === 'invidious') { diff --git a/src/renderer/store/modules/profiles.js b/src/renderer/store/modules/profiles.js index 55069a19a5717..8e0b699f118f6 100644 --- a/src/renderer/store/modules/profiles.js +++ b/src/renderer/store/modules/profiles.js @@ -100,13 +100,14 @@ const actions = { }) ?? null if (channel === null) { continue } let updated = false - if (channel.name !== channelName || (channel.thumbnail !== thumbnail && thumbnail !== null)) { - if (thumbnail !== null) { - channel.thumbnail = thumbnail - } + if (channel.name !== channelName && channelName != null) { channel.name = channelName updated = true } + if (channel.thumbnail !== thumbnail && thumbnail != null) { + channel.thumbnail = thumbnail + updated = true + } if (updated) { await dispatch('updateProfile', currentProfileCopy) } else { // channel has not been updated, stop iterating through profiles diff --git a/src/renderer/views/SubscribedChannels/SubscribedChannels.js b/src/renderer/views/SubscribedChannels/SubscribedChannels.js index 0ca0ebe39a5a6..0022240632d9e 100644 --- a/src/renderer/views/SubscribedChannels/SubscribedChannels.js +++ b/src/renderer/views/SubscribedChannels/SubscribedChannels.js @@ -83,7 +83,7 @@ export default defineComponent({ methods: { getSubscription: function () { this.subscribedChannels = this.activeSubscriptionList.slice().sort((a, b) => { - return a.name.localeCompare(b.name, this.locale) + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }) }, From 6308a2b87cf77e9b4b8a38e79d2a20100a240682 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Mon, 14 Aug 2023 19:09:13 -0700 Subject: [PATCH 2/2] use deepCopy --- .../components/data-settings/data-settings.js | 5 +++-- .../ft-profile-channel-list.js | 10 +++++----- .../ft-profile-filter-channels-list.js | 18 +++++------------- .../ft-subscribe-button/ft-subscribe-button.js | 10 +++++----- src/renderer/components/side-nav/side-nav.js | 3 ++- src/renderer/helpers/utils.js | 9 +++++++++ src/renderer/store/modules/profiles.js | 3 ++- src/renderer/store/modules/subscriptions.js | 6 ++---- 8 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/renderer/components/data-settings/data-settings.js b/src/renderer/components/data-settings/data-settings.js index da11301b82a3c..6e8ec6c3df723 100644 --- a/src/renderer/components/data-settings/data-settings.js +++ b/src/renderer/components/data-settings/data-settings.js @@ -9,6 +9,7 @@ import { MAIN_PROFILE_ID } from '../../../constants' import { calculateColorLuminance, getRandomColor } from '../../helpers/colors' import { copyToClipboard, + deepCopy, escapeHTML, getTodayDateStrLocalTimezone, readFileFromDialog, @@ -69,7 +70,7 @@ export default defineComponent({ ] }, primaryProfile: function () { - return JSON.parse(JSON.stringify(this.profileList[0])) + return deepCopy(this.profileList[0]) } }, methods: { @@ -174,7 +175,7 @@ export default defineComponent({ }) if (existingProfileIndex !== -1) { - const existingProfile = JSON.parse(JSON.stringify(this.profileList[existingProfileIndex])) + const existingProfile = deepCopy(this.profileList[existingProfileIndex]) existingProfile.subscriptions = existingProfile.subscriptions.concat(profileObject.subscriptions) existingProfile.subscriptions = existingProfile.subscriptions.filter((sub, index) => { const profileIndex = existingProfile.subscriptions.findIndex((x) => { diff --git a/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js b/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js index f26eecc1a7675..971382b0f0398 100644 --- a/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js +++ b/src/renderer/components/ft-profile-channel-list/ft-profile-channel-list.js @@ -6,7 +6,7 @@ import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue' import FtButton from '../../components/ft-button/ft-button.vue' import FtPrompt from '../../components/ft-prompt/ft-prompt.vue' -import { showToast } from '../../helpers/utils' +import { deepCopy, showToast } from '../../helpers/utils' import { youtubeImageUrlToInvidious } from '../../helpers/api/invidious' export default defineComponent({ @@ -71,7 +71,7 @@ export default defineComponent({ }, watch: { profile: function () { - const subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { + const subscriptions = deepCopy(this.profile.subscriptions).sort((a, b) => { return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }) subscriptions.forEach((channel) => { @@ -86,7 +86,7 @@ export default defineComponent({ }, mounted: function () { if (typeof this.profile.subscriptions !== 'undefined') { - const subscriptions = JSON.parse(JSON.stringify(this.profile.subscriptions)).sort((a, b) => { + const subscriptions = deepCopy(this.profile.subscriptions).sort((a, b) => { return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }) subscriptions.forEach((channel) => { @@ -119,7 +119,7 @@ export default defineComponent({ }) this.profileList.forEach((x) => { - const profile = JSON.parse(JSON.stringify(x)) + const profile = deepCopy(x) profile.subscriptions = profile.subscriptions.filter((channel) => { const index = channelsToRemove.findIndex((y) => { return y.id === channel.id @@ -133,7 +133,7 @@ export default defineComponent({ showToast(this.$t('Profile.Profile has been updated')) this.selectNone() } else { - const profile = JSON.parse(JSON.stringify(this.profile)) + const profile = deepCopy(this.profile) this.subscriptions = this.subscriptions.filter((channel) => { return !channel.selected diff --git a/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js b/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js index 6f878aed8ae1a..aecb99f49ebb6 100644 --- a/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js +++ b/src/renderer/components/ft-profile-filter-channels-list/ft-profile-filter-channels-list.js @@ -6,7 +6,7 @@ import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtChannelBubble from '../../components/ft-channel-bubble/ft-channel-bubble.vue' import FtButton from '../../components/ft-button/ft-button.vue' import FtSelect from '../ft-select/ft-select.vue' -import { showToast } from '../../helpers/utils' +import { deepCopy, showToast } from '../../helpers/utils' import { youtubeImageUrlToInvidious } from '../../helpers/api/invidious' export default defineComponent({ @@ -57,7 +57,7 @@ export default defineComponent({ }, mounted: function () { if (typeof this.profile.subscriptions !== 'undefined') { - this.channels = JSON.parse(JSON.stringify(this.profileList[this.filteredProfileIndex].subscriptions)).sort((a, b) => { + this.channels = deepCopy(this.profileList[this.filteredProfileIndex].subscriptions).sort((a, b) => { return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }).filter((channel) => { const index = this.profile.subscriptions.findIndex((sub) => { @@ -76,16 +76,8 @@ export default defineComponent({ }, methods: { updateChannelList () { - this.channels = JSON.parse(JSON.stringify(this.profileList[this.filteredProfileIndex].subscriptions)).sort((a, b) => { - const nameA = a.name.toLowerCase() - const nameB = b.name.toLowerCase() - if (nameA < nameB) { - return -1 - } - if (nameA > nameB) { - return 1 - } - return 0 + this.channels = deepCopy(this.profileList[this.filteredProfileIndex].subscriptions).sort((a, b) => { + return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) }).filter((channel) => { const index = this.profile.subscriptions.findIndex((sub) => { return sub.id === channel.id @@ -120,7 +112,7 @@ export default defineComponent({ return channel.selected }) - const profile = JSON.parse(JSON.stringify(this.profile)) + const profile = deepCopy(this.profile) profile.subscriptions = profile.subscriptions.concat(subscriptions) this.updateProfile(profile) showToast(this.$t('Profile.Profile has been updated')) diff --git a/src/renderer/components/ft-subscribe-button/ft-subscribe-button.js b/src/renderer/components/ft-subscribe-button/ft-subscribe-button.js index 270715369b708..ba07a6a4a9547 100644 --- a/src/renderer/components/ft-subscribe-button/ft-subscribe-button.js +++ b/src/renderer/components/ft-subscribe-button/ft-subscribe-button.js @@ -5,7 +5,7 @@ import { mapActions } from 'vuex' import FtButton from '../../components/ft-button/ft-button.vue' import { MAIN_PROFILE_ID } from '../../../constants' -import { showToast } from '../../helpers/utils' +import { deepCopy, showToast } from '../../helpers/utils' export default defineComponent({ name: 'FtSubscribeButton', @@ -69,7 +69,7 @@ export default defineComponent({ return } - const currentProfile = JSON.parse(JSON.stringify(this.activeProfile)) + const currentProfile = deepCopy(this.activeProfile) if (this.isSubscribed) { currentProfile.subscriptions = currentProfile.subscriptions.filter((channel) => { @@ -108,9 +108,9 @@ export default defineComponent({ showToast(this.$t('Channel.Added channel to your subscriptions')) if (this.activeProfile._id !== MAIN_PROFILE_ID) { - const primaryProfile = JSON.parse(JSON.stringify(this.profileList.find(prof => { + const primaryProfile = deepCopy(this.profileList.find(prof => { return prof._id === MAIN_PROFILE_ID - }))) + })) const index = primaryProfile.subscriptions.findIndex((channel) => { return channel.id === this.channelId @@ -125,7 +125,7 @@ export default defineComponent({ }, unsubscribe: function(profile, channelId) { - const parsedProfile = JSON.parse(JSON.stringify(profile)) + const parsedProfile = deepCopy(profile) const index = parsedProfile.subscriptions.findIndex((channel) => { return channel.id === channelId }) diff --git a/src/renderer/components/side-nav/side-nav.js b/src/renderer/components/side-nav/side-nav.js index b0d355ad42f07..76adcbfd581b3 100644 --- a/src/renderer/components/side-nav/side-nav.js +++ b/src/renderer/components/side-nav/side-nav.js @@ -2,6 +2,7 @@ import { defineComponent } from 'vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import SideNavMoreOptions from '../side-nav-more-options/side-nav-more-options.vue' import { youtubeImageUrlToInvidious } from '../../helpers/api/invidious' +import { deepCopy } from '../../helpers/utils' export default defineComponent({ name: 'SideNav', @@ -32,7 +33,7 @@ export default defineComponent({ return this.$i18n.locale.replace('_', '-') }, activeSubscriptions: function () { - const subscriptions = JSON.parse(JSON.stringify(this.activeProfile.subscriptions)) + const subscriptions = deepCopy(this.activeProfile.subscriptions) subscriptions.sort((a, b) => { return a.name?.toLowerCase().localeCompare(b.name?.toLowerCase(), this.locale) diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 7decc6613a9c6..b3bda444f9b61 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -656,3 +656,12 @@ export function escapeHTML(untrusted) { .replaceAll('"', '"') .replaceAll('\'', ''') } + +/** + * Performs a deep copy of a javascript object + * @param {Object} obj + * @returns {Object} + */ +export function deepCopy(obj) { + return JSON.parse(JSON.stringify(obj)) +} diff --git a/src/renderer/store/modules/profiles.js b/src/renderer/store/modules/profiles.js index 8e0b699f118f6..3ee50d7d48b48 100644 --- a/src/renderer/store/modules/profiles.js +++ b/src/renderer/store/modules/profiles.js @@ -1,6 +1,7 @@ import { MAIN_PROFILE_ID } from '../../../constants' import { DBProfileHandlers } from '../../../datastores/handlers/index' import { calculateColorLuminance, getRandomColor } from '../../helpers/colors' +import { deepCopy } from '../../helpers/utils' const state = { profileList: [{ @@ -94,7 +95,7 @@ const actions = { const thumbnail = channelThumbnailUrl?.replace(/=s\d*/, '=s176') ?? null // change thumbnail size if different const profileList = getters.getProfileList for (const profile of profileList) { - const currentProfileCopy = JSON.parse(JSON.stringify(profile)) + const currentProfileCopy = deepCopy(profile) const channel = currentProfileCopy.subscriptions.find((channel) => { return channel.id === channelId }) ?? null diff --git a/src/renderer/store/modules/subscriptions.js b/src/renderer/store/modules/subscriptions.js index e9b0c4e1efc71..294ce4bed0efd 100644 --- a/src/renderer/store/modules/subscriptions.js +++ b/src/renderer/store/modules/subscriptions.js @@ -1,11 +1,9 @@ +import { deepCopy } from '../../helpers/utils' + const defaultCacheEntryValueForForOneChannel = { videos: null, } -function deepCopy(obj) { - return JSON.parse(JSON.stringify(obj)) -} - const state = { videoCache: {}, liveCache: {},