Skip to content

Commit a97b2da

Browse files
PikachuEXEAlban Dumas
authored and
Alban Dumas
committed
Make Cmd left/right go back/forward (FreeTubeApp#6466)
* * Make Cmd left/right go back/forward * ! Fix wrong new shortcut * * Allow shortcut label separator to be translated * * Show one action per shortcut action with N shortcuts * * Remove duplicate entry, use array not map, remove unused locale entries, update shortcut separator
1 parent bb71292 commit a97b2da

File tree

6 files changed

+116
-65
lines changed

6 files changed

+116
-65
lines changed

src/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ const KeyboardShortcuts = {
131131
SHOW_SHORTCUTS: 'shift+?',
132132
HISTORY_BACKWARD: 'alt+arrowleft',
133133
HISTORY_FORWARD: 'alt+arrowright',
134+
HISTORY_BACKWARD_ALT_MAC: 'cmd+[',
135+
HISTORY_FORWARD_ALT_MAC: 'cmd+]',
134136
FULLSCREEN: 'f11',
135137
NAVIGATE_TO_SETTINGS: 'ctrl+,',
136138
NAVIGATE_TO_HISTORY: 'ctrl+H',

src/main/index.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
DBActions,
1212
SyncEvents,
1313
ABOUT_BITCOIN_ADDRESS,
14+
KeyboardShortcuts,
1415
} from '../constants'
1516
import * as baseHandlers from '../datastores/handlers/base'
1617
import { extractExpiryTimestamp, ImageCache } from './ImageCache'
@@ -1765,6 +1766,20 @@ function runApp() {
17651766
},
17661767
type: 'normal',
17671768
},
1769+
...(process.platform === 'darwin'
1770+
? [
1771+
{
1772+
label: 'Back',
1773+
accelerator: KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD_ALT_MAC,
1774+
click: (_menuItem, browserWindow, _event) => {
1775+
if (browserWindow == null) { return }
1776+
1777+
browserWindow.webContents.navigationHistory.goBack()
1778+
},
1779+
visible: false,
1780+
},
1781+
]
1782+
: []),
17681783
{
17691784
label: 'Forward',
17701785
accelerator: 'Alt+Right',
@@ -1775,6 +1790,20 @@ function runApp() {
17751790
},
17761791
type: 'normal',
17771792
},
1793+
...(process.platform === 'darwin'
1794+
? [
1795+
{
1796+
label: 'Forward',
1797+
accelerator: KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD_ALT_MAC,
1798+
click: (_menuItem, browserWindow, _event) => {
1799+
if (browserWindow == null) { return }
1800+
1801+
browserWindow.webContents.navigationHistory.goForward()
1802+
},
1803+
visible: false,
1804+
},
1805+
]
1806+
: []),
17781807
]
17791808
},
17801809
{

src/renderer/components/FtKeyboardShortcutPrompt/FtKeyboardShortcutPrompt.vue

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -113,73 +113,77 @@ const primarySections = computed(() => [
113113
114114
const isMac = process.platform === 'darwin'
115115
116-
const localizedShortcutNameDictionary = computed(() => {
117-
return new Map([
118-
['SHOW_SHORTCUTS', t('KeyboardShortcutPrompt.Show Keyboard Shortcuts')],
119-
['HISTORY_BACKWARD', t('KeyboardShortcutPrompt.History Backward')],
120-
['HISTORY_FORWARD', t('KeyboardShortcutPrompt.History Forward')],
121-
['FULLSCREEN', t('KeyboardShortcutPrompt.Fullscreen')],
122-
['NAVIGATE_TO_SETTINGS', t('KeyboardShortcutPrompt.Navigate to Settings')],
123-
(
124-
isMac
125-
? ['NAVIGATE_TO_HISTORY_MAC', t('KeyboardShortcutPrompt.Navigate to History')]
126-
: ['NAVIGATE_TO_HISTORY', t('KeyboardShortcutPrompt.Navigate to History')]
127-
),
128-
['NEW_WINDOW', t('KeyboardShortcutPrompt.New Window')],
129-
['MINIMIZE_WINDOW', t('KeyboardShortcutPrompt.Minimize Window')],
130-
['CLOSE_WINDOW', t('KeyboardShortcutPrompt.Close Window')],
131-
['RESTART_WINDOW', t('KeyboardShortcutPrompt.Restart Window')],
132-
['FORCE_RESTART_WINDOW', t('KeyboardShortcutPrompt.Force Restart Window')],
133-
['TOGGLE_DEVTOOLS', t('KeyboardShortcutPrompt.Toggle Developer Tools')],
134-
['RESET_ZOOM', t('KeyboardShortcutPrompt.Reset Zoom')],
135-
['ZOOM_IN', t('KeyboardShortcutPrompt.Zoom In')],
136-
['ZOOM_OUT', t('KeyboardShortcutPrompt.Zoom Out')],
137-
['FOCUS_SEARCH', t('KeyboardShortcutPrompt.Focus Search')],
138-
['SEARCH_IN_NEW_WINDOW', t('KeyboardShortcutPrompt.Search in New Window')],
139-
140-
['REFRESH', t('KeyboardShortcutPrompt.Refresh')],
141-
['FOCUS_SECONDARY_SEARCH', t('KeyboardShortcutPrompt.Focus Secondary Search')],
142-
143-
['CAPTIONS', t('KeyboardShortcutPrompt.Captions')],
144-
['THEATRE_MODE', t('KeyboardShortcutPrompt.Theatre Mode')],
145-
['FULLSCREEN', t('KeyboardShortcutPrompt.Fullscreen')],
146-
['FULLWINDOW', t('KeyboardShortcutPrompt.Full Window')],
147-
['PICTURE_IN_PICTURE', t('KeyboardShortcutPrompt.Picture in Picture')],
148-
['MUTE', t('KeyboardShortcutPrompt.Mute')],
149-
['VOLUME_UP', t('KeyboardShortcutPrompt.Volume Up')],
150-
['VOLUME_DOWN', t('KeyboardShortcutPrompt.Volume Down')],
151-
['TAKE_SCREENSHOT', t('KeyboardShortcutPrompt.Take Screenshot')],
152-
['STATS', t('KeyboardShortcutPrompt.Stats')],
153-
154-
['PLAY', t('KeyboardShortcutPrompt.Play')],
155-
['LARGE_REWIND', t('KeyboardShortcutPrompt.Large Rewind')],
156-
['LARGE_FAST_FORWARD', t('KeyboardShortcutPrompt.Large Fast Forward')],
157-
['SMALL_REWIND', t('KeyboardShortcutPrompt.Small Rewind')],
158-
['SMALL_FAST_FORWARD', t('KeyboardShortcutPrompt.Small Fast Forward')],
159-
['DECREASE_VIDEO_SPEED', t('KeyboardShortcutPrompt.Decrease Video Speed')],
160-
['INCREASE_VIDEO_SPEED', t('KeyboardShortcutPrompt.Increase Video Speed')],
161-
['SKIP_N_TENTHS', t('KeyboardShortcutPrompt.Skip by Tenths')],
162-
['LAST_CHAPTER', t('KeyboardShortcutPrompt.Last Chapter')],
163-
['NEXT_CHAPTER', t('KeyboardShortcutPrompt.Next Chapter')],
164-
['LAST_FRAME', t('KeyboardShortcutPrompt.Last Frame')],
165-
['NEXT_FRAME', t('KeyboardShortcutPrompt.Next Frame')],
166-
])
116+
const localizedShortcutNameToShortcutsMappings = computed(() => {
117+
return [
118+
[t('KeyboardShortcutPrompt.Show Keyboard Shortcuts'), ['SHOW_SHORTCUTS']],
119+
[t('KeyboardShortcutPrompt.History Backward'), [
120+
'HISTORY_BACKWARD',
121+
...isMac ? ['HISTORY_BACKWARD_ALT_MAC'] : [],
122+
]],
123+
[t('KeyboardShortcutPrompt.History Forward'), [
124+
'HISTORY_FORWARD',
125+
...isMac ? ['HISTORY_FORWARD_ALT_MAC'] : [],
126+
]],
127+
[t('KeyboardShortcutPrompt.Navigate to Settings'), ['NAVIGATE_TO_SETTINGS']],
128+
[t('KeyboardShortcutPrompt.Navigate to History'), [
129+
isMac ? 'NAVIGATE_TO_HISTORY_MAC' : 'NAVIGATE_TO_HISTORY',
130+
]],
131+
[t('KeyboardShortcutPrompt.New Window'), ['NEW_WINDOW']],
132+
[t('KeyboardShortcutPrompt.Minimize Window'), ['MINIMIZE_WINDOW']],
133+
[t('KeyboardShortcutPrompt.Close Window'), ['CLOSE_WINDOW']],
134+
[t('KeyboardShortcutPrompt.Restart Window'), ['RESTART_WINDOW']],
135+
[t('KeyboardShortcutPrompt.Force Restart Window'), ['FORCE_RESTART_WINDOW']],
136+
[t('KeyboardShortcutPrompt.Toggle Developer Tools'), ['TOGGLE_DEVTOOLS']],
137+
[t('KeyboardShortcutPrompt.Reset Zoom'), ['RESET_ZOOM']],
138+
[t('KeyboardShortcutPrompt.Zoom In'), ['ZOOM_IN']],
139+
[t('KeyboardShortcutPrompt.Zoom Out'), ['ZOOM_OUT']],
140+
[t('KeyboardShortcutPrompt.Focus Search'), ['FOCUS_SEARCH']],
141+
[t('KeyboardShortcutPrompt.Search in New Window'), ['SEARCH_IN_NEW_WINDOW']],
142+
143+
[t('KeyboardShortcutPrompt.Refresh'), ['REFRESH']],
144+
[t('KeyboardShortcutPrompt.Focus Secondary Search'), ['FOCUS_SECONDARY_SEARCH']],
145+
146+
[t('KeyboardShortcutPrompt.Captions'), ['CAPTIONS']],
147+
[t('KeyboardShortcutPrompt.Theatre Mode'), ['THEATRE_MODE']],
148+
[t('KeyboardShortcutPrompt.Fullscreen'), ['FULLSCREEN']],
149+
[t('KeyboardShortcutPrompt.Full Window'), ['FULLWINDOW']],
150+
[t('KeyboardShortcutPrompt.Picture in Picture'), ['PICTURE_IN_PICTURE']],
151+
[t('KeyboardShortcutPrompt.Mute'), ['MUTE']],
152+
[t('KeyboardShortcutPrompt.Volume Up'), ['VOLUME_UP']],
153+
[t('KeyboardShortcutPrompt.Volume Down'), ['VOLUME_DOWN']],
154+
[t('KeyboardShortcutPrompt.Take Screenshot'), ['TAKE_SCREENSHOT']],
155+
[t('KeyboardShortcutPrompt.Stats'), ['STATS']],
156+
157+
[t('KeyboardShortcutPrompt.Play'), ['PLAY']],
158+
[t('KeyboardShortcutPrompt.Large Rewind'), ['LARGE_REWIND']],
159+
[t('KeyboardShortcutPrompt.Large Fast Forward'), ['LARGE_FAST_FORWARD']],
160+
[t('KeyboardShortcutPrompt.Small Rewind'), ['SMALL_REWIND']],
161+
[t('KeyboardShortcutPrompt.Small Fast Forward'), ['SMALL_FAST_FORWARD']],
162+
[t('KeyboardShortcutPrompt.Decrease Video Speed'), ['DECREASE_VIDEO_SPEED']],
163+
[t('KeyboardShortcutPrompt.Increase Video Speed'), ['INCREASE_VIDEO_SPEED']],
164+
[t('KeyboardShortcutPrompt.Skip by Tenths'), ['SKIP_N_TENTHS']],
165+
[t('KeyboardShortcutPrompt.Last Chapter'), ['LAST_CHAPTER']],
166+
[t('KeyboardShortcutPrompt.Next Chapter'), ['NEXT_CHAPTER']],
167+
[t('KeyboardShortcutPrompt.Last Frame'), ['LAST_FRAME']],
168+
[t('KeyboardShortcutPrompt.Next Frame'), ['NEXT_FRAME']],
169+
]
167170
})
168171
169172
function hideKeyboardShortcutPrompt() {
170173
store.dispatch('hideKeyboardShortcutPrompt')
171174
}
172175
173176
function getLocalizedShortcutNamesAndValues(dictionary) {
174-
const localizedDictionary = localizedShortcutNameDictionary.value
175-
return Object.entries(dictionary)
176-
.filter(([key]) =>
177-
localizedDictionary.has(key)
177+
const shortcutNameToShortcutsMappings = localizedShortcutNameToShortcutsMappings.value
178+
const shortcutLabelSeparator = t('shortcutLabelSeparator')
179+
180+
return shortcutNameToShortcutsMappings
181+
.filter(([_localizedShortcutName, shortcutCodes]) =>
182+
shortcutCodes.some(shortcutCode => Object.hasOwn(dictionary, shortcutCode))
178183
)
179-
.map(([shortcutNameKey, shortcut]) => {
180-
const localizedShortcutName = localizedDictionary.get(shortcutNameKey)
181-
const localizedShortcut = getLocalizedShortcut(shortcut)
182-
return [localizedShortcutName, localizedShortcut]
184+
.map(([localizedShortcutName, shortcutCodes]) => {
185+
const localizedShortcuts = shortcutCodes.map(code => getLocalizedShortcut(dictionary[code]))
186+
return [localizedShortcutName, localizedShortcuts.join(shortcutLabelSeparator)]
183187
})
184188
}
185189

src/renderer/components/top-nav/top-nav.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,26 @@ export default defineComponent({
100100
},
101101

102102
forwardText: function () {
103+
const shortcuts = [KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD]
104+
if (process.platform === 'darwin') {
105+
shortcuts.push(KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD_ALT_MAC)
106+
}
107+
103108
return localizeAndAddKeyboardShortcutToActionTitle(
104109
this.$t('Forward'),
105-
KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD
110+
shortcuts,
106111
) + this.navigationHistoryAddendum
107112
},
108113

109114
backwardText: function () {
115+
const shortcuts = [KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD]
116+
if (process.platform === 'darwin') {
117+
shortcuts.push(KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD_ALT_MAC)
118+
}
119+
110120
return localizeAndAddKeyboardShortcutToActionTitle(
111121
this.$t('Back'),
112-
KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD
122+
shortcuts,
113123
) + this.navigationHistoryAddendum
114124
},
115125

src/renderer/helpers/utils.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,12 +1023,17 @@ export function addKeyboardShortcutToActionTitle(actionTitle, shortcut) {
10231023

10241024
/**
10251025
* @param {string} localizedActionTitle
1026-
* @param {string} unlocalizedShortcut
1026+
* @param {string|string[]} sometimesManyUnlocalizedShortcuts
10271027
* @returns {string} the localized action title with keyboard shortcut
10281028
*/
1029-
export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle, unlocalizedShortcut) {
1030-
const localizedShortcut = getLocalizedShortcut(unlocalizedShortcut)
1031-
return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcut)
1029+
export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle, sometimesManyUnlocalizedShortcuts) {
1030+
let unlocalizedShortcuts = sometimesManyUnlocalizedShortcuts
1031+
if (!Array.isArray(sometimesManyUnlocalizedShortcuts)) {
1032+
unlocalizedShortcuts = [unlocalizedShortcuts]
1033+
}
1034+
const localizedShortcuts = unlocalizedShortcuts.map((s) => getLocalizedShortcut(s))
1035+
const shortcutLabelSeparator = i18n.t('shortcutLabelSeparator')
1036+
return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcuts.join(shortcutLabelSeparator))
10321037
}
10331038

10341039
/**

static/locales/en-US.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,7 @@ checkmark: ✓
11171117
Display Label: '{label}: {value}'
11181118
KeyboardShortcutTemplate: '{label} ({shortcut})'
11191119
shortcutJoinOperator: +
1120+
shortcutLabelSeparator: ''
11201121
Keys:
11211122
alt: Alt
11221123
ctrl: Ctrl

0 commit comments

Comments
 (0)