mirror of
https://github.com/nkanaev/yarr.git
synced 2025-11-07 18:09:36 +00:00
rename keybindings -> key
This commit is contained in:
186
src/assets/javascripts/key.js
Normal file
186
src/assets/javascripts/key.js
Normal file
@@ -0,0 +1,186 @@
|
||||
function scrollto(target, scroll) {
|
||||
var padding = 10
|
||||
var targetRect = target.getBoundingClientRect()
|
||||
var scrollRect = scroll.getBoundingClientRect()
|
||||
|
||||
// target
|
||||
var relativeOffset = targetRect.y - scrollRect.y
|
||||
var absoluteOffset = relativeOffset + scroll.scrollTop
|
||||
|
||||
if (padding <= relativeOffset && relativeOffset + targetRect.height <= scrollRect.height - padding) return
|
||||
|
||||
var newPos = scroll.scrollTop
|
||||
if (relativeOffset < padding) {
|
||||
newPos = absoluteOffset - padding
|
||||
} else {
|
||||
newPos = absoluteOffset - scrollRect.height + targetRect.height + padding
|
||||
}
|
||||
scroll.scrollTop = Math.round(newPos)
|
||||
}
|
||||
|
||||
var helperFunctions = {
|
||||
// navigation helper, navigate relative to selected item
|
||||
navigateToItem: function(relativePosition) {
|
||||
if (vm.itemSelected == null) {
|
||||
// if no item is selected, select first
|
||||
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
||||
return
|
||||
}
|
||||
|
||||
var itemPosition = vm.items.findIndex(function(x) { return x.id === vm.itemSelected })
|
||||
if (itemPosition === -1) {
|
||||
if (vm.items.length !== 0) vm.itemSelected = vm.items[0].id
|
||||
return
|
||||
}
|
||||
|
||||
var newPosition = itemPosition + relativePosition
|
||||
if (newPosition < 0 || newPosition >= vm.items.length) return
|
||||
|
||||
vm.itemSelected = vm.items[newPosition].id
|
||||
|
||||
vm.$nextTick(function() {
|
||||
var scroll = document.querySelector('#item-list-scroll')
|
||||
|
||||
var handle = scroll.querySelector('input[type=radio]:checked')
|
||||
var target = handle && handle.parentElement
|
||||
|
||||
if (target && scroll) scrollto(target, scroll)
|
||||
})
|
||||
},
|
||||
// navigation helper, navigate relative to selected feed
|
||||
navigateToFeed: function(relativePosition) {
|
||||
var navigationList = Array.from(document.querySelectorAll('#col-feed-list input[name=feed]'))
|
||||
.filter(function(r) { return r.offsetParent !== null && r.value !== 'folder:null' })
|
||||
.map(function(r) { return r.value })
|
||||
|
||||
var currentFeedPosition = navigationList.indexOf(vm.feedSelected)
|
||||
|
||||
if (currentFeedPosition == -1) {
|
||||
vm.feedSelected = ''
|
||||
return
|
||||
}
|
||||
|
||||
var newPosition = currentFeedPosition+relativePosition
|
||||
if (newPosition < 0 || newPosition >= navigationList.length) return
|
||||
|
||||
vm.feedSelected = navigationList[newPosition]
|
||||
|
||||
vm.$nextTick(function() {
|
||||
var scroll = document.querySelector('#feed-list-scroll')
|
||||
|
||||
var handle = scroll.querySelector('input[type=radio]:checked')
|
||||
var target = handle && handle.parentElement
|
||||
|
||||
if (target && scroll) scrollto(target, scroll)
|
||||
})
|
||||
},
|
||||
scrollContent: function(direction) {
|
||||
var padding = 40
|
||||
var scroll = document.querySelector('.content')
|
||||
if (!scroll) return
|
||||
|
||||
var height = scroll.getBoundingClientRect().height
|
||||
var newpos = scroll.scrollTop + (height - padding) * direction
|
||||
|
||||
if (typeof scroll.scrollTo == 'function') {
|
||||
scroll.scrollTo({top: newpos, left: 0, behavior: 'smooth'})
|
||||
} else {
|
||||
scroll.scrollTop = newpos
|
||||
}
|
||||
}
|
||||
}
|
||||
var shortcutFunctions = {
|
||||
openItemLink: function() {
|
||||
if (vm.itemSelectedDetails && vm.itemSelectedDetails.link) {
|
||||
window.open(vm.itemSelectedDetails.link, '_blank')
|
||||
}
|
||||
},
|
||||
toggleItemRead: function() {
|
||||
if (vm.itemSelected != null) {
|
||||
vm.toggleItemRead(vm.itemSelectedDetails)
|
||||
}
|
||||
},
|
||||
markAllRead: function() {
|
||||
// same condition as 'Mark all read button'
|
||||
if (vm.filterSelected == 'unread'){
|
||||
vm.markItemsRead()
|
||||
}
|
||||
},
|
||||
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)
|
||||
},
|
||||
scrollForward: function() {
|
||||
helperFunctions.scrollContent(+1)
|
||||
},
|
||||
scrollBackward: function() {
|
||||
helperFunctions.scrollContent(-1)
|
||||
},
|
||||
showAll() {
|
||||
vm.filterSelected = ''
|
||||
},
|
||||
showUnread() {
|
||||
vm.filterSelected = 'unread'
|
||||
},
|
||||
showStarred() {
|
||||
vm.filterSelected = 'starred'
|
||||
},
|
||||
}
|
||||
|
||||
// If you edit, make sure you update the help modal
|
||||
var keybindings = {
|
||||
"o": shortcutFunctions.openItemLink,
|
||||
"r": shortcutFunctions.toggleItemRead,
|
||||
"R": shortcutFunctions.markAllRead,
|
||||
"s": shortcutFunctions.toggleItemStarred,
|
||||
"/": shortcutFunctions.focusSearch,
|
||||
"j": shortcutFunctions.nextItem,
|
||||
"k": shortcutFunctions.previousItem,
|
||||
"l": shortcutFunctions.nextFeed,
|
||||
"h": shortcutFunctions.previousFeed,
|
||||
"f": shortcutFunctions.scrollForward,
|
||||
"b": shortcutFunctions.scrollBackward,
|
||||
"1": shortcutFunctions.showUnread,
|
||||
"2": shortcutFunctions.showStarred,
|
||||
"3": shortcutFunctions.showAll,
|
||||
}
|
||||
|
||||
function isTextBox(element) {
|
||||
var tagName = element.tagName.toLowerCase()
|
||||
// Input elements that aren't text
|
||||
var inputBlocklist = ['button','checkbox','color','file','hidden','image','radio','range','reset','search','submit']
|
||||
|
||||
return tagName === 'textarea' ||
|
||||
( tagName === 'input'
|
||||
&& inputBlocklist.indexOf(element.getAttribute('type').toLowerCase()) == -1
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
var keybindFunction = keybindings[event.key]
|
||||
if (keybindFunction) {
|
||||
event.preventDefault()
|
||||
keybindFunction()
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user