Add a source picker to search and use the full window width
Search now queries YouTube and SoundCloud together by default and interleaves the two result lists so neither buries the other; a picker left of the input narrows it to one source (plus the local library when configured), and a prefix typed into the query still outranks it. The panel was capped at 1180px, which left most of a wide screen empty — it now scales to 1680px and gives the search column the extra room. A dead link also reported "could not parse yt-dlp's response", which described our parser rather than the problem; it now shows yt-dlp's own error line, or says the link did not open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f84489e27e
commit
971fd65b1f
+4
-2
@@ -42,8 +42,10 @@ export const api = {
|
||||
|
||||
state: (serverId: string) => request<ServerStateResponse>(`/api/servers/${serverId}/state`),
|
||||
|
||||
search: (serverId: string, query: string) =>
|
||||
request<{ tracks: Track[] }>(`/api/servers/${serverId}/search?q=${encodeURIComponent(query)}`),
|
||||
search: (serverId: string, query: string, source: string) =>
|
||||
request<{ tracks: Track[] }>(
|
||||
`/api/servers/${serverId}/search?q=${encodeURIComponent(query)}&source=${source}`,
|
||||
),
|
||||
|
||||
play: (
|
||||
serverId: string,
|
||||
|
||||
@@ -16,8 +16,11 @@ interface Props {
|
||||
onError(message: string | null): void;
|
||||
}
|
||||
|
||||
const SOURCE_KEY = "mbot.searchSource";
|
||||
|
||||
export function SearchPanel({ serverId, canControl, localLibrary, onError }: Props) {
|
||||
const [query, setQuery] = useState("");
|
||||
const [source, setSource] = useState<string>(() => localStorage.getItem(SOURCE_KEY) ?? "all");
|
||||
const [results, setResults] = useState<Track[]>([]);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [lastAdded, setLastAdded] = useState<string | null>(null);
|
||||
@@ -38,7 +41,7 @@ export function SearchPanel({ serverId, canControl, localLibrary, onError }: Pro
|
||||
setQuery("");
|
||||
return;
|
||||
}
|
||||
const { tracks } = await api.search(serverId, value);
|
||||
const { tracks } = await api.search(serverId, value, source);
|
||||
setResults(tracks);
|
||||
setSearched(true);
|
||||
} catch (err) {
|
||||
@@ -62,6 +65,20 @@ export function SearchPanel({ serverId, canControl, localLibrary, onError }: Pro
|
||||
<div className="card grow">
|
||||
<h2>Поиск</h2>
|
||||
<form className="search-form" onSubmit={submit}>
|
||||
<select
|
||||
value={source}
|
||||
onChange={(event) => {
|
||||
setSource(event.target.value);
|
||||
localStorage.setItem(SOURCE_KEY, event.target.value);
|
||||
}}
|
||||
disabled={!canControl}
|
||||
title="Где искать"
|
||||
>
|
||||
<option value="all">Везде</option>
|
||||
<option value="youtube">YouTube</option>
|
||||
<option value="soundcloud">SoundCloud</option>
|
||||
{localLibrary && <option value="local">Медиатека</option>}
|
||||
</select>
|
||||
<input
|
||||
value={query}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
|
||||
+15
-4
@@ -105,9 +105,9 @@ select:focus {
|
||||
}
|
||||
|
||||
.app {
|
||||
max-width: 1180px;
|
||||
max-width: 1680px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 18px 60px;
|
||||
padding: 20px 24px 60px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
@@ -151,11 +151,17 @@ select:focus {
|
||||
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
|
||||
gap: 18px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@media (min-width: 1500px) {
|
||||
.layout {
|
||||
grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.layout > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -180,7 +186,7 @@ select:focus {
|
||||
.card.grow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 460px;
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.card.grow .track-list {
|
||||
@@ -431,6 +437,11 @@ select:focus {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.search-form select {
|
||||
width: auto;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.hint {
|
||||
color: var(--muted);
|
||||
font-size: 12.5px;
|
||||
|
||||
Reference in New Issue
Block a user