-
Notifications
You must be signed in to change notification settings - Fork 1.2k
VIM-like Navigation #7336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
VIM-like Navigation #7336
Conversation
I’m a bit concerned that the new PR might end up getting abandoned just like the previous one, especially since it was abandoned after one day. I’m worried that reviewing it might end up being a waste of time if it gets discarded again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first glace there are a few issues with this pull request:
- Please fix the invalid code (referencing variables that you didn't actually create), missing translation strings and wrong indentation pointed out by the linter.
- The title of this pull request is misleading, it sounds like you are just implementing VIM waypoints but this actually changes various keyboard shortcuts, which personally I don't think is a good idea unless it is made extremely obvious to the user that that is what is happening.
- Please choose a unique keyboard shortcuts to show and hide the waypoints as well as for the other VIM interactions such as scrolling, they should not conflict with the existing keyboard shortcuts and hotkeys. Alternatively you could ensure that these VIM hotkeys are disabled on the watch page or make it very obvious to the user that the behaviour of various well-known keyboard shortcuts and hot keys will change when the VIM setting is enabled.
- Please don't unnecessarily place functions inside of functions, as that will result in the inner functions getting treated like variables and recreated every time the outer function is called.
- While a prompt is open only things inside that prompt can be triggered but this will show waypoints even on things that are not accessible while prompts are open.
src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js
Outdated
Show resolved
Hide resolved
Head branch was pushed to by a user without write access
Head branch was pushed to by a user without write access
Instead of pushing and commenting after every single commit, please just do one push and comment at the end, so that we don't get spammed with notifications. |
Head branch was pushed to by a user without write access
Co-authored-by: absidue <[email protected]>
Head branch was pushed to by a user without write access
Head branch was pushed to by a user without write access
Conflicts have been resolved. A maintainer will review the pull request shortly. |
Head branch was pushed to by a user without write access
When I press t in the development branch, it toggles the playback of the video, are you sure it's being used for theater mode? |
Yes, I am, because this is where the FreeTube/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js Lines 2260 to 2269 in e2a53d0
|
I'm saying when you open the video player and press t, it toggles the playback, not theater mode. |
For me it only does theatre mode, it doesn't pause or play the video. |
That could be a bug then because for me it toggles the playback. |
There is no bug in the dev branch. You can verify that by looking at the code yourself |
I see that you commited something to the dev branch. That info in available to me through GH. This tends me to believe that you have made more commits locally to your dev branch. |
Head branch was pushed to by a user without write access
Head branch was pushed to by a user without write access
Head branch was pushed to by a user without write access
|
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When adding a new optional setting, especially one as invasive as this one, please remember to test with the setting disabled too.
// If this.areVimWaypointsShown.selector starts with an f it means | ||
// the user is in nav mode so capture any input and pass it to | ||
// setAreVimWaypointsShown | ||
if (this.areVimWaypointsShown.selector[0] === 'w' && !event.ctrlKey && this.enableVimNavigation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reorder the checks (not just in this if) so that the check for the setting is first. For people that have the setting enabled it won't change anything, but for people that have it disabled it skips having to do unnecessary checks.
@@ -81,6 +81,10 @@ const situationalAppShortcuts = computed(() => | |||
getLocalizedShortcutNamesAndValues(KeyboardShortcuts.APP.SITUATIONAL) | |||
) | |||
const VimAppShortcuts = computed(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow the naming conventions that are used in the rest of the code base (remember to rename the references to this variable too).
const VimAppShortcuts = computed(() => | |
const vimAppShortcuts = computed(() => |
.proxy-warning, | ||
.vim-warning { | ||
padding-block: 12px; | ||
padding-inline: 4%; | ||
background-color: var(--accent-color); | ||
color: var(--text-with-accent-color); | ||
font-weight: bold; | ||
} | ||
|
||
.vim-warning { | ||
margin-block: 1px; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you add CSS to the proxy settings, when your changes are in the general settings?
@@ -2130,7 +2147,7 @@ export default defineComponent({ | |||
event.preventDefault() | |||
changePlayBackRate(videoPlaybackRateInterval.value) | |||
break | |||
case KeyboardShortcuts.VIDEO_PLAYER.GENERAL.FULLSCREEN: | |||
case KeyboardShortcuts.VIDEO_PLAYER.GENERAL['FULLSCREEN']: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert
<p class="vim-warning"> | ||
<FontAwesomeIcon | ||
:icon="['fas', 'circle-exclamation']" | ||
class="warning-icon" | ||
fixed-width | ||
/> | ||
{{ $t('Settings.General Settings.VIM Warning') }} | ||
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This warning should only be shown when the setting is enabled. Just like with the checks inside the ifs, when the setting is disabled, the app and code should also act like it is disabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid confusing users, the VIM specific shortcuts should be hidden in the popup when the setting is disabled.
@@ -344,20 +351,59 @@ export default defineComponent({ | |||
}, | |||
|
|||
activateKeyboardShortcuts: function () { | |||
if (this.enableVimNavigation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently one has to restart the app after the setting is enabled and disabled, please change this so the listeners are added and removed when the setting is changed. Also keep in mind that anything that is still on screen such as the way points have to be cleaned up when the setting is disabled.
showVimWaypoints({ commit }) { | ||
commit('setAreVimWaypointsShown', ['w']) | ||
}, | ||
|
||
hideVimWaypoints({ commit }) { | ||
commit('setAreVimWaypointsShown', []) | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are never used, please revert.
function close() { | ||
document.querySelectorAll('.vimHint').forEach((el) => el.remove()) | ||
state.areVimWaypointsShown.selector = [] | ||
} | ||
|
||
function numberToHintStr(number, chars, digits = 0) { | ||
const base = chars.length | ||
let hintStr = '' | ||
let remainder = 0 | ||
|
||
do { | ||
remainder = number % base | ||
hintStr = chars[remainder] + hintStr // Unshift using string operations | ||
number = Math.floor(number / base) | ||
} while (number > 0) | ||
|
||
// Use padStart to ensure the string is at least 'digits' in length. | ||
hintStr = hintStr.padStart(digits, chars[0]) | ||
|
||
return hintStr | ||
} | ||
|
||
// Example usage: Generate hints for all link elements | ||
function generateHints(minChars, chars) { | ||
// Get all anchor (A) elements from the document. | ||
const elems = (document.querySelector('.prompt') || document).querySelectorAll( | ||
'a, button, [type="button"], [type="submit"], [role="tab"], [role="button"], input[type="text"], [role="link"]' | ||
) | ||
const numLinks = elems.length | ||
|
||
// Determine the minimum number of digits needed for the hints. | ||
const needed = Math.max(minChars, Math.ceil(Math.log(numLinks) / Math.log(chars.length))) | ||
|
||
let shortCount = 0 | ||
if (needed > minChars && needed > 1) { | ||
const totalSpace = Math.pow(chars.length, needed) | ||
shortCount = Math.floor((totalSpace - numLinks) / (chars.length - 1)) | ||
} | ||
|
||
const longCount = numLinks - shortCount | ||
const hints = [] | ||
|
||
if (needed > 1) { | ||
for (let i = 0; i < shortCount; i++) { | ||
hints.push(numberToHintStr(i, chars, needed - 1)) | ||
} | ||
} | ||
|
||
const start = shortCount * chars.length | ||
for (let i = start; i < start + longCount; i++) { | ||
hints.push(numberToHintStr(i, chars, needed)) | ||
} | ||
|
||
return hints | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As was already mentioned in a previous review, please don't nest functions inside of functions. Not only does it make the code messier and less readable, but it also forces the JavaScript runtime to redefine the functions each time the outer one is called.
const hintStyles = { | ||
position: 'absolute', | ||
background: 'linear-gradient(to bottom, #fff204 0%, #d8cb03 100%)', | ||
fontSize: '13px', | ||
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif', | ||
fontWeight: '600', | ||
borderRadius: '3px', | ||
color: 'black', | ||
zIndex: '10000', // Ensure it is above other content | ||
padding: '1px 2px', | ||
letterSpacing: '0.5px', | ||
display: 'flex' // Use flexbox for letter alignment | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you are already assigning a class to this element, it would make a lot more sense to put the CSS in the App.css file. You'll need to use the :deep()
selector as you are creating these elements outside of Vue.
Will have a look. |
VIM Navigation
Pull Request Type
Related issue
#251 (comment)
#1864
Closes #1864
Description
Implements VIM-like key-bindings, similar to Vimium.
Screenshots
Testing
I tested this with basic usage. Navigating to both general and video player keybinding contexts.
Desktop
Additional context
Any conflicting native keybindings will change when vim navigation is enabled. The change will reflect in the keyboard shortcuts modal (Shift + ?). I've yet to implement back and forth page navigation but it should be pretty easy.
Note that there's a prior iteration of this PR in which it was requested that any custom formatting be removed, this is the follow up to that.