diff --git a/web/src/App.tsx b/web/src/App.tsx
index ebd6bd5..6341634 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -121,6 +121,13 @@ export default function App() {
const favCount = useMemo(() => Object.values(favs).filter(Boolean).length, [favs]);
+ function toggleSelect(key: string, on?: boolean) {
+ setSelectedSet((prev) => ({ ...prev, [key]: typeof on === 'boolean' ? on : !prev[key] }));
+ }
+ function clearSelection() {
+ setSelectedSet({});
+ }
+
async function handlePlay(name: string, rel?: string) {
setError(null);
if (!selected) return setError('Bitte einen Voice-Channel auswählen');
@@ -206,8 +213,8 @@ export default function App() {
-
- {!isAdmin && (
+
+ {!isAdmin ? (
<>
setAdminPwd(e.target.value)} />
@@ -215,6 +222,40 @@ export default function App() {
>
+ ) : (
+
+
Ausgewählt: {selectedCount}
+ {selectedCount > 0 && (
+
+ )}
+ {selectedCount === 1 && (
+
{
+ const from = Object.entries(selectedSet).find(([,v])=>v)?.[0];
+ if(!from) return;
+ try {
+ await adminRename(from, newName);
+ clearSelection();
+ const resp = await fetchSounds(query, activeFolder === '__favs__' ? '__all__' : activeFolder);
+ setSounds(resp.items); setTotal(resp.total); setFolders(resp.folders);
+ } catch (e:any) { setError(e?.message||'Umbenennen fehlgeschlagen'); }
+ }} />
+ )}
+
+
+
)}
@@ -237,11 +278,21 @@ export default function App() {
const key = `${s.relativePath ?? s.fileName}`;
const isFav = !!favs[key];
return (
-
handlePlay(s.name, s.relativePath)}>
-
{s.name}
-
-
-
+
+ {isAdmin && (
+
{ e.stopPropagation(); toggleSelect(key, e.target.checked); }}
+ />
+ )}
+
handlePlay(s.name, s.relativePath)}>
+
{s.name}
+
+
+
+
);