From 5c68370dddb159c5a9706ad086a05277b85390c3 Mon Sep 17 00:00:00 2001 From: Moritz Vifian Date: Sun, 12 Jan 2025 13:22:11 +0100 Subject: [PATCH] select first song on enter #20 --- app/imports/ui/Songlist/List.tsx | 24 +++++++++++++++++++++--- app/imports/ui/Songlist/Menu.tsx | 26 ++++++++++++++++++++------ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/app/imports/ui/Songlist/List.tsx b/app/imports/ui/Songlist/List.tsx index 3339028..24c13c1 100644 --- a/app/imports/ui/Songlist/List.tsx +++ b/app/imports/ui/Songlist/List.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import {useContext, useMemo, useState} from 'react'; -import {NavLink, RouteComponentProps, withRouter} from 'react-router-dom'; +import {NavLink, RouteComponentProps, useHistory, withRouter} from 'react-router-dom'; import {Song} from '../../api/collections'; import Drawer from '../Drawer'; -import {userMayWrite} from '../../api/helpers'; +import {routePath, userMayWrite, View} from '../../api/helpers'; import classNames from 'classnames'; import {Meteor} from 'meteor/meteor'; @@ -21,6 +21,9 @@ interface ListProps extends RouteComponentProps { const List = (props: ListProps) => { const [filter, setFilter] = useState('') + // todo: upgrade to new react-router -> useNavigate can be used + const history = useHistory() + const [fuzzyMatches, exactMatches] = useMemo(() => { let visibleSongs = props.songs @@ -55,6 +58,20 @@ const List = (props: ListProps) => { groups.set('im Titel', exactMatches); } + const navigateToFirstMatch = () => { + let song + if(exactMatches.length>0) { + song = exactMatches[0] + }else if(fuzzyMatches.length>0) { + song = fuzzyMatches[0] + } + if(song) { + const newUrl = routePath(View.view, song) + showMenu + history.push(newUrl) + } + } + // Add and group fuzzy matches for (const song of fuzzyMatches) { const group = grouper(song); @@ -72,11 +89,12 @@ const List = (props: ListProps) => { : undefined; return ( + - setFilter(e)}/> + setFilter(e)}/>
    {addSong} {Array.from(groups, ([group, songs]) => { diff --git a/app/imports/ui/Songlist/Menu.tsx b/app/imports/ui/Songlist/Menu.tsx index 097a73f..6aa9494 100644 --- a/app/imports/ui/Songlist/Menu.tsx +++ b/app/imports/ui/Songlist/Menu.tsx @@ -10,7 +10,8 @@ import classNames from "classnames"; import classnames from "classnames"; import {Tooltip} from "react-tooltip"; -export function Menu(props: { filter: string, filterChanged: (filter: string) => void }) { + +export function Menu(props: { filter: string, filterChanged: (filter: string) => void, onEnter: Function}) { const [showTags, setShowTags] = useState(false); const [hasFocus, setHasFocus] = useState(false); const [skipBlurCheck, setSkipBlurCheck] = useState(false); @@ -75,11 +76,20 @@ export function Menu(props: { filter: string, filterChanged: (filter: string) => const {themeDark, toggleTheme} = useContext(ThemeContext); const {setShowMenu} = useContext(MenuContext); + const removeFocusAction = () => { + props.filterChanged(''); + setShowTags(false); + // escape fires no blur event (that's why it worked with 'X' icon) + setHasFocus(false); + } + return <> + )} + onKeyDown={props.onKeyDown} + > {showSearch ? <> onFocus={() => setHasFocus(true)} onKeyDown={(event: React.KeyboardEvent) => { if (event.key === 'Escape') { - props.filterChanged(''); - setShowTags(false); - // escape fires no blur event (that's why it worked with 'X' icon) - setHasFocus(false); + removeFocusAction() } + else if(event.key === 'Enter') { + + removeFocusAction() + + + props?.onEnter() + } }} onChange={(event: React.ChangeEvent) => { props.filterChanged(event.currentTarget.value)