yarr/src/assets/javascripts/keybindings.js
2021-03-03 12:52:41 +00:00

106 lines
3.1 KiB
JavaScript

const helperFunctions = {
// navigation helper, navigate relative to selected item
navigateToItem: function(relativePosition) {
if(vm.itemSelected == null){
if(vm.items.length !== 0) {
// if no item is selected, select first
vm.itemSelected = vm.items[0].id
}
return
}
const itemPosition = vm.items.findIndex(x=>x.id==vm.itemSelected)
if(itemPosition == -1){
// Item not found error
return
}
const newPosition = itemPosition+relativePosition
if(newPosition < 0 || newPosition >= vm.items.length){
return
}
vm.itemSelected = vm.items[newPosition].id
},
// navigation helper, navigate relative to selected feed
navigateToFeed: function(relativePosition) {
// create a list with feed and folders guids, ignore feeds in collapsed folders
// Example result with folder 2 collapsed:
// ['folder:1','feed:1','feed:2','folder:2', 'folder:3','feed:3']
const navigationList = vm.foldersWithFeeds.map(
folder =>
folder.is_expanded
? ['folder:'+folder.id].concat(folder.feeds.map(feed=>'feed:'+feed.id))
: 'folder:'+folder.id
).flat()
const currentFeedPosition = navigationList.indexOf(vm.feedSelected)
if(currentFeedPosition== -1){
// feed not found error
return
}
const newPosition = currentFeedPosition+relativePosition
if(newPosition < 0 || newPosition >= navigationList.length){
return
}
vm.feedSelected = navigationList[newPosition];
}
}
const shortcutFunctions = {
toggleItemRead: function() {
if(vm.itemSelected != null) {
vm.toggleItemRead(vm.itemSelectedDetails)
}
},
toggleItemStarred: function() {
if(vm.itemSelected != null) {
vm.toggleItemStarred(vm.itemSelectedDetails)
}
},
focusSearch: function() {
document.getElementById("searchbar").focus()
},
nextItem(){
helperFunctions.navigateToItem(+1)
},
previousItem() {
helperFunctions.navigateToItem(-1)
},
nextFeed(){
helperFunctions.navigateToFeed(+1)
},
previousFeed() {
helperFunctions.navigateToFeed(-1)
},
}
const keybindings = {
"r": shortcutFunctions.toggleItemRead,
"s": shortcutFunctions.toggleItemStarred,
"?": shortcutFunctions.focusSearch,
"j": shortcutFunctions.nextItem,
"k": shortcutFunctions.previousItem,
"l": shortcutFunctions.nextFeed,
"h": shortcutFunctions.previousFeed,
}
function isTextBox(element) {
var tagName = element.tagName.toLowerCase()
// Input elements that aren't text
const inputBlocklist = ['button','checkbox','color','file','hidden','image','radio','range','reset','search','submit']
return tagName === 'textarea' ||
( tagName === 'input'
&& !inputBlocklist.includes(element.getAttribute('type').toLowerCase())
)
}
document.addEventListener('keydown',function(event) {
// Ignore while focused on text or
// when using modifier keys (to not clash with browser behaviour)
if(isTextBox(event.target) || event.metaKey || event.ctrlKey) {
return
}
const keybindFunction = keybindings[event.key]
if(keybindFunction) {
event.preventDefault()
keybindFunction()
}
})