Skip to content

Commit c2ce7be

Browse files
PikachuEXEOothecaPickle
authored andcommitted
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 033d9d7 commit c2ce7be

File tree

7 files changed

+116
-74
lines changed

7 files changed

+116
-74
lines changed

src/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ const KeyboardShortcuts = {
130130
SHOW_SHORTCUTS: 'shift+?',
131131
HISTORY_BACKWARD: 'alt+arrowleft',
132132
HISTORY_FORWARD: 'alt+arrowright',
133+
HISTORY_BACKWARD_ALT_MAC: 'cmd+[',
134+
HISTORY_FORWARD_ALT_MAC: 'cmd+]',
133135
FULLSCREEN: 'f11',
134136
NAVIGATE_TO_SETTINGS: 'ctrl+,',
135137
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'
@@ -1726,6 +1727,20 @@ function runApp() {
17261727
},
17271728
type: 'normal',
17281729
},
1730+
...(process.platform === 'darwin'
1731+
? [
1732+
{
1733+
label: 'Back',
1734+
accelerator: KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD_ALT_MAC,
1735+
click: (_menuItem, browserWindow, _event) => {
1736+
if (browserWindow == null) { return }
1737+
1738+
browserWindow.webContents.navigationHistory.goBack()
1739+
},
1740+
visible: false,
1741+
},
1742+
]
1743+
: []),
17291744
{
17301745
label: 'Forward',
17311746
accelerator: 'Alt+Right',
@@ -1736,6 +1751,20 @@ function runApp() {
17361751
},
17371752
type: 'normal',
17381753
},
1754+
...(process.platform === 'darwin'
1755+
? [
1756+
{
1757+
label: 'Forward',
1758+
accelerator: KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD_ALT_MAC,
1759+
click: (_menuItem, browserWindow, _event) => {
1760+
if (browserWindow == null) { return }
1761+
1762+
browserWindow.webContents.navigationHistory.goForward()
1763+
},
1764+
visible: false,
1765+
},
1766+
]
1767+
: []),
17391768
]
17401769
},
17411770
{

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
@@ -86,16 +86,26 @@ export default defineComponent({
8686
},
8787

8888
forwardText: function () {
89+
const shortcuts = [KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD]
90+
if (process.platform === 'darwin') {
91+
shortcuts.push(KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD_ALT_MAC)
92+
}
93+
8994
return localizeAndAddKeyboardShortcutToActionTitle(
9095
this.$t('Forward'),
91-
KeyboardShortcuts.APP.GENERAL.HISTORY_FORWARD
96+
shortcuts,
9297
)
9398
},
9499

95100
backwardText: function () {
101+
const shortcuts = [KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD]
102+
if (process.platform === 'darwin') {
103+
shortcuts.push(KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD_ALT_MAC)
104+
}
105+
96106
return localizeAndAddKeyboardShortcutToActionTitle(
97107
this.$t('Back'),
98-
KeyboardShortcuts.APP.GENERAL.HISTORY_BACKWARD
108+
shortcuts,
99109
)
100110
},
101111

src/renderer/helpers/utils.js

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

975975
/**
976976
* @param {string} localizedActionTitle
977-
* @param {string} unlocalizedShortcut
977+
* @param {string|string[]} sometimesManyUnlocalizedShortcuts
978978
* @returns {string} the localized action title with keyboard shortcut
979979
*/
980-
export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle, unlocalizedShortcut) {
981-
const localizedShortcut = getLocalizedShortcut(unlocalizedShortcut)
982-
return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcut)
980+
export function localizeAndAddKeyboardShortcutToActionTitle(localizedActionTitle, sometimesManyUnlocalizedShortcuts) {
981+
let unlocalizedShortcuts = sometimesManyUnlocalizedShortcuts
982+
if (!Array.isArray(sometimesManyUnlocalizedShortcuts)) {
983+
unlocalizedShortcuts = [unlocalizedShortcuts]
984+
}
985+
const localizedShortcuts = unlocalizedShortcuts.map((s) => getLocalizedShortcut(s))
986+
const shortcutLabelSeparator = i18n.t('shortcutLabelSeparator')
987+
return addKeyboardShortcutToActionTitle(localizedActionTitle, localizedShortcuts.join(shortcutLabelSeparator))
983988
}
984989

985990
/**

static/locales/en-US.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,7 @@ checkmark: ✓
11191119
Display Label: '{label}: {value}'
11201120
KeyboardShortcutTemplate: '{label} ({shortcut})'
11211121
shortcutJoinOperator: +
1122+
shortcutLabelSeparator: ''
11221123
Keys:
11231124
alt: Alt
11241125
ctrl: Ctrl

static/locales/ja.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -784,20 +784,11 @@ Video:
784784
MembersOnly: メンバー限定動画は Google にログインし、投稿チャンネルに課金する必要があるので FreeTube から直接見ることはできません。
785785
AgeRestricted: 年齢制限がかかっている 動画 は Google にログインしておりかつ年齢確認を済ましている YouTube アカウントが必要なため、FreeTube
786786
から直接見ることはできません。
787-
<<<<<<< HEAD
788-
Videos:
789-
#& Sort By
790-
Sort By:
791-
Newest: '新しい'
792-
Oldest: '古い'
793-
#& Most Popular
794-
=======
795787
DeArrow:
796788
Show Original Details: 元の情報を表示
797789
Show Modified Details: 変更された詳細を表示
798790
DRMProtected:
799791
DRM保護された動画はFreeTubeでは再生できません。これらの動画には、独自の非オープンソースのコンポーネントが必要です。この動画を視聴したい場合は、DRM対応のウェブブラウザで公式のYouTubeウェブサイトでご覧ください。
800-
>>>>>>> 2ce95b3c0 (Cleanup strings after auto-play changes (#6581))
801792
#& Playlists
802793
Playlist:
803794
#& About

0 commit comments

Comments
 (0)