mirror of
https://github.com/nkanaev/yarr.git
synced 2025-05-24 00:33:14 +00:00
106 lines
3.1 KiB
JavaScript
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()
|
|
}
|
|
})
|