improve search

This commit is contained in:
SrGooglo 2025-04-09 15:44:02 +00:00
parent 61ec4a80f8
commit deed590d9e
2 changed files with 195 additions and 173 deletions

View File

@ -33,20 +33,20 @@ const ResultsTypeDecorators = {
}, },
}, },
tracks: { tracks: {
icon: "FiAlbum", icon: "MdAlbum",
label: "Tracks", label: "Tracks",
renderItem: (props) => { renderItem: (props) => {
const { item, onClick } = props const { item, onClick } = props
return ( return (
<div className="suggestion" onClick={onClick}> <div className="suggestion">
<MusicTrack track={item} /> <MusicTrack track={item} onClick={onClick} />
</div> </div>
) )
}, },
}, },
playlists: { playlists: {
icon: "FiAlbum", icon: "MdPlaylistPlay",
label: "Playlists", label: "Playlists",
renderItem: (props) => { renderItem: (props) => {
return ( return (
@ -83,18 +83,6 @@ const Results = (props) => {
return results[key].items.length > 0 return results[key].items.length > 0
}) })
if (groupsKeys.length === 0) {
return (
<div className="searcher no_results">
<antd.Result
status="info"
title="No results"
subTitle="We are sorry, but we could not find any results for your search."
/>
</div>
)
}
const handleClick = async (decorator, data) => { const handleClick = async (decorator, data) => {
if (typeof decorator.onClick === "function") { if (typeof decorator.onClick === "function") {
await decorator.onClick(data) await decorator.onClick(data)
@ -105,6 +93,26 @@ const Results = (props) => {
} }
} }
if (props.loading) {
return (
<div className="searcher_results">
<antd.Skeleton active />
</div>
)
}
if (groupsKeys.length === 0) {
return (
<div className="searcher_results no_results">
<antd.Result
status="info"
title="No results"
subTitle="We are sorry, but we could not find any results for your search."
/>
</div>
)
}
return ( return (
<div <div
className={classnames("searcher_results", { className={classnames("searcher_results", {
@ -121,12 +129,12 @@ const Results = (props) => {
return ( return (
<div className="searcher_results_category" key={index}> <div className="searcher_results_category" key={index}>
<div className="searcher_results_category_header"> <div className="searcher_results_category_header">
<h1> <h2>
{createIconRender(decorator.icon)} {createIconRender(decorator.icon)}
<Translation> <Translation>
{(t) => t(decorator.label)} {(t) => t(decorator.label)}
</Translation> </Translation>
</h1> </h2>
</div> </div>
<div <div
@ -150,7 +158,7 @@ const Results = (props) => {
) )
} }
export default (props) => { const Searcher = (props) => {
const [loading, setLoading] = React.useState(false) const [loading, setLoading] = React.useState(false)
const [searchResult, setSearchResult] = React.useState(null) const [searchResult, setSearchResult] = React.useState(null)
const [searchValue, setSearchValue] = React.useState("") const [searchValue, setSearchValue] = React.useState("")
@ -253,13 +261,14 @@ export default (props) => {
/> />
{searchResult && props.renderResults && ( {searchResult && props.renderResults && (
<div className="results"> <Results
{loading && <antd.Skeleton active />} loading={loading}
{!loading && ( results={searchResult}
<Results results={searchResult} onClose={props.close} /> onClose={props.close}
)} />
</div>
)} )}
</div> </div>
) )
} }
export default Searcher

View File

@ -1,211 +1,224 @@
html { html {
&.mobile { &.mobile {
.searcher { .searcher {
display: flex; display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: scroll; overflow-y: scroll;
.searcher_results { .searcher_results {
display: flex; display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: scroll; overflow-y: scroll;
.searcher_results_category { .searcher_results_category {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0; padding: 0;
gap: 5px; gap: 5px;
.searcher_results_category_header { .searcher_results_category_header {
font-size: 0.6rem; font-size: 0.6rem;
} }
.searcher_results_category_suggestions { .searcher_results_category_suggestions {
padding: 0 15px; padding: 0 15px;
&#playlists { &#playlists {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0; padding: 0;
.playlistItem { .playlistItem {
width: 100%; width: 100%;
max-width: none; max-width: none;
} }
} }
} }
} }
} }
} }
} }
} }
.searcher { .searcher {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
gap: 10px; gap: 10px;
.results { width: 100%;
border-radius: 10px;
width: 100%; &.small {
.ant-input-affix-wrapper {
padding: 7px;
overflow-x: hidden; height: fit-content;
overflow-y: overlay;
}
&.small { .ant-input-prefix {
.ant-input-affix-wrapper { font-size: 1rem;
padding: 7px; }
height: fit-content; .ant-input {
font-size: 0.8rem;
}
}
}
.ant-input-prefix { .ant-input-affix-wrapper {
font-size: 1rem; position: sticky;
}
.ant-input { top: 0;
font-size: 0.8rem; left: 0;
}
}
}
.ant-input-affix-wrapper { display: inline-flex;
position: sticky; flex-direction: row;
top: 0; align-items: center;
left: 0;
display: inline-flex; border: 0;
flex-direction: row; padding: 0;
margin: 0;
align-items: center; min-height: 60px;
height: 60px;
border-radius: 10px;
border: 0; padding: 0 10px;
padding: 0;
margin: 0;
min-height: 60px; background-color: var(--background-color-primary);
height: 60px;
border-radius: 10px;
padding: 0 10px; .ant-input-prefix {
font-size: 2rem;
.ant-input-prefix { svg {
font-size: 2rem; color: var(--text-color);
}
}
svg { .ant-input {
color: var(--text-color); height: 100%;
} color: var(--text-color);
}
.ant-input { font-size: 1rem;
height: 100%;
color: var(--text-color);
font-size: 1rem; margin: 0;
}
margin: 0; }
}
}
} }
.searcher_results { .searcher_results {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
gap: 10px; width: 100%;
gap: 10px;
padding: 20px;
&.one_column { border-radius: 12px;
grid-template-columns: 1fr;
}
&.no_results { overflow-x: hidden;
display: flex; overflow-y: overlay;
flex-direction: column;
align-items: center; color: var(--text-color);
justify-content: center; background-color: var(--background-color-primary);
}
.searcher_results_category { .ant-result,
background-color: var(--background-color-primary); .ant-result-title,
.ant-result-subtitle {
color: var(--text-color);
}
padding: 20px; &.one_column {
grid-template-columns: 1fr;
}
border-radius: 8px; &.no_results {
display: flex;
flex-direction: column;
height: fit-content; align-items: center;
width: 100%; justify-content: center;
}
gap: 20px; .searcher_results_category {
border-radius: 8px;
.searcher_results_category_header { height: fit-content;
h1 { width: 100%;
margin: 0;
}
}
.searcher_results_category_suggestions { gap: 20px;
display: flex;
flex-direction: column;
gap: 10px; .searcher_results_category_header {
background-color: var(--background-color-accent);
border-radius: 8px;
padding: 5px 10px;
padding: 10px; width: fit-content;
.playlistItem { h1 {
background-color: var(--background-color-accent); margin: 0;
}
}
max-width: 300px; .searcher_results_category_suggestions {
height: 80px; display: flex;
flex-direction: column;
.playlistItem_cover { gap: 10px;
width: 80px;
height: 80px;
img { padding: 10px;
height: 80px;
width: 80px;
}
}
.playlistItem_info { .playlistItem {
max-width: unset; background-color: var(--background-color-accent);
h1 { max-width: 300px;
font-size: 1rem; height: 80px;
white-space: break-spaces;
}
}
}
.music-track { .playlistItem_cover {
background-color: var(--background-color-accent); width: 80px;
} height: 80px;
}
#playlists { img {
display: grid; height: 80px;
width: 80px;
}
}
grid-template-columns: 1fr 1fr 1fr; .playlistItem_info {
} max-width: unset;
}
} h1 {
font-size: 1rem;
white-space: break-spaces;
}
}
}
.music-track {
background-color: var(--background-color-accent);
}
}
#playlists {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
}
}