mirror of
				https://github.com/nkanaev/yarr.git
				synced 2025-10-30 22:43:29 +00:00 
			
		
		
		
	add navigation and general keybindings
This commit is contained in:
		
				
					committed by
					
						 Nazar Kanaev
						Nazar Kanaev
					
				
			
			
				
	
			
			
			
						parent
						
							fc5da31acf
						
					
				
				
					commit
					4225e06db9
				
			| @@ -161,7 +161,8 @@ | |||||||
|                 </button> |                 </button> | ||||||
|                 <div class="input-icon flex-grow-1"> |                 <div class="input-icon flex-grow-1"> | ||||||
|                     <span class="icon">{% inline "search.svg" %}</span> |                     <span class="icon">{% inline "search.svg" %}</span> | ||||||
|                     <input class="d-block toolbar-search" type="" v-model="itemSearch"> |                     <!-- id used by keybindings --> | ||||||
|  |                     <input id="searchbar" class="d-block toolbar-search" type="" v-model="itemSearch"> | ||||||
|                 </div> |                 </div> | ||||||
|                 <button class="toolbar-item ml-2" |                 <button class="toolbar-item ml-2" | ||||||
|                         @click="markItemsRead()" |                         @click="markItemsRead()" | ||||||
|   | |||||||
| @@ -1,7 +1,87 @@ | |||||||
| const keybindings = {} | 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) { | function isTextBox(element) { | ||||||
|   var tagName = element.tagName.toLowerCase(); |   var tagName = element.tagName.toLowerCase() | ||||||
|   // Input elements that aren't text |   // Input elements that aren't text | ||||||
|   const inputBlocklist = ['button','checkbox','color','file','hidden','image','radio','range','reset','search','submit'] |   const inputBlocklist = ['button','checkbox','color','file','hidden','image','radio','range','reset','search','submit'] | ||||||
|  |  | ||||||
| @@ -12,12 +92,14 @@ function isTextBox(element) { | |||||||
| } | } | ||||||
|  |  | ||||||
| document.addEventListener('keydown',function(event) { | document.addEventListener('keydown',function(event) { | ||||||
|   if(isTextBox(event.target)) { |   // Ignore while focused on text or | ||||||
|     return; |   // when using modifier keys (to not clash with browser behaviour) | ||||||
|  |   if(isTextBox(event.target) || event.metaKey || event.ctrlKey) { | ||||||
|  |     return | ||||||
|   } |   } | ||||||
|   const keybindFunction = keybindings[event.key]; |   const keybindFunction = keybindings[event.key] | ||||||
|   if(keybindFunction) { |   if(keybindFunction) { | ||||||
|     event.preventDefault(); |     event.preventDefault() | ||||||
|     keybindFunction(); |     keybindFunction() | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user