diff --git a/package.json b/package.json index 2755d44535708..5bb25ab620d79 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "autolinker": "^4.1.0", "bgutils-js": "^3.1.2", "electron-context-menu": "^4.0.4", - "lodash.debounce": "^4.0.8", "marked": "^15.0.5", "path-browserify": "^1.0.1", "portal-vue": "^2.1.7", diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index 3bcfd3689bc3d..d7c87dca85d60 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -9,10 +9,10 @@ import { openExternalLink, showToast, toDistractionFreeTitle, - deepCopy + deepCopy, + debounce } from '../../helpers/utils' import { deArrowData, deArrowThumbnail } from '../../helpers/sponsorblock' -import debounce from 'lodash.debounce' import thumbnailPlaceholder from '../../assets/img/thumbnail_placeholder.svg' export default defineComponent({ diff --git a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js index 09fb1a20fcc95..6712635378d7c 100644 --- a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js +++ b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js @@ -1,6 +1,5 @@ import { defineComponent, nextTick } from 'vue' import { mapActions } from 'vuex' -import debounce from 'lodash.debounce' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtPrompt from '../ft-prompt/ft-prompt.vue' import FtButton from '../ft-button/ft-button.vue' @@ -9,6 +8,7 @@ import FtInput from '../../components/ft-input/ft-input.vue' import FtSelect from '../../components/ft-select/ft-select.vue' import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue' import { + debounce, showToast, ctrlFHandler, getIconForSortPreference diff --git a/src/renderer/components/general-settings/general-settings.js b/src/renderer/components/general-settings/general-settings.js index c8e089f3967ac..94734c5ee4686 100644 --- a/src/renderer/components/general-settings/general-settings.js +++ b/src/renderer/components/general-settings/general-settings.js @@ -7,9 +7,8 @@ import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtButton from '../ft-button/ft-button.vue' -import debounce from 'lodash.debounce' import allLocales from '../../../../static/locales/activeLocales.json' -import { randomArrayItem, showToast } from '../../helpers/utils' +import { debounce, randomArrayItem, showToast } from '../../helpers/utils' import { translateWindowTitle } from '../../helpers/strings' export default defineComponent({ diff --git a/src/renderer/components/playlist-info/playlist-info.js b/src/renderer/components/playlist-info/playlist-info.js index 51348d3e9256e..07c7857ce23ab 100644 --- a/src/renderer/components/playlist-info/playlist-info.js +++ b/src/renderer/components/playlist-info/playlist-info.js @@ -8,12 +8,12 @@ import FtPrompt from '../ft-prompt/ft-prompt.vue' import FtButton from '../ft-button/ft-button.vue' import { ctrlFHandler, + debounce, formatNumber, showToast, getTodayDateStrLocalTimezone, writeFileWithPicker, } from '../../helpers/utils' -import debounce from 'lodash.debounce' import thumbnailPlaceholder from '../../assets/img/thumbnail_placeholder.svg' export default defineComponent({ diff --git a/src/renderer/components/proxy-settings/proxy-settings.js b/src/renderer/components/proxy-settings/proxy-settings.js index dcd560f92a454..eefe25063f052 100644 --- a/src/renderer/components/proxy-settings/proxy-settings.js +++ b/src/renderer/components/proxy-settings/proxy-settings.js @@ -8,10 +8,8 @@ import FtInput from '../ft-input/ft-input.vue' import FtLoader from '../ft-loader/ft-loader.vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' -import debounce from 'lodash.debounce' - import { IpcChannels } from '../../../constants' -import { showToast } from '../../helpers/utils' +import { debounce, showToast } from '../../helpers/utils' export default defineComponent({ name: 'ProxySettings', diff --git a/src/renderer/components/top-nav/top-nav.js b/src/renderer/components/top-nav/top-nav.js index 6ed717333c914..f1ec0a5a19d1d 100644 --- a/src/renderer/components/top-nav/top-nav.js +++ b/src/renderer/components/top-nav/top-nav.js @@ -3,10 +3,9 @@ import { mapActions, mapMutations } from 'vuex' import FtInput from '../ft-input/ft-input.vue' import FtProfileSelector from '../ft-profile-selector/ft-profile-selector.vue' import FtIconButton from '../ft-icon-button/ft-icon-button.vue' -import debounce from 'lodash.debounce' import { IpcChannels, KeyboardShortcuts, MIXED_SEARCH_HISTORY_ENTRIES_DISPLAY_LIMIT, MOBILE_WIDTH_THRESHOLD, SEARCH_RESULTS_DISPLAY_LIMIT } from '../../../constants' -import { localizeAndAddKeyboardShortcutToActionTitle, openInternalPath } from '../../helpers/utils' +import { debounce, localizeAndAddKeyboardShortcutToActionTitle, openInternalPath } from '../../helpers/utils' import { translateWindowTitle } from '../../helpers/strings' import { clearLocalSearchSuggestionsSession, getLocalSearchSuggestions } from '../../helpers/api/local' import { getInvidiousSearchSuggestions } from '../../helpers/api/invidious' diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 791772003fb7e..97b60c8798bda 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -1030,3 +1030,27 @@ export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle const localizedShortcut = getLocalizedShortcut(unlocalizedShortcut) return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcut) } + +/** + * @template {Function} T + * @param {T} func + * @param {number} wait + * @returns {T} + */ +export function debounce(func, wait) { + let timeout + + // Using a fully fledged function here instead of an arrow function + // so that we can get `this` and pass it onto the original function. + // Vue components using options API use `this` alot. + return function (...args) { + const context = this + + clearTimeout(timeout) + + timeout = setTimeout(() => { + timeout = null + func.apply(context, args) + }, wait) + } +} diff --git a/src/renderer/views/History/History.js b/src/renderer/views/History/History.js index 1613eb1998f15..54eb8f4541572 100644 --- a/src/renderer/views/History/History.js +++ b/src/renderer/views/History/History.js @@ -1,6 +1,5 @@ import { defineComponent } from 'vue' import { isNavigationFailure, NavigationFailureType } from 'vue-router' -import debounce from 'lodash.debounce' import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtCard from '../../components/ft-card/ft-card.vue' import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' @@ -9,7 +8,7 @@ import FtButton from '../../components/ft-button/ft-button.vue' import FtInput from '../../components/ft-input/ft-input.vue' import FtAutoLoadNextPageWrapper from '../../components/ft-auto-load-next-page-wrapper/ft-auto-load-next-page-wrapper.vue' import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue' -import { ctrlFHandler } from '../../helpers/utils' +import { ctrlFHandler, debounce } from '../../helpers/utils' const identity = (v) => v diff --git a/src/renderer/views/Playlist/Playlist.js b/src/renderer/views/Playlist/Playlist.js index e671f5363e1da..42b42d59605fa 100644 --- a/src/renderer/views/Playlist/Playlist.js +++ b/src/renderer/views/Playlist/Playlist.js @@ -1,6 +1,5 @@ import { defineComponent, nextTick } from 'vue' import { mapActions, mapMutations } from 'vuex' -import debounce from 'lodash.debounce' import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtCard from '../../components/ft-card/ft-card.vue' import PlaylistInfo from '../../components/playlist-info/playlist-info.vue' @@ -16,6 +15,7 @@ import { parseLocalPlaylistVideo, } from '../../helpers/api/local' import { + debounce, extractNumberFromString, getIconForSortPreference, showToast, diff --git a/src/renderer/views/SubscribedChannels/SubscribedChannels.vue b/src/renderer/views/SubscribedChannels/SubscribedChannels.vue index 2a93d4af38890..48ad30d0a24d8 100644 --- a/src/renderer/views/SubscribedChannels/SubscribedChannels.vue +++ b/src/renderer/views/SubscribedChannels/SubscribedChannels.vue @@ -84,10 +84,9 @@ import FtInput from '../../components/ft-input/ft-input.vue' import FtSubscribeButton from '../../components/FtSubscribeButton/FtSubscribeButton.vue' import { invidiousGetChannelInfo, youtubeImageUrlToInvidious, invidiousImageUrlToInvidious } from '../../helpers/api/invidious' import { getLocalChannel, parseLocalChannelHeader } from '../../helpers/api/local' -import { ctrlFHandler } from '../../helpers/utils' +import { ctrlFHandler, debounce } from '../../helpers/utils' import { useI18n } from '../../composables/use-i18n-polyfill.js' import store from '../../store/index' -import debounce from 'lodash.debounce' const route = useRoute() const router = useRouter() diff --git a/src/renderer/views/UserPlaylists/UserPlaylists.js b/src/renderer/views/UserPlaylists/UserPlaylists.js index 25deadd856017..a64225ba91a43 100644 --- a/src/renderer/views/UserPlaylists/UserPlaylists.js +++ b/src/renderer/views/UserPlaylists/UserPlaylists.js @@ -1,6 +1,5 @@ import { defineComponent } from 'vue' import { mapActions } from 'vuex' -import debounce from 'lodash.debounce' import FtCard from '../../components/ft-card/ft-card.vue' import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue' import FtTooltip from '../../components/ft-tooltip/ft-tooltip.vue' @@ -12,7 +11,7 @@ import FtInput from '../../components/ft-input/ft-input.vue' import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue' import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue' import FtAutoLoadNextPageWrapper from '../../components/ft-auto-load-next-page-wrapper/ft-auto-load-next-page-wrapper.vue' -import { ctrlFHandler, getIconForSortPreference } from '../../helpers/utils' +import { ctrlFHandler, debounce, getIconForSortPreference } from '../../helpers/utils' import { isNavigationFailure, NavigationFailureType } from 'vue-router' const SORT_BY_VALUES = {