From fe5de7fdfa218ffa6d13e49d20a50342eb8b7be2 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 13 Oct 2024 10:13:11 -0500 Subject: [PATCH 01/16] Update title for custom FreeTube button labels with keyboard shortcuts --- src/constants.js | 35 +++++++++++++++++++ .../ft-refresh-widget/ft-refresh-widget.js | 9 +++++ .../ft-refresh-widget/ft-refresh-widget.vue | 2 +- .../player-components/FullWindowButton.js | 14 ++++++-- .../player-components/ScreenshotButton.js | 10 ++++-- .../player-components/StatsButton.js | 14 ++++++-- .../player-components/TheatreModeButton.js | 13 +++++-- src/renderer/components/top-nav/top-nav.js | 17 ++++++--- static/locales/en-US.yaml | 1 + 9 files changed, 100 insertions(+), 15 deletions(-) diff --git a/src/constants.js b/src/constants.js index f45e30fb8211d..79be6c527b3ba 100644 --- a/src/constants.js +++ b/src/constants.js @@ -113,6 +113,40 @@ const SyncEvents = { }, } +const KeyboardShortcuts = { + APP: { + HISTORY_BACKWARD: 'Alt+Left Arrow', + HISTORY_FORWARD: 'Alt+Right Arrow', + NEW_WINDOW: 'Cmd/Ctrl+N' + }, + FEED: { + REFRESH: 'r' + }, + VIDEO_PLAYER: { + SUBTITLES: 'c', + STATS: 'd', + FULLSCREEN: 'f', + PICTURE_IN_PICTURE: 'i', + LARGE_REWIND: 'j', + PLAY: 'k', + LARGE_FAST_FORWARD: 'l', + MUTE: 'm', + DECREASE_VIDEO_SPEED: 'o', + INCREASE_VIDEO_SPEED: 'p', + FULLWINDOW: 's', + THEATRE_MODE: 't', + TAKE_SCREENSHOT: 'u', + VOLUME_UP: 'Up Arrow', + VOLUME_DOWN: 'Down Arrow', + SMALL_REWIND: 'Left Arrow', + SMALL_FAST_FORWARD: 'Right Arrow', + LAST_CHAPTER: 'Cmd/Ctrl+Left Arrow', + NEXT_CHAPTER: 'Cmd/Ctrl+Right Arrow', + LAST_FRAME: ',', + NEXT_FRAME: '.' + }, +} + // Utils const MAIN_PROFILE_ID = 'allChannels' @@ -132,6 +166,7 @@ export { IpcChannels, DBActions, SyncEvents, + KeyboardShortcuts, MAIN_PROFILE_ID, MOBILE_WIDTH_THRESHOLD, PLAYLIST_HEIGHT_FORCE_LIST_THRESHOLD, diff --git a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js index f73e7585ab3e2..75e81e87cb275 100644 --- a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js +++ b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js @@ -1,6 +1,7 @@ import { defineComponent } from 'vue' import FtIconButton from '../ft-icon-button/ft-icon-button.vue' +import { KeyboardShortcuts } from '../../../constants' export default defineComponent({ name: 'FtRefreshWidget', @@ -22,6 +23,14 @@ export default defineComponent({ } }, emits: ['click'], + computed: { + refreshFeedButtonTitle: function() { + return this.$t('KeyboardShortcutTemplate', { + label: this.$t('Feed.Refresh Feed', { subscriptionName: this.title }), + shortcut: KeyboardShortcuts.FEED.REFRESH + }) + } + }, methods: { click: function() { this.$emit('click') diff --git a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.vue b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.vue index 8224711566915..18dadae7709cb 100644 --- a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.vue +++ b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.vue @@ -12,7 +12,7 @@ :disabled="disableRefresh" :icon="['fas', 'sync']" class="refreshButton" - :title="$t('Feed.Refresh Feed', { subscriptionName: title })" + :title="refreshFeedButtonTitle" :size="12" theme="primary" @click="click" diff --git a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js index 2f0db723e3faf..0170a7ca59c42 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js @@ -1,6 +1,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' +import { KeyboardShortcuts } from '../../../../constants' export class FullWindowButton extends shaka.ui.Element { /** @@ -69,10 +70,19 @@ export class FullWindowButton extends shaka.ui.Element { updateLocalisedStrings_() { this.nameSpan_.textContent = i18n.t('Video.Player.Full Window') + this.icon_.textContent = this.fullWindowEnabled_ ? 'close_fullscreen' : 'open_in_full' - this.currentState_.textContent = this.localization.resolve(this.fullWindowEnabled_ ? 'ON' : 'OFF') + this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { + label: this.localization.resolve(this.fullWindowEnabled_ ? 'ON' : 'OFF'), + shortcut: KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW + }) + + const baseAriaLabel = this.fullWindowEnabled_ ? i18n.t('Video.Player.Exit Full Window') : i18n.t('Video.Player.Full Window') - this.button_.ariaLabel = this.fullWindowEnabled_ ? i18n.t('Video.Player.Exit Full Window') : i18n.t('Video.Player.Full Window') + this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { + label: baseAriaLabel, + shortcut: KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW + }) } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js index f9b187cef056e..799777c4dcdc7 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js @@ -1,6 +1,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' +import { KeyboardShortcuts } from '../../../../constants' export class ScreenshotButton extends shaka.ui.Element { /** @@ -49,8 +50,11 @@ export class ScreenshotButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - this.nameSpan_.textContent = i18n.t('Video.Player.Take Screenshot') - - this.button_.ariaLabel = i18n.t('Video.Player.Take Screenshot') + const label = i18n.t('KeyboardShortcutTemplate', { + label: i18n.t('Video.Player.Take Screenshot'), + shortcut: KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT + }) + this.nameSpan_.textContent = label + this.button_.ariaLabel = label } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js index b6f6e8eb7a560..1b15bc232ad06 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js @@ -1,6 +1,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' +import { KeyboardShortcuts } from '../../../../constants' export class StatsButton extends shaka.ui.Element { /** @@ -66,11 +67,18 @@ export class StatsButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { this.nameSpan_.textContent = i18n.t('Video.Player.Stats.Stats') - this.icon_.textContent = this.showStats_ ? 'insert_chart' : 'insert_chart_outlined' - this.currentState_.textContent = this.localization.resolve(this.showStats_ ? 'ON' : 'OFF') + this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { + label: this.localization.resolve(this.showStats_ ? 'ON' : 'OFF'), + shortcut: KeyboardShortcuts.VIDEO_PLAYER.STATS + }) + + const baseAriaLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') - this.button_.ariaLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') + this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { + label: baseAriaLabel, + shortcut: KeyboardShortcuts.VIDEO_PLAYER.STATS + }) } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js index 043e75b4e9d62..352961e8dabb5 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js @@ -1,6 +1,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' +import { KeyboardShortcuts } from '../../../../constants' export class TheatreModeButton extends shaka.ui.Element { /** @@ -71,8 +72,16 @@ export class TheatreModeButton extends shaka.ui.Element { this.icon_.textContent = this.theatreModeEnabled_ ? 'monitor' : 'tv' - this.currentState_.textContent = this.localization.resolve(this.theatreModeEnabled_ ? 'ON' : 'OFF') + this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { + label: this.localization.resolve(this.theatreModeEnabled_ ? 'ON' : 'OFF'), + shortcut: KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE + }) + + const baseAriaLabel = this.theatreModeEnabled_ ? i18n.t('Video.Player.Exit Theatre Mode') : i18n.t('Video.Player.Theatre Mode') - this.button_.ariaLabel = this.theatreModeEnabled_ ? i18n.t('Video.Player.Exit Theatre Mode') : i18n.t('Video.Player.Theatre Mode') + this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { + label: baseAriaLabel, + shortcut: KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE + }) } } diff --git a/src/renderer/components/top-nav/top-nav.js b/src/renderer/components/top-nav/top-nav.js index f5aef0c0b669e..f7d3adbd1da76 100644 --- a/src/renderer/components/top-nav/top-nav.js +++ b/src/renderer/components/top-nav/top-nav.js @@ -4,7 +4,7 @@ import FtInput from '../ft-input/ft-input.vue' import FtProfileSelector from '../ft-profile-selector/ft-profile-selector.vue' import debounce from 'lodash.debounce' -import { IpcChannels, MOBILE_WIDTH_THRESHOLD } from '../../../constants' +import { IpcChannels, KeyboardShortcuts, MOBILE_WIDTH_THRESHOLD } from '../../../constants' import { openInternalPath } from '../../helpers/utils' import { translateWindowTitle } from '../../helpers/strings' import { clearLocalSearchSuggestionsSession, getLocalSearchSuggestions } from '../../helpers/api/local' @@ -87,15 +87,24 @@ export default defineComponent({ }, forwardText: function () { - return this.$t('Forward') + return this.$t('KeyboardShortcutTemplate', { + label: this.$t('Forward'), + shortcut: KeyboardShortcuts.APP.HISTORY_FORWARD + }) }, backwardText: function () { - return this.$t('Back') + return this.$t('KeyboardShortcutTemplate', { + label: this.$t('Back'), + shortcut: KeyboardShortcuts.APP.HISTORY_BACKWARD + }) }, newWindowText: function () { - return this.$t('Open New Window') + return this.$t('KeyboardShortcutTemplate', { + label: this.$t('Open New Window'), + shortcut: KeyboardShortcuts.APP.NEW_WINDOW + }) } }, watch: { diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 88f9725a5f183..3304877af6526 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -1130,3 +1130,4 @@ Cancel: Cancel checkmark: ✓ # French is the only language that should change this (they have a space before the colon) Display Label: '{label}: {value}' +KeyboardShortcutTemplate: '{label} ({shortcut})' From 31340530e6adade0932beef4845aeb68e54ef1e1 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 13 Oct 2024 17:51:25 -0500 Subject: [PATCH 02/16] Add keyboard shortcut to unmodified Shaka control labels --- .../ft-shaka-video-player.js | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 4c3c10f968b80..c5ba1e1307cf4 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -7,7 +7,7 @@ import shaka from 'shaka-player' import store from '../../store/index' import i18n from '../../i18n/index' -import { IpcChannels } from '../../../constants' +import { IpcChannels, KeyboardShortcuts } from '../../../constants' import { AudioTrackSelection } from './player-components/AudioTrackSelection' import { FullWindowButton } from './player-components/FullWindowButton' import { LegacyQualitySelection } from './player-components/LegacyQualitySelection' @@ -41,6 +41,19 @@ const RequestType = shaka.net.NetworkingEngine.RequestType const AdvancedRequestType = shaka.net.NetworkingEngine.AdvancedRequestType const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat +const shakaControlKeysToShortcuts = { + MUTE: KeyboardShortcuts.VIDEO_PLAYER.MUTE, + UNMUTE: KeyboardShortcuts.VIDEO_PLAYER.MUTE, + PLAY: KeyboardShortcuts.VIDEO_PLAYER.PLAY, + PAUSE: KeyboardShortcuts.VIDEO_PLAYER.PLAY, + PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, + ENTER_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, + EXIT_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, + CAPTIONS: KeyboardShortcuts.VIDEO_PLAYER.CAPTIONS, + FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN, + EXIT_FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN +} + /** @type {Map} */ const LOCALE_MAPPINGS = new Map(process.env.SHAKA_LOCALE_MAPPINGS) @@ -968,7 +981,7 @@ export default defineComponent({ * @param {string} locale */ async function setLocale(locale) { - // For most of FreeTube's locales their is an equivalent one in shaka-player, + // For most of FreeTube's locales, there is an equivalent one in shaka-player, // however if there isn't one we should fall back to US English. // At the time of writing "et", "eu", "gl", "is" don't have any translations const shakaLocale = LOCALE_MAPPINGS.get(locale) ?? 'en' @@ -989,6 +1002,20 @@ export default defineComponent({ localization.changeLocale([shakaLocale]) + // Add the keyboard shortcut to the label for the default Shaka controls + + const shakaControlKeysToShortcutLocalizations = new Map() + Object.entries(shakaControlKeysToShortcuts).forEach(([shakaControlKey, shortcut]) => { + const originalLocalization = localization.resolve(shakaControlKey) + const localizationWithShortcut = i18n.t('KeyboardShortcutTemplate', { + label: originalLocalization, + shortcut: shortcut + }) + shakaControlKeysToShortcutLocalizations.set(shakaControlKey, localizationWithShortcut) + }) + + localization.insert(shakaLocale, shakaControlKeysToShortcutLocalizations) + events.dispatchEvent(new CustomEvent('localeChanged')) } From 0d3882eca29a6b8a8bb138efeb77b3e539491da3 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 13 Oct 2024 18:08:13 -0500 Subject: [PATCH 03/16] Replace in-code use of available shortcuts with the corresponding constants --- .../ft-shaka-video-player.js | 57 +++++++------------ .../subscriptions-tab-ui.js | 8 +-- src/renderer/views/Popular/Popular.js | 8 +-- src/renderer/views/Trending/Trending.js | 8 +-- 4 files changed, 34 insertions(+), 47 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index c5ba1e1307cf4..8de012f7cabcb 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -2006,55 +2006,47 @@ export default defineComponent({ const video_ = video.value - switch (event.key) { + switch (event.key.toLowerCase()) { case ' ': - case 'Spacebar': // older browsers might return spacebar instead of a space character - case 'K': - case 'k': + case 'spacebar': // older browsers might return spacebar instead of a space character + case KeyboardShortcuts.VIDEO_PLAYER.PLAY: // Toggle Play/Pause event.preventDefault() video_.paused ? video_.play() : video_.pause() break - case 'J': - case 'j': + case KeyboardShortcuts.VIDEO_PLAYER.LARGE_REWIND: // Rewind by 2x the time-skip interval (in seconds) event.preventDefault() seekBySeconds(-defaultSkipInterval.value * video_.playbackRate * 2) break - case 'L': - case 'l': + case KeyboardShortcuts.VIDEO_PLAYER.LARGE_FAST_FORWARD: // Fast-Forward by 2x the time-skip interval (in seconds) event.preventDefault() seekBySeconds(defaultSkipInterval.value * video_.playbackRate * 2) break - case 'O': - case 'o': + case KeyboardShortcuts.VIDEO_PLAYER.DECREASE_VIDEO_SPEED: // Decrease playback rate by user configured interval event.preventDefault() changePlayBackRate(-videoPlaybackRateInterval.value) break - case 'P': - case 'p': + case KeyboardShortcuts.VIDEO_PLAYER.INCREASE_VIDEO_SPEED: // Increase playback rate by user configured interval event.preventDefault() changePlayBackRate(videoPlaybackRateInterval.value) break - case 'F': - case 'f': + case KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN: // Toggle full screen event.preventDefault() ui.getControls().toggleFullScreen() break - case 'M': - case 'm': + case KeyboardShortcuts.VIDEO_PLAYER.MUTE: // Toggle mute only if metakey is not pressed if (!event.metaKey) { event.preventDefault() video_.muted = !video_.muted } break - case 'C': - case 'c': + case KeyboardShortcuts.VIDEO_PLAYER.SUBTITLES: // Toggle caption/subtitles if (player.getTextTracks().length > 0) { event.preventDefault() @@ -2063,17 +2055,17 @@ export default defineComponent({ player.setTextTrackVisibility(!currentlyVisible) } break - case 'ArrowUp': + case 'arrowup': // Increase volume event.preventDefault() changeVolume(0.05) break - case 'ArrowDown': + case 'arrowdown': // Decrease Volume event.preventDefault() changeVolume(-0.05) break - case 'ArrowLeft': + case 'arrowleft': event.preventDefault() if (canChapterJump(event, 'previous')) { // Jump to the previous chapter @@ -2083,7 +2075,7 @@ export default defineComponent({ seekBySeconds(-defaultSkipInterval.value * video_.playbackRate) } break - case 'ArrowRight': + case 'arrowright': event.preventDefault() if (canChapterJump(event, 'next')) { // Jump to the next chapter @@ -2093,8 +2085,7 @@ export default defineComponent({ seekBySeconds(defaultSkipInterval.value * video_.playbackRate) } break - case 'I': - case 'i': + case KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE: // Toggle picture in picture if (props.format !== 'audio') { const controls = ui.getControls() @@ -2127,18 +2118,17 @@ export default defineComponent({ } break } - case ',': + case KeyboardShortcuts.VIDEO_PLAYER.LAST_FRAME: event.preventDefault() // Return to previous frame frameByFrame(-1) break - case '.': + case KeyboardShortcuts.VIDEO_PLAYER.NEXT_FRAME: event.preventDefault() // Advance to next frame frameByFrame(1) break - case 'D': - case 'd': + case KeyboardShortcuts.VIDEO_PLAYER.STATS: // Toggle stats display event.preventDefault() @@ -2146,7 +2136,7 @@ export default defineComponent({ detail: !showStats.value })) break - case 'Escape': + case 'escape': // Exit full window if (fullWindowEnabled.value) { event.preventDefault() @@ -2156,16 +2146,14 @@ export default defineComponent({ })) } break - case 'S': - case 's': + case KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW: // Toggle full window mode event.preventDefault() events.dispatchEvent(new CustomEvent('setFullWindow', { detail: !fullWindowEnabled.value })) break - case 'T': - case 't': + case KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE: // Toggle theatre mode if (props.theatrePossible) { event.preventDefault() @@ -2175,8 +2163,7 @@ export default defineComponent({ })) } break - case 'U': - case 'u': + case KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT: if (process.env.IS_ELECTRON && enableScreenshot.value && props.format !== 'audio') { event.preventDefault() // Take screenshot diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js index 489d928f383e0..b945e42b77b02 100644 --- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js +++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js @@ -7,6 +7,7 @@ import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtElementList from '../FtElementList/FtElementList.vue' import FtChannelBubble from '../ft-channel-bubble/ft-channel-bubble.vue' import FtAutoLoadNextPageWrapper from '../ft-auto-load-next-page-wrapper/ft-auto-load-next-page-wrapper.vue' +import { KeyboardShortcuts } from '../../../constants' export default defineComponent({ name: 'SubscriptionsTabUI', @@ -113,10 +114,9 @@ export default defineComponent({ // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat if (event.repeat) { return } - switch (event.key) { - case 'r': - case 'R': - case 'F5': + switch (event.key.toLowerCase()) { + case 'f5': + case KeyboardShortcuts.FEED.REFRESH: if (!this.isLoading && this.activeSubscriptionList.length > 0) { this.$emit('refresh') } diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js index 2a35f9d8cb68d..300c276f045d3 100644 --- a/src/renderer/views/Popular/Popular.js +++ b/src/renderer/views/Popular/Popular.js @@ -8,6 +8,7 @@ import FtRefreshWidget from '../../components/ft-refresh-widget/ft-refresh-widge import { invidiousAPICall } from '../../helpers/api/invidious' import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils' +import { KeyboardShortcuts } from '../../../constants' export default defineComponent({ name: 'Popular', @@ -90,10 +91,9 @@ export default defineComponent({ // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat if (event.repeat) { return } - switch (event.key) { - case 'r': - case 'R': - case 'F5': + switch (event.key.toLowerCase()) { + case 'f5': + case KeyboardShortcuts.FEED.REFRESH: if (!this.isLoading) { this.fetchPopularInfo() } diff --git a/src/renderer/views/Trending/Trending.js b/src/renderer/views/Trending/Trending.js index 533f9cf8b56e5..2cfd80b22beb6 100644 --- a/src/renderer/views/Trending/Trending.js +++ b/src/renderer/views/Trending/Trending.js @@ -10,6 +10,7 @@ import FtRefreshWidget from '../../components/ft-refresh-widget/ft-refresh-widge import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils' import { getLocalTrending } from '../../helpers/api/local' import { invidiousAPICall } from '../../helpers/api/invidious' +import { KeyboardShortcuts } from '../../../constants' export default defineComponent({ name: 'Trending', @@ -189,10 +190,9 @@ export default defineComponent({ // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat if (event.repeat) { return } - switch (event.key) { - case 'r': - case 'R': - case 'F5': + switch (event.key.toLowerCase()) { + case 'f5': + case KeyboardShortcuts.FEED.REFRESH: if (!this.isLoading) { this.getTrendingInfo(true) } From 443c4afa48447c849c117bad8dfbb1533a05f8b4 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 13 Oct 2024 21:34:25 -0500 Subject: [PATCH 04/16] Add explanatory comments --- src/constants.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/constants.js b/src/constants.js index 79be6c527b3ba..455f0c50c3b33 100644 --- a/src/constants.js +++ b/src/constants.js @@ -113,6 +113,7 @@ const SyncEvents = { }, } +// note: the multi-character shortcut values are currently just for presentational use const KeyboardShortcuts = { APP: { HISTORY_BACKWARD: 'Alt+Left Arrow', @@ -136,14 +137,17 @@ const KeyboardShortcuts = { FULLWINDOW: 's', THEATRE_MODE: 't', TAKE_SCREENSHOT: 'u', - VOLUME_UP: 'Up Arrow', - VOLUME_DOWN: 'Down Arrow', - SMALL_REWIND: 'Left Arrow', - SMALL_FAST_FORWARD: 'Right Arrow', - LAST_CHAPTER: 'Cmd/Ctrl+Left Arrow', - NEXT_CHAPTER: 'Cmd/Ctrl+Right Arrow', LAST_FRAME: ',', - NEXT_FRAME: '.' + NEXT_FRAME: '.', + + /* For future use + VOLUME_UP: 'Up Arrow', + VOLUME_DOWN: 'Down Arrow', + SMALL_REWIND: 'Left Arrow', + SMALL_FAST_FORWARD: 'Right Arrow', + LAST_CHAPTER: 'Cmd/Ctrl+Left Arrow', + NEXT_CHAPTER: 'Cmd/Ctrl+Right Arrow', + */ }, } From 42c312808099f9d95f0487395a76a9d8f2528aa4 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 14 Oct 2024 08:04:22 -0500 Subject: [PATCH 05/16] Fix captions constant name --- src/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.js b/src/constants.js index 455f0c50c3b33..a515670ee4eb2 100644 --- a/src/constants.js +++ b/src/constants.js @@ -124,7 +124,7 @@ const KeyboardShortcuts = { REFRESH: 'r' }, VIDEO_PLAYER: { - SUBTITLES: 'c', + CAPTIONS: 'c', STATS: 'd', FULLSCREEN: 'f', PICTURE_IN_PICTURE: 'i', From 7c379e22a431d1cff523a7d5a0a304337e6528be Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 14 Oct 2024 08:14:19 -0500 Subject: [PATCH 06/16] Prevent creating new shortcut localization if Shaka localization key has no matching value --- .../ft-shaka-video-player/ft-shaka-video-player.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 8de012f7cabcb..c9dafd7b7142b 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -1007,6 +1007,12 @@ export default defineComponent({ const shakaControlKeysToShortcutLocalizations = new Map() Object.entries(shakaControlKeysToShortcuts).forEach(([shakaControlKey, shortcut]) => { const originalLocalization = localization.resolve(shakaControlKey) + if (originalLocalization === '') { + // e.g., A Shaka localization key in shakaControlKeysToShortcuts has fallen out of date and need to be updated + console.error('Mising Shaka localization key "%s"', shakaControlKey) + return + } + const localizationWithShortcut = i18n.t('KeyboardShortcutTemplate', { label: originalLocalization, shortcut: shortcut From 764cace794ba8ff38c61c4bf5384f29963bcb2f1 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 14 Oct 2024 13:57:29 -0500 Subject: [PATCH 07/16] Add util functions to localize special keys --- src/constants.js | 18 ++++---- .../ft-refresh-widget/ft-refresh-widget.js | 9 ++-- .../ft-shaka-video-player.js | 12 +++--- .../player-components/FullWindowButton.js | 14 +++---- .../player-components/ScreenshotButton.js | 9 ++-- .../player-components/StatsButton.js | 19 ++++----- .../player-components/TheatreModeButton.js | 14 +++---- src/renderer/components/top-nav/top-nav.js | 26 ++++++------ src/renderer/helpers/utils.js | 41 +++++++++++++++++++ static/locales/en-US.yaml | 9 ++++ 10 files changed, 109 insertions(+), 62 deletions(-) diff --git a/src/constants.js b/src/constants.js index a515670ee4eb2..f9af1ddfeda25 100644 --- a/src/constants.js +++ b/src/constants.js @@ -116,9 +116,9 @@ const SyncEvents = { // note: the multi-character shortcut values are currently just for presentational use const KeyboardShortcuts = { APP: { - HISTORY_BACKWARD: 'Alt+Left Arrow', - HISTORY_FORWARD: 'Alt+Right Arrow', - NEW_WINDOW: 'Cmd/Ctrl+N' + HISTORY_BACKWARD: 'alt+left arrow', + HISTORY_FORWARD: 'alt+right arrow', + NEW_WINDOW: 'ctrl+N' }, FEED: { REFRESH: 'r' @@ -141,12 +141,12 @@ const KeyboardShortcuts = { NEXT_FRAME: '.', /* For future use - VOLUME_UP: 'Up Arrow', - VOLUME_DOWN: 'Down Arrow', - SMALL_REWIND: 'Left Arrow', - SMALL_FAST_FORWARD: 'Right Arrow', - LAST_CHAPTER: 'Cmd/Ctrl+Left Arrow', - NEXT_CHAPTER: 'Cmd/Ctrl+Right Arrow', + VOLUME_UP: 'up arrow', + VOLUME_DOWN: 'down arrow', + SMALL_REWIND: 'Left arrow', + SMALL_FAST_FORWARD: 'right arrow', + LAST_CHAPTER: 'ctrl+left arrow', + NEXT_CHAPTER: 'ctrl+right arrow', */ }, } diff --git a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js index 75e81e87cb275..c3180377f46ad 100644 --- a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js +++ b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js @@ -2,6 +2,7 @@ import { defineComponent } from 'vue' import FtIconButton from '../ft-icon-button/ft-icon-button.vue' import { KeyboardShortcuts } from '../../../constants' +import { addKeyboardShortcutToActionLabel } from '../../helpers/utils' export default defineComponent({ name: 'FtRefreshWidget', @@ -25,10 +26,10 @@ export default defineComponent({ emits: ['click'], computed: { refreshFeedButtonTitle: function() { - return this.$t('KeyboardShortcutTemplate', { - label: this.$t('Feed.Refresh Feed', { subscriptionName: this.title }), - shortcut: KeyboardShortcuts.FEED.REFRESH - }) + return addKeyboardShortcutToActionLabel( + this.$t('Feed.Refresh Feed', { subscriptionName: this.title }), + KeyboardShortcuts.FEED.REFRESH + ) } }, methods: { diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index c9dafd7b7142b..34e6c20a9e39b 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -24,6 +24,7 @@ import { translateSponsorBlockCategory } from '../../helpers/player/utils' import { + addKeyboardShortcutToActionLabel, getPicturesPath, showSaveDialog, showToast @@ -1013,10 +1014,11 @@ export default defineComponent({ return } - const localizationWithShortcut = i18n.t('KeyboardShortcutTemplate', { - label: originalLocalization, - shortcut: shortcut - }) + const localizationWithShortcut = addKeyboardShortcutToActionLabel( + originalLocalization, + shortcut + ) + shakaControlKeysToShortcutLocalizations.set(shakaControlKey, localizationWithShortcut) }) @@ -2052,7 +2054,7 @@ export default defineComponent({ video_.muted = !video_.muted } break - case KeyboardShortcuts.VIDEO_PLAYER.SUBTITLES: + case KeyboardShortcuts.VIDEO_PLAYER.CAPTIONS: // Toggle caption/subtitles if (player.getTextTracks().length > 0) { event.preventDefault() diff --git a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js index 0170a7ca59c42..abfd0d36dbdd7 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js @@ -2,6 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' +import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' export class FullWindowButton extends shaka.ui.Element { /** @@ -73,16 +74,13 @@ export class FullWindowButton extends shaka.ui.Element { this.icon_.textContent = this.fullWindowEnabled_ ? 'close_fullscreen' : 'open_in_full' - this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { - label: this.localization.resolve(this.fullWindowEnabled_ ? 'ON' : 'OFF'), - shortcut: KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW - }) + this.currentState_.textContent = this.localization.resolve(this.fullWindowEnabled_ ? 'ON' : 'OFF') const baseAriaLabel = this.fullWindowEnabled_ ? i18n.t('Video.Player.Exit Full Window') : i18n.t('Video.Player.Full Window') - this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { - label: baseAriaLabel, - shortcut: KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW - }) + this.button_.ariaLabel = addKeyboardShortcutToActionLabel( + baseAriaLabel, + KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW + ) } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js index 799777c4dcdc7..f46a375ab0504 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js @@ -2,6 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' +import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' export class ScreenshotButton extends shaka.ui.Element { /** @@ -50,10 +51,10 @@ export class ScreenshotButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - const label = i18n.t('KeyboardShortcutTemplate', { - label: i18n.t('Video.Player.Take Screenshot'), - shortcut: KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT - }) + const label = addKeyboardShortcutToActionLabel( + i18n.t('Video.Player.Take Screenshot'), + KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT + ) this.nameSpan_.textContent = label this.button_.ariaLabel = label } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js index 1b15bc232ad06..11449f20fd4f1 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js @@ -2,6 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' +import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' export class StatsButton extends shaka.ui.Element { /** @@ -66,19 +67,15 @@ export class StatsButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - this.nameSpan_.textContent = i18n.t('Video.Player.Stats.Stats') this.icon_.textContent = this.showStats_ ? 'insert_chart' : 'insert_chart_outlined' - this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { - label: this.localization.resolve(this.showStats_ ? 'ON' : 'OFF'), - shortcut: KeyboardShortcuts.VIDEO_PLAYER.STATS - }) - - const baseAriaLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') + const baseLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') + const label = addKeyboardShortcutToActionLabel( + baseLabel, + KeyboardShortcuts.VIDEO_PLAYER.STATS + ) - this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { - label: baseAriaLabel, - shortcut: KeyboardShortcuts.VIDEO_PLAYER.STATS - }) + this.currentState_.textContent = label + this.button_.ariaLabel = label } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js index 352961e8dabb5..e12d0e14a8394 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js @@ -2,6 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' +import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' export class TheatreModeButton extends shaka.ui.Element { /** @@ -72,16 +73,13 @@ export class TheatreModeButton extends shaka.ui.Element { this.icon_.textContent = this.theatreModeEnabled_ ? 'monitor' : 'tv' - this.currentState_.textContent = i18n.t('KeyboardShortcutTemplate', { - label: this.localization.resolve(this.theatreModeEnabled_ ? 'ON' : 'OFF'), - shortcut: KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE - }) + this.currentState_.textContent = this.localization.resolve(this.theatreModeEnabled_ ? 'ON' : 'OFF') const baseAriaLabel = this.theatreModeEnabled_ ? i18n.t('Video.Player.Exit Theatre Mode') : i18n.t('Video.Player.Theatre Mode') - this.button_.ariaLabel = i18n.t('KeyboardShortcutTemplate', { - label: baseAriaLabel, - shortcut: KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE - }) + this.button_.ariaLabel = addKeyboardShortcutToActionLabel( + baseAriaLabel, + KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE + ) } } diff --git a/src/renderer/components/top-nav/top-nav.js b/src/renderer/components/top-nav/top-nav.js index f7d3adbd1da76..678f33c044f31 100644 --- a/src/renderer/components/top-nav/top-nav.js +++ b/src/renderer/components/top-nav/top-nav.js @@ -5,7 +5,7 @@ import FtProfileSelector from '../ft-profile-selector/ft-profile-selector.vue' import debounce from 'lodash.debounce' import { IpcChannels, KeyboardShortcuts, MOBILE_WIDTH_THRESHOLD } from '../../../constants' -import { openInternalPath } from '../../helpers/utils' +import { localizeAndAddKeyboardShortcutToActionLabel, openInternalPath } from '../../helpers/utils' import { translateWindowTitle } from '../../helpers/strings' import { clearLocalSearchSuggestionsSession, getLocalSearchSuggestions } from '../../helpers/api/local' import { invidiousAPICall } from '../../helpers/api/invidious' @@ -87,24 +87,24 @@ export default defineComponent({ }, forwardText: function () { - return this.$t('KeyboardShortcutTemplate', { - label: this.$t('Forward'), - shortcut: KeyboardShortcuts.APP.HISTORY_FORWARD - }) + return localizeAndAddKeyboardShortcutToActionLabel( + this.$t('Forward'), + KeyboardShortcuts.APP.HISTORY_FORWARD + ) }, backwardText: function () { - return this.$t('KeyboardShortcutTemplate', { - label: this.$t('Back'), - shortcut: KeyboardShortcuts.APP.HISTORY_BACKWARD - }) + return localizeAndAddKeyboardShortcutToActionLabel( + this.$t('Back'), + KeyboardShortcuts.APP.HISTORY_BACKWARD + ) }, newWindowText: function () { - return this.$t('KeyboardShortcutTemplate', { - label: this.$t('Open New Window'), - shortcut: KeyboardShortcuts.APP.NEW_WINDOW - }) + return localizeAndAddKeyboardShortcutToActionLabel( + this.$t('Open New Window'), + KeyboardShortcuts.APP.NEW_WINDOW + ) } }, watch: { diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 79c8369302484..770d2fb263b14 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -889,3 +889,44 @@ export function getChannelPlaylistId(channelId, type, sortBy) { return channelId.replace(/^UC/, 'UU') } } + +function getIndividualLocalizedShortcut(shortcut) { + switch (shortcut) { + case 'alt': + return i18n.t('Keys.alt') + case 'ctrl': + return process.platform === 'darwin' + ? i18n.t('Keys.ctrl') + : i18n.t('Keys.cmd') + case 'left arrow': + return i18n.t('Keys.left arrow') + case 'right arrow': + return i18n.t('Keys.right arrow') + case 'up arrow': + return i18n.t('Keys.up arrow') + case 'down arrow': + return i18n.t('Keys.down arrow') + default: + return shortcut + } +} + +function getLocalizedShortcut(shortcut) { + const shortcuts = shortcut.split('+') + const localizedShortcuts = shortcuts.map((shortcut) => getIndividualLocalizedShortcut(shortcut)) + + const shortcutJoinOperator = i18n.t('shortcutJoinOperator') + return localizedShortcuts.join(shortcutJoinOperator) +} + +export function addKeyboardShortcutToActionLabel(actionLabel, shortcut) { + return i18n.t('KeyboardShortcutTemplate', { + label: actionLabel, + shortcut + }) +} + +export function localizeAndAddKeyboardShortcutToActionLabel(localizedActionLabel, unlocalizedShortcut) { + const localizedShortcut = getLocalizedShortcut(unlocalizedShortcut) + return addKeyboardShortcutToActionLabel(localizedActionLabel, localizedShortcut) +} diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 3304877af6526..9a8c9858579d0 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -1131,3 +1131,12 @@ checkmark: ✓ # French is the only language that should change this (they have a space before the colon) Display Label: '{label}: {value}' KeyboardShortcutTemplate: '{label} ({shortcut})' +shortcutJoinOperator: + +Keys: + alt: Alt + cmd: Cmd + ctrl: Ctrl + down arrow: Down Arrow + left arrow: Left Arrow + right arrow: Right Arrow + up arrow: Up Arrow From 6798c3ac83ef4cc0027dbd9460877c08e8bd50f6 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 14 Oct 2024 14:08:54 -0500 Subject: [PATCH 08/16] Replace more video player shortcut usage in code with corresponding constants --- src/constants.js | 16 ++++++++-------- .../ft-shaka-video-player.js | 8 ++++---- src/renderer/helpers/utils.js | 16 ++++++++-------- static/locales/en-US.yaml | 8 ++++---- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/constants.js b/src/constants.js index f9af1ddfeda25..e720218094e53 100644 --- a/src/constants.js +++ b/src/constants.js @@ -116,8 +116,8 @@ const SyncEvents = { // note: the multi-character shortcut values are currently just for presentational use const KeyboardShortcuts = { APP: { - HISTORY_BACKWARD: 'alt+left arrow', - HISTORY_FORWARD: 'alt+right arrow', + HISTORY_BACKWARD: 'alt+arrowleft', + HISTORY_FORWARD: 'alt+arrowright', NEW_WINDOW: 'ctrl+N' }, FEED: { @@ -139,14 +139,14 @@ const KeyboardShortcuts = { TAKE_SCREENSHOT: 'u', LAST_FRAME: ',', NEXT_FRAME: '.', + VOLUME_UP: 'arrowup', + VOLUME_DOWN: 'arrowdown', + SMALL_REWIND: 'arrowleft', + SMALL_FAST_FORWARD: 'arrowright', /* For future use - VOLUME_UP: 'up arrow', - VOLUME_DOWN: 'down arrow', - SMALL_REWIND: 'Left arrow', - SMALL_FAST_FORWARD: 'right arrow', - LAST_CHAPTER: 'ctrl+left arrow', - NEXT_CHAPTER: 'ctrl+right arrow', + LAST_CHAPTER: 'ctrl+arrowleft', + NEXT_CHAPTER: 'ctrl+arrowright', */ }, } diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 34e6c20a9e39b..dc7f98015dd06 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -2063,17 +2063,17 @@ export default defineComponent({ player.setTextTrackVisibility(!currentlyVisible) } break - case 'arrowup': + case KeyboardShortcuts.VIDEO_PLAYER.VOLUME_UP: // Increase volume event.preventDefault() changeVolume(0.05) break - case 'arrowdown': + case KeyboardShortcuts.VIDEO_PLAYER.VOLUME_DOWN: // Decrease Volume event.preventDefault() changeVolume(-0.05) break - case 'arrowleft': + case KeyboardShortcuts.VIDEO_PLAYER.SMALL_REWIND: event.preventDefault() if (canChapterJump(event, 'previous')) { // Jump to the previous chapter @@ -2083,7 +2083,7 @@ export default defineComponent({ seekBySeconds(-defaultSkipInterval.value * video_.playbackRate) } break - case 'arrowright': + case KeyboardShortcuts.VIDEO_PLAYER.SMALL_FAST_FORWARD: event.preventDefault() if (canChapterJump(event, 'next')) { // Jump to the next chapter diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 770d2fb263b14..58f56446d45b5 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -898,14 +898,14 @@ function getIndividualLocalizedShortcut(shortcut) { return process.platform === 'darwin' ? i18n.t('Keys.ctrl') : i18n.t('Keys.cmd') - case 'left arrow': - return i18n.t('Keys.left arrow') - case 'right arrow': - return i18n.t('Keys.right arrow') - case 'up arrow': - return i18n.t('Keys.up arrow') - case 'down arrow': - return i18n.t('Keys.down arrow') + case 'arrowleft': + return i18n.t('Keys.arrowleft') + case 'arrowright': + return i18n.t('Keys.arrowright') + case 'arrowup': + return i18n.t('Keys.arrowup') + case 'arrowdown': + return i18n.t('Keys.arrowdown') default: return shortcut } diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 9a8c9858579d0..99fc55c1f5743 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -1136,7 +1136,7 @@ Keys: alt: Alt cmd: Cmd ctrl: Ctrl - down arrow: Down Arrow - left arrow: Left Arrow - right arrow: Right Arrow - up arrow: Up Arrow + arrowdown: Down Arrow + arrowleft: Left Arrow + arrowright: Right Arrow + arrowup: Up Arrow From 6f8d21295d0b9f20594631a4abfc0e224de01a86 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Mon, 14 Oct 2024 14:31:57 -0500 Subject: [PATCH 09/16] Add labels for History and Settings app shortcuts, and update variable naming --- src/constants.js | 7 +++-- .../ft-refresh-widget/ft-refresh-widget.js | 4 +-- .../ft-shaka-video-player.js | 4 +-- .../player-components/FullWindowButton.js | 4 +-- .../player-components/ScreenshotButton.js | 4 +-- .../player-components/StatsButton.js | 4 +-- .../player-components/TheatreModeButton.js | 4 +-- src/renderer/components/side-nav/side-nav.js | 19 ++++++++++++- src/renderer/components/side-nav/side-nav.vue | 4 +-- src/renderer/components/top-nav/top-nav.js | 8 +++--- src/renderer/helpers/utils.js | 27 ++++++++++++++----- 11 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/constants.js b/src/constants.js index e720218094e53..4a102ac93ad5b 100644 --- a/src/constants.js +++ b/src/constants.js @@ -113,12 +113,15 @@ const SyncEvents = { }, } -// note: the multi-character shortcut values are currently just for presentational use +// note: the multi-key shortcut values are currently just for display use in action titles const KeyboardShortcuts = { APP: { HISTORY_BACKWARD: 'alt+arrowleft', HISTORY_FORWARD: 'alt+arrowright', - NEW_WINDOW: 'ctrl+N' + NEW_WINDOW: 'ctrl+N', + NAVIGATE_TO_SETTINGS: 'ctrl+,', + NAVIGATE_TO_HISTORY: 'ctrl+H', + NAVIGATE_TO_HISTORY_MAC: 'cmd+Y', }, FEED: { REFRESH: 'r' diff --git a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js index c3180377f46ad..ff242914e65a9 100644 --- a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js +++ b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js @@ -2,7 +2,7 @@ import { defineComponent } from 'vue' import FtIconButton from '../ft-icon-button/ft-icon-button.vue' import { KeyboardShortcuts } from '../../../constants' -import { addKeyboardShortcutToActionLabel } from '../../helpers/utils' +import { addKeyboardShortcutToActionTitle } from '../../helpers/utils' export default defineComponent({ name: 'FtRefreshWidget', @@ -26,7 +26,7 @@ export default defineComponent({ emits: ['click'], computed: { refreshFeedButtonTitle: function() { - return addKeyboardShortcutToActionLabel( + return addKeyboardShortcutToActionTitle( this.$t('Feed.Refresh Feed', { subscriptionName: this.title }), KeyboardShortcuts.FEED.REFRESH ) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index dc7f98015dd06..eeb5de4f4aed0 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -24,7 +24,7 @@ import { translateSponsorBlockCategory } from '../../helpers/player/utils' import { - addKeyboardShortcutToActionLabel, + addKeyboardShortcutToActionTitle, getPicturesPath, showSaveDialog, showToast @@ -1014,7 +1014,7 @@ export default defineComponent({ return } - const localizationWithShortcut = addKeyboardShortcutToActionLabel( + const localizationWithShortcut = addKeyboardShortcutToActionTitle( originalLocalization, shortcut ) diff --git a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js index abfd0d36dbdd7..abda948c23c45 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js @@ -2,7 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' -import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' +import { addKeyboardShortcutToActionTitle } from '../../../helpers/utils' export class FullWindowButton extends shaka.ui.Element { /** @@ -78,7 +78,7 @@ export class FullWindowButton extends shaka.ui.Element { const baseAriaLabel = this.fullWindowEnabled_ ? i18n.t('Video.Player.Exit Full Window') : i18n.t('Video.Player.Full Window') - this.button_.ariaLabel = addKeyboardShortcutToActionLabel( + this.button_.ariaLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW ) diff --git a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js index f46a375ab0504..0900c47f9514b 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js @@ -2,7 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' -import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' +import { addKeyboardShortcutToActionTitle } from '../../../helpers/utils' export class ScreenshotButton extends shaka.ui.Element { /** @@ -51,7 +51,7 @@ export class ScreenshotButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - const label = addKeyboardShortcutToActionLabel( + const label = addKeyboardShortcutToActionTitle( i18n.t('Video.Player.Take Screenshot'), KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT ) diff --git a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js index 11449f20fd4f1..dd3378b97e424 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js @@ -2,7 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' -import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' +import { addKeyboardShortcutToActionTitle } from '../../../helpers/utils' export class StatsButton extends shaka.ui.Element { /** @@ -70,7 +70,7 @@ export class StatsButton extends shaka.ui.Element { this.icon_.textContent = this.showStats_ ? 'insert_chart' : 'insert_chart_outlined' const baseLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') - const label = addKeyboardShortcutToActionLabel( + const label = addKeyboardShortcutToActionTitle( baseLabel, KeyboardShortcuts.VIDEO_PLAYER.STATS ) diff --git a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js index e12d0e14a8394..52237c1c5dd1a 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js @@ -2,7 +2,7 @@ import shaka from 'shaka-player' import i18n from '../../../i18n/index' import { KeyboardShortcuts } from '../../../../constants' -import { addKeyboardShortcutToActionLabel } from '../../../helpers/utils' +import { addKeyboardShortcutToActionTitle } from '../../../helpers/utils' export class TheatreModeButton extends shaka.ui.Element { /** @@ -77,7 +77,7 @@ export class TheatreModeButton extends shaka.ui.Element { const baseAriaLabel = this.theatreModeEnabled_ ? i18n.t('Video.Player.Exit Theatre Mode') : i18n.t('Video.Player.Theatre Mode') - this.button_.ariaLabel = addKeyboardShortcutToActionLabel( + this.button_.ariaLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE ) diff --git a/src/renderer/components/side-nav/side-nav.js b/src/renderer/components/side-nav/side-nav.js index 45db9ef8e5ca5..e791d870fb7f4 100644 --- a/src/renderer/components/side-nav/side-nav.js +++ b/src/renderer/components/side-nav/side-nav.js @@ -2,7 +2,8 @@ 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' +import { deepCopy, localizeAndAddKeyboardShortcutToActionTitle } from '../../helpers/utils' +import { KeyboardShortcuts } from '../../../constants' export default defineComponent({ name: 'SideNav', @@ -80,6 +81,22 @@ export default defineComponent({ return { hiddenLabels: this.hideText } + }, + historyTitle: function() { + const shortcut = process.platform === 'darwin' + ? KeyboardShortcuts.APP.NAVIGATE_TO_HISTORY_MAC + : KeyboardShortcuts.APP.NAVIGATE_TO_HISTORY + + return localizeAndAddKeyboardShortcutToActionTitle( + this.$t('History.History'), + shortcut + ) + }, + settingsTitle: function() { + return localizeAndAddKeyboardShortcutToActionTitle( + this.$t('Settings.Settings'), + KeyboardShortcuts.APP.NAVIGATE_TO_SETTINGS + ) } } }) diff --git a/src/renderer/components/side-nav/side-nav.vue b/src/renderer/components/side-nav/side-nav.vue index ebfb8d44169eb..620ab24c52c3e 100644 --- a/src/renderer/components/side-nav/side-nav.vue +++ b/src/renderer/components/side-nav/side-nav.vue @@ -132,7 +132,7 @@ class="navOption mobileShow" role="button" to="/history" - :title="$t('History.History')" + :title="historyTitle" >
getIndividualLocalizedShortcut(shortcut)) @@ -919,14 +924,24 @@ function getLocalizedShortcut(shortcut) { return localizedShortcuts.join(shortcutJoinOperator) } -export function addKeyboardShortcutToActionLabel(actionLabel, shortcut) { +/** + * @param {string} actionTitle + * @param {string} shortcut + * @returns {string} the localized action title with keyboard shortcut + */ +export function addKeyboardShortcutToActionTitle(actionTitle, shortcut) { return i18n.t('KeyboardShortcutTemplate', { - label: actionLabel, + label: actionTitle, shortcut }) } -export function localizeAndAddKeyboardShortcutToActionLabel(localizedActionLabel, unlocalizedShortcut) { +/** + * @param {string} localizedActionTitle + * @param {string} unlocalizedShortcut + * @returns {string} the localized action title with keyboard shortcut + */ +export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle, unlocalizedShortcut) { const localizedShortcut = getLocalizedShortcut(unlocalizedShortcut) - return addKeyboardShortcutToActionLabel(localizedActionLabel, localizedShortcut) + return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcut) } From 16693ea2b08c39f0b9dfac1c0f8faa8c74727190 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 20 Oct 2024 13:32:02 -0500 Subject: [PATCH 10/16] Display 'Option' instead of 'Alt' for Mac users --- src/renderer/helpers/utils.js | 5 ++++- static/locales/en-US.yaml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 6276334d31825..b68be6ee28e8b 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -892,8 +892,11 @@ export function getChannelPlaylistId(channelId, type, sortBy) { function getIndividualLocalizedShortcut(shortcut) { switch (shortcut) { + case 'option': case 'alt': - return i18n.t('Keys.alt') + return process.platform === 'darwin' + ? i18n.t('Keys.option') + : i18n.t('Keys.alt') case 'cmd': case 'ctrl': return process.platform === 'darwin' diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 99fc55c1f5743..3e6c5e1910c7b 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -1136,6 +1136,7 @@ Keys: alt: Alt cmd: Cmd ctrl: Ctrl + option: Option arrowdown: Down Arrow arrowleft: Left Arrow arrowright: Right Arrow From cf263fbaf7a80fc3defd31f41267912e416d4bc8 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 20 Oct 2024 16:06:43 -0500 Subject: [PATCH 11/16] Use Mac icons in keyboard shortcuts for Macs --- src/renderer/helpers/utils.js | 42 ++++++++++++++++++++++++++--------- static/locales/en-US.yaml | 2 -- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index b68be6ee28e8b..4d972097f8d0a 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -892,16 +892,10 @@ export function getChannelPlaylistId(channelId, type, sortBy) { function getIndividualLocalizedShortcut(shortcut) { switch (shortcut) { - case 'option': case 'alt': - return process.platform === 'darwin' - ? i18n.t('Keys.option') - : i18n.t('Keys.alt') - case 'cmd': + return i18n.t('Keys.alt') case 'ctrl': - return process.platform === 'darwin' - ? i18n.t('Keys.cmd') - : i18n.t('Keys.ctrl') + return i18n.t('Keys.ctrl') case 'arrowleft': return i18n.t('Keys.arrowleft') case 'arrowright': @@ -915,16 +909,42 @@ function getIndividualLocalizedShortcut(shortcut) { } } +function getMacIconForShortcut(shortcut) { + switch (shortcut) { + case 'option': + case 'alt': + return '⌥' + case 'cmd': + case 'ctrl': + return '⌘' + case 'arrowleft': + return '◀' + case 'arrowright': + return '▶' + case 'arrowup': + return '▲' + case 'arrowdown': + return '▼' + default: + return shortcut + } +} + /** * @param {string} shortcut * @returns {string} the localized and recombined shortcut */ function getLocalizedShortcut(shortcut) { const shortcuts = shortcut.split('+') - const localizedShortcuts = shortcuts.map((shortcut) => getIndividualLocalizedShortcut(shortcut)) - const shortcutJoinOperator = i18n.t('shortcutJoinOperator') - return localizedShortcuts.join(shortcutJoinOperator) + if (process.platform === 'darwin') { + const shortcutsAsIcons = shortcuts.map((shortCut => getMacIconForShortcut(shortCut))) + return shortcutsAsIcons.join('') + } else { + const localizedShortcuts = shortcuts.map((shortcut) => getIndividualLocalizedShortcut(shortcut)) + const shortcutJoinOperator = i18n.t('shortcutJoinOperator') + return localizedShortcuts.join(shortcutJoinOperator) + } } /** diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 3e6c5e1910c7b..28a9a3ed34f57 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -1134,9 +1134,7 @@ KeyboardShortcutTemplate: '{label} ({shortcut})' shortcutJoinOperator: + Keys: alt: Alt - cmd: Cmd ctrl: Ctrl - option: Option arrowdown: Down Arrow arrowleft: Left Arrow arrowright: Right Arrow From d642682a137560e3187ce0815a15386b52592524 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Wed, 23 Oct 2024 08:25:10 -0500 Subject: [PATCH 12/16] Update Mac arrow icon choice --- src/renderer/helpers/utils.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js index 4d972097f8d0a..7291b7b421237 100644 --- a/src/renderer/helpers/utils.js +++ b/src/renderer/helpers/utils.js @@ -918,13 +918,13 @@ function getMacIconForShortcut(shortcut) { case 'ctrl': return '⌘' case 'arrowleft': - return '◀' + return '←' case 'arrowright': - return '▶' + return '→' case 'arrowup': - return '▲' + return '↑' case 'arrowdown': - return '▼' + return '↓' default: return shortcut } From 348100d01ce2ec77b1ec1d534bfa456400112f52 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Wed, 23 Oct 2024 08:36:31 -0500 Subject: [PATCH 13/16] Update KeyboardShortcuts constant organization in preparation for keyboard shorcut modal --- src/constants.js | 65 ++++++++++--------- .../ft-refresh-widget/ft-refresh-widget.js | 2 +- .../ft-shaka-video-player.js | 58 ++++++++--------- .../player-components/FullWindowButton.js | 2 +- .../player-components/ScreenshotButton.js | 2 +- .../player-components/StatsButton.js | 2 +- .../player-components/TheatreModeButton.js | 2 +- src/renderer/components/side-nav/side-nav.js | 6 +- .../subscriptions-tab-ui.js | 2 +- src/renderer/components/top-nav/top-nav.js | 6 +- src/renderer/views/Popular/Popular.js | 2 +- src/renderer/views/Trending/Trending.js | 2 +- 12 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/constants.js b/src/constants.js index 4a102ac93ad5b..196d1ab95ffab 100644 --- a/src/constants.js +++ b/src/constants.js @@ -116,41 +116,44 @@ const SyncEvents = { // note: the multi-key shortcut values are currently just for display use in action titles const KeyboardShortcuts = { APP: { - HISTORY_BACKWARD: 'alt+arrowleft', - HISTORY_FORWARD: 'alt+arrowright', - NEW_WINDOW: 'ctrl+N', - NAVIGATE_TO_SETTINGS: 'ctrl+,', - NAVIGATE_TO_HISTORY: 'ctrl+H', - NAVIGATE_TO_HISTORY_MAC: 'cmd+Y', - }, - FEED: { - REFRESH: 'r' + GENERAL: { + HISTORY_BACKWARD: 'alt+arrowleft', + HISTORY_FORWARD: 'alt+arrowright', + NEW_WINDOW: 'ctrl+N', + NAVIGATE_TO_SETTINGS: 'ctrl+,', + NAVIGATE_TO_HISTORY: 'ctrl+H', + NAVIGATE_TO_HISTORY_MAC: 'cmd+Y', + }, + SITUATIONAL: { + REFRESH: 'r' + }, }, VIDEO_PLAYER: { - CAPTIONS: 'c', - STATS: 'd', - FULLSCREEN: 'f', - PICTURE_IN_PICTURE: 'i', - LARGE_REWIND: 'j', - PLAY: 'k', - LARGE_FAST_FORWARD: 'l', - MUTE: 'm', - DECREASE_VIDEO_SPEED: 'o', - INCREASE_VIDEO_SPEED: 'p', - FULLWINDOW: 's', - THEATRE_MODE: 't', - TAKE_SCREENSHOT: 'u', - LAST_FRAME: ',', - NEXT_FRAME: '.', - VOLUME_UP: 'arrowup', - VOLUME_DOWN: 'arrowdown', - SMALL_REWIND: 'arrowleft', - SMALL_FAST_FORWARD: 'arrowright', - - /* For future use + GENERAL: { + CAPTIONS: 'c', + THEATRE_MODE: 't', + FULLSCREEN: 'f', + FULLWINDOW: 's', + PICTURE_IN_PICTURE: 'i', + MUTE: 'm', + VOLUME_UP: 'arrowup', + VOLUME_DOWN: 'arrowdown', + STATS: 'd', + TAKE_SCREENSHOT: 'u', + }, + PLAYBACK: { + PLAY: 'k', + LARGE_REWIND: 'j', + LARGE_FAST_FORWARD: 'l', + SMALL_REWIND: 'arrowleft', + SMALL_FAST_FORWARD: 'arrowright', + DECREASE_VIDEO_SPEED: 'o', + INCREASE_VIDEO_SPEED: 'p', + LAST_FRAME: ',', + NEXT_FRAME: '.', LAST_CHAPTER: 'ctrl+arrowleft', NEXT_CHAPTER: 'ctrl+arrowright', - */ + } }, } diff --git a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js index ff242914e65a9..c0c6ccb6700bd 100644 --- a/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js +++ b/src/renderer/components/ft-refresh-widget/ft-refresh-widget.js @@ -28,7 +28,7 @@ export default defineComponent({ refreshFeedButtonTitle: function() { return addKeyboardShortcutToActionTitle( this.$t('Feed.Refresh Feed', { subscriptionName: this.title }), - KeyboardShortcuts.FEED.REFRESH + KeyboardShortcuts.APP.SITUATIONAL.REFRESH ) } }, diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index eeb5de4f4aed0..45f83427af0a1 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -43,16 +43,16 @@ const AdvancedRequestType = shaka.net.NetworkingEngine.AdvancedRequestType const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat const shakaControlKeysToShortcuts = { - MUTE: KeyboardShortcuts.VIDEO_PLAYER.MUTE, - UNMUTE: KeyboardShortcuts.VIDEO_PLAYER.MUTE, - PLAY: KeyboardShortcuts.VIDEO_PLAYER.PLAY, - PAUSE: KeyboardShortcuts.VIDEO_PLAYER.PLAY, - PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, - ENTER_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, - EXIT_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE, - CAPTIONS: KeyboardShortcuts.VIDEO_PLAYER.CAPTIONS, - FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN, - EXIT_FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN + MUTE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.MUTE, + UNMUTE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.MUTE, + PLAY: KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.PLAY, + PAUSE: KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.PLAY, + PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.PICTURE_IN_PICTURE, + ENTER_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.PICTURE_IN_PICTURE, + EXIT_PICTURE_IN_PICTURE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.PICTURE_IN_PICTURE, + CAPTIONS: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.CAPTIONS, + FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLSCREEN, + EXIT_FULL_SCREEN: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLSCREEN } /** @type {Map} */ @@ -2017,44 +2017,44 @@ export default defineComponent({ switch (event.key.toLowerCase()) { case ' ': case 'spacebar': // older browsers might return spacebar instead of a space character - case KeyboardShortcuts.VIDEO_PLAYER.PLAY: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.PLAY: // Toggle Play/Pause event.preventDefault() video_.paused ? video_.play() : video_.pause() break - case KeyboardShortcuts.VIDEO_PLAYER.LARGE_REWIND: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.LARGE_REWIND: // Rewind by 2x the time-skip interval (in seconds) event.preventDefault() seekBySeconds(-defaultSkipInterval.value * video_.playbackRate * 2) break - case KeyboardShortcuts.VIDEO_PLAYER.LARGE_FAST_FORWARD: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.LARGE_FAST_FORWARD: // Fast-Forward by 2x the time-skip interval (in seconds) event.preventDefault() seekBySeconds(defaultSkipInterval.value * video_.playbackRate * 2) break - case KeyboardShortcuts.VIDEO_PLAYER.DECREASE_VIDEO_SPEED: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.DECREASE_VIDEO_SPEED: // Decrease playback rate by user configured interval event.preventDefault() changePlayBackRate(-videoPlaybackRateInterval.value) break - case KeyboardShortcuts.VIDEO_PLAYER.INCREASE_VIDEO_SPEED: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.INCREASE_VIDEO_SPEED: // Increase playback rate by user configured interval event.preventDefault() changePlayBackRate(videoPlaybackRateInterval.value) break - case KeyboardShortcuts.VIDEO_PLAYER.FULLSCREEN: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLSCREEN: // Toggle full screen event.preventDefault() ui.getControls().toggleFullScreen() break - case KeyboardShortcuts.VIDEO_PLAYER.MUTE: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.MUTE: // Toggle mute only if metakey is not pressed if (!event.metaKey) { event.preventDefault() video_.muted = !video_.muted } break - case KeyboardShortcuts.VIDEO_PLAYER.CAPTIONS: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.CAPTIONS: // Toggle caption/subtitles if (player.getTextTracks().length > 0) { event.preventDefault() @@ -2063,17 +2063,17 @@ export default defineComponent({ player.setTextTrackVisibility(!currentlyVisible) } break - case KeyboardShortcuts.VIDEO_PLAYER.VOLUME_UP: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.VOLUME_UP: // Increase volume event.preventDefault() changeVolume(0.05) break - case KeyboardShortcuts.VIDEO_PLAYER.VOLUME_DOWN: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.VOLUME_DOWN: // Decrease Volume event.preventDefault() changeVolume(-0.05) break - case KeyboardShortcuts.VIDEO_PLAYER.SMALL_REWIND: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.SMALL_REWIND: event.preventDefault() if (canChapterJump(event, 'previous')) { // Jump to the previous chapter @@ -2083,7 +2083,7 @@ export default defineComponent({ seekBySeconds(-defaultSkipInterval.value * video_.playbackRate) } break - case KeyboardShortcuts.VIDEO_PLAYER.SMALL_FAST_FORWARD: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.SMALL_FAST_FORWARD: event.preventDefault() if (canChapterJump(event, 'next')) { // Jump to the next chapter @@ -2093,7 +2093,7 @@ export default defineComponent({ seekBySeconds(defaultSkipInterval.value * video_.playbackRate) } break - case KeyboardShortcuts.VIDEO_PLAYER.PICTURE_IN_PICTURE: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.PICTURE_IN_PICTURE: // Toggle picture in picture if (props.format !== 'audio') { const controls = ui.getControls() @@ -2126,17 +2126,17 @@ export default defineComponent({ } break } - case KeyboardShortcuts.VIDEO_PLAYER.LAST_FRAME: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.LAST_FRAME: event.preventDefault() // Return to previous frame frameByFrame(-1) break - case KeyboardShortcuts.VIDEO_PLAYER.NEXT_FRAME: + case KeyboardShortcuts.VIDEO_PLAYER.PLAYBACK.NEXT_FRAME: event.preventDefault() // Advance to next frame frameByFrame(1) break - case KeyboardShortcuts.VIDEO_PLAYER.STATS: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.STATS: // Toggle stats display event.preventDefault() @@ -2154,14 +2154,14 @@ export default defineComponent({ })) } break - case KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLWINDOW: // Toggle full window mode event.preventDefault() events.dispatchEvent(new CustomEvent('setFullWindow', { detail: !fullWindowEnabled.value })) break - case KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.THEATRE_MODE: // Toggle theatre mode if (props.theatrePossible) { event.preventDefault() @@ -2171,7 +2171,7 @@ export default defineComponent({ })) } break - case KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT: + case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.TAKE_SCREENSHOT: if (process.env.IS_ELECTRON && enableScreenshot.value && props.format !== 'audio') { event.preventDefault() // Take screenshot diff --git a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js index abda948c23c45..bc176c17a0db5 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js @@ -80,7 +80,7 @@ export class FullWindowButton extends shaka.ui.Element { this.button_.ariaLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, - KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW + KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLWINDOW ) } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js index 0900c47f9514b..4a974f1f94cb8 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js @@ -53,7 +53,7 @@ export class ScreenshotButton extends shaka.ui.Element { updateLocalisedStrings_() { const label = addKeyboardShortcutToActionTitle( i18n.t('Video.Player.Take Screenshot'), - KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT + KeyboardShortcuts.VIDEO_PLAYER.GENERAL.TAKE_SCREENSHOT ) this.nameSpan_.textContent = label this.button_.ariaLabel = label diff --git a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js index dd3378b97e424..5f6dccc818e3e 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/StatsButton.js @@ -72,7 +72,7 @@ export class StatsButton extends shaka.ui.Element { const baseLabel = this.showStats_ ? i18n.t('Video.Player.Hide Stats') : i18n.t('Video.Player.Show Stats') const label = addKeyboardShortcutToActionTitle( baseLabel, - KeyboardShortcuts.VIDEO_PLAYER.STATS + KeyboardShortcuts.VIDEO_PLAYER.GENERAL.STATS ) this.currentState_.textContent = label diff --git a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js index 52237c1c5dd1a..370b7cd8d4223 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js @@ -79,7 +79,7 @@ export class TheatreModeButton extends shaka.ui.Element { this.button_.ariaLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, - KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE + KeyboardShortcuts.VIDEO_PLAYER.GENERAL.THEATRE_MODE ) } } diff --git a/src/renderer/components/side-nav/side-nav.js b/src/renderer/components/side-nav/side-nav.js index e791d870fb7f4..72aad5874e09b 100644 --- a/src/renderer/components/side-nav/side-nav.js +++ b/src/renderer/components/side-nav/side-nav.js @@ -84,8 +84,8 @@ export default defineComponent({ }, historyTitle: function() { const shortcut = process.platform === 'darwin' - ? KeyboardShortcuts.APP.NAVIGATE_TO_HISTORY_MAC - : KeyboardShortcuts.APP.NAVIGATE_TO_HISTORY + ? KeyboardShortcuts.APP.GENERAL.NAVIGATE_TO_HISTORY_MAC + : KeyboardShortcuts.APP.GENERAL.NAVIGATE_TO_HISTORY return localizeAndAddKeyboardShortcutToActionTitle( this.$t('History.History'), @@ -95,7 +95,7 @@ export default defineComponent({ settingsTitle: function() { return localizeAndAddKeyboardShortcutToActionTitle( this.$t('Settings.Settings'), - KeyboardShortcuts.APP.NAVIGATE_TO_SETTINGS + KeyboardShortcuts.APP.GENERAL.NAVIGATE_TO_SETTINGS ) } } diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js index b945e42b77b02..e6d9fb8cf7a70 100644 --- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js +++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js @@ -116,7 +116,7 @@ export default defineComponent({ switch (event.key.toLowerCase()) { case 'f5': - case KeyboardShortcuts.FEED.REFRESH: + case KeyboardShortcuts.APP.SITUATIONAL.REFRESH: if (!this.isLoading && this.activeSubscriptionList.length > 0) { this.$emit('refresh') } diff --git a/src/renderer/components/top-nav/top-nav.js b/src/renderer/components/top-nav/top-nav.js index a379644e5d6ac..da69066ed51a8 100644 --- a/src/renderer/components/top-nav/top-nav.js +++ b/src/renderer/components/top-nav/top-nav.js @@ -89,21 +89,21 @@ export default defineComponent({ forwardText: function () { return localizeAndAddKeyboardShortcutToActionTitle( this.$t('Forward'), - KeyboardShortcuts.APP.HISTORY_FORWARD + KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD ) }, backwardText: function () { return localizeAndAddKeyboardShortcutToActionTitle( this.$t('Back'), - KeyboardShortcuts.APP.HISTORY_BACKWARD + KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD ) }, newWindowText: function () { return localizeAndAddKeyboardShortcutToActionTitle( this.$t('Open New Window'), - KeyboardShortcuts.APP.NEW_WINDOW + KeyboardShortcuts.APP.GENERAL.NEW_WINDOW ) } }, diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js index 300c276f045d3..7ef0a2b01a4b0 100644 --- a/src/renderer/views/Popular/Popular.js +++ b/src/renderer/views/Popular/Popular.js @@ -93,7 +93,7 @@ export default defineComponent({ switch (event.key.toLowerCase()) { case 'f5': - case KeyboardShortcuts.FEED.REFRESH: + case KeyboardShortcuts.APP.SITUATIONAL.REFRESH: if (!this.isLoading) { this.fetchPopularInfo() } diff --git a/src/renderer/views/Trending/Trending.js b/src/renderer/views/Trending/Trending.js index 2cfd80b22beb6..425bb9ffd7d19 100644 --- a/src/renderer/views/Trending/Trending.js +++ b/src/renderer/views/Trending/Trending.js @@ -192,7 +192,7 @@ export default defineComponent({ switch (event.key.toLowerCase()) { case 'f5': - case KeyboardShortcuts.FEED.REFRESH: + case KeyboardShortcuts.APP.SITUATIONAL.REFRESH: if (!this.isLoading) { this.getTrendingInfo(true) } From 89b6861b7d09d2774d8577a2419ed261c55ab87c Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 23 Nov 2024 08:18:41 -0600 Subject: [PATCH 14/16] Adjust nameSpan._textContent to be set to same value as aria-label --- .../player-components/FullWindowButton.js | 7 ++----- .../player-components/ScreenshotButton.js | 3 +-- .../player-components/TheatreModeButton.js | 4 +--- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js index 8e3d37ebc8031..4b348db754fef 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/FullWindowButton.js @@ -69,17 +69,14 @@ export class FullWindowButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - this.nameSpan_.textContent = i18n.t('Video.Player.Full Window') - this.icon_.textContent = this.fullWindowEnabled_ ? 'close_fullscreen' : 'open_in_full' - this.currentState_.textContent = this.localization.resolve(this.fullWindowEnabled_ ? 'ON' : 'OFF') const baseAriaLabel = this.fullWindowEnabled_ ? i18n.t('Video.Player.Exit Full Window') : i18n.t('Video.Player.Full Window') - - this.button_.ariaLabel = addKeyboardShortcutToActionTitle( + const newLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, KeyboardShortcuts.VIDEO_PLAYER.FULLWINDOW ) + this.nameSpan_.textContent = this.button_.ariaLabel = newLabel } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js index 0900c47f9514b..d3a4735a9ec57 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/ScreenshotButton.js @@ -55,7 +55,6 @@ export class ScreenshotButton extends shaka.ui.Element { i18n.t('Video.Player.Take Screenshot'), KeyboardShortcuts.VIDEO_PLAYER.TAKE_SCREENSHOT ) - this.nameSpan_.textContent = label - this.button_.ariaLabel = label + this.nameSpan_.textContent = this.button_.ariaLabel = label } } diff --git a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js index 52237c1c5dd1a..a40a57013c256 100644 --- a/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js +++ b/src/renderer/components/ft-shaka-video-player/player-components/TheatreModeButton.js @@ -69,15 +69,13 @@ export class TheatreModeButton extends shaka.ui.Element { /** @private */ updateLocalisedStrings_() { - this.nameSpan_.textContent = i18n.t('Video.Player.Theatre Mode') - this.icon_.textContent = this.theatreModeEnabled_ ? 'monitor' : 'tv' this.currentState_.textContent = this.localization.resolve(this.theatreModeEnabled_ ? 'ON' : 'OFF') const baseAriaLabel = this.theatreModeEnabled_ ? i18n.t('Video.Player.Exit Theatre Mode') : i18n.t('Video.Player.Theatre Mode') - this.button_.ariaLabel = addKeyboardShortcutToActionTitle( + this.nameSpan_.textContent = this.button_.ariaLabel = addKeyboardShortcutToActionTitle( baseAriaLabel, KeyboardShortcuts.VIDEO_PLAYER.THEATRE_MODE ) From 304fa82fb3d9309d38520d3afeb33e804fab368a Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 23 Nov 2024 19:01:47 -0600 Subject: [PATCH 15/16] Add code comment explaining shakaControlKeysToShortcuts --- .../components/ft-shaka-video-player/ft-shaka-video-player.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index b63df0fa3f9cc..473f1005d9146 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -40,6 +40,10 @@ const RequestType = shaka.net.NetworkingEngine.RequestType const AdvancedRequestType = shaka.net.NetworkingEngine.AdvancedRequestType const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat +/* + Mapping of Shaka localization keys for control labels to FreeTube shortcuts. + See: https://github.com/shaka-project/shaka-player/blob/main/ui/locales/en.json +*/ const shakaControlKeysToShortcuts = { MUTE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.MUTE, UNMUTE: KeyboardShortcuts.VIDEO_PLAYER.GENERAL.MUTE, From 532fcc7b760d22151729a39f011c59c221ebf8a7 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Tue, 26 Nov 2024 17:09:59 -0500 Subject: [PATCH 16/16] Move changes from deleted Popular.js to Popular.vue --- src/renderer/views/Popular/Popular.js | 108 ------------------------- src/renderer/views/Popular/Popular.vue | 8 +- 2 files changed, 4 insertions(+), 112 deletions(-) delete mode 100644 src/renderer/views/Popular/Popular.js diff --git a/src/renderer/views/Popular/Popular.js b/src/renderer/views/Popular/Popular.js deleted file mode 100644 index 7ef0a2b01a4b0..0000000000000 --- a/src/renderer/views/Popular/Popular.js +++ /dev/null @@ -1,108 +0,0 @@ -import { defineComponent } from 'vue' -import { mapMutations } from 'vuex' -import FtLoader from '../../components/ft-loader/ft-loader.vue' -import FtCard from '../../components/ft-card/ft-card.vue' -import FtElementList from '../../components/FtElementList/FtElementList.vue' -import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue' -import FtRefreshWidget from '../../components/ft-refresh-widget/ft-refresh-widget.vue' - -import { invidiousAPICall } from '../../helpers/api/invidious' -import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils' -import { KeyboardShortcuts } from '../../../constants' - -export default defineComponent({ - name: 'Popular', - components: { - 'ft-loader': FtLoader, - 'ft-card': FtCard, - 'ft-element-list': FtElementList, - 'ft-icon-button': FtIconButton, - 'ft-refresh-widget': FtRefreshWidget, - }, - data: function () { - return { - isLoading: false, - shownResults: [] - } - }, - computed: { - lastPopularRefreshTimestamp: function () { - return getRelativeTimeFromDate(this.$store.getters.getLastPopularRefreshTimestamp, true) - }, - popularCache: function () { - return this.$store.getters.getPopularCache - } - }, - mounted: function () { - document.addEventListener('keydown', this.keyboardShortcutHandler) - - this.shownResults = this.popularCache || [] - if (!this.shownResults || this.shownResults.length < 1) { - this.fetchPopularInfo() - } - }, - beforeDestroy: function () { - document.removeEventListener('keydown', this.keyboardShortcutHandler) - }, - methods: { - fetchPopularInfo: async function () { - const searchPayload = { - resource: 'popular', - id: '', - params: {} - } - - this.isLoading = true - const result = await invidiousAPICall(searchPayload) - .catch((err) => { - const errorMessage = this.$t('Invidious API Error (Click to copy)') - showToast(`${errorMessage}: ${err}`, 10000, () => { - copyToClipboard(err) - }) - return undefined - }) - - if (!result) { - this.isLoading = false - return - } - - const items = result.filter((item) => { - return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist' - }) - setPublishedTimestampsInvidious(items.filter(item => item.type === 'video' || item.type === 'shortVideo')) - this.setLastPopularRefreshTimestamp(new Date()) - - this.shownResults = items - - this.isLoading = false - this.$store.commit('setPopularCache', items) - }, - - /** - * This function `keyboardShortcutHandler` should always be at the bottom of this file - * @param {KeyboardEvent} event the keyboard event - */ - keyboardShortcutHandler: function (event) { - if (event.ctrlKey || document.activeElement.classList.contains('ft-input')) { - return - } - // Avoid handling events due to user holding a key (not released) - // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat - if (event.repeat) { return } - - switch (event.key.toLowerCase()) { - case 'f5': - case KeyboardShortcuts.APP.SITUATIONAL.REFRESH: - if (!this.isLoading) { - this.fetchPopularInfo() - } - break - } - }, - - ...mapMutations([ - 'setLastPopularRefreshTimestamp' - ]) - } -}) diff --git a/src/renderer/views/Popular/Popular.vue b/src/renderer/views/Popular/Popular.vue index 66cdecfaf5c11..edc14b6e7f56d 100644 --- a/src/renderer/views/Popular/Popular.vue +++ b/src/renderer/views/Popular/Popular.vue @@ -35,6 +35,7 @@ import store from '../../store/index' import { invidiousAPICall } from '../../helpers/api/invidious' import { copyToClipboard, getRelativeTimeFromDate, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils' import { useI18n } from '../../composables/use-i18n-polyfill' +import { KeyboardShortcuts } from '../../../constants' const { t } = useI18n() @@ -107,10 +108,9 @@ function keyboardShortcutHandler(event) { // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat if (event.repeat) { return } - switch (event.key) { - case 'r': - case 'R': - case 'F5': + switch (event.key.toLowerCase()) { + case 'f5': + case KeyboardShortcuts.APP.SITUATIONAL.REFRESH: if (!isLoading.value) { fetchPopularInfo() }