fix: robust NC activity filter, title extraction, scan result detail
Watcher: - Accept both NC 22+ (type="file_created") and older NC (subject="created_self") so the upload filter works across all Nextcloud versions - Add .opus to audio_extensions - Fix tests: set nc.username on mocks, use realistic activity dicts with type field - Add tests for old NC style, non-band path filter, normalize_nc_path, cursor advance API: - Fix internal.py title extraction: always use filename stem (was using parts[-2] for >3-part paths, which gave folder name instead of song title) - nc-scan now returns NcScanResult with folder, files_found, imported, skipped counts instead of bare song list — gives the UI actionable feedback Web: - Show rich scan result message: folder scanned, count imported, count already registered Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,14 @@ interface BandInvite {
|
||||
expires_at: string;
|
||||
}
|
||||
|
||||
interface NcScanResult {
|
||||
folder: string;
|
||||
files_found: number;
|
||||
imported: number;
|
||||
skipped: number;
|
||||
songs: SongSummary[];
|
||||
}
|
||||
|
||||
export function BandPage() {
|
||||
const { bandId } = useParams<{ bandId: string }>();
|
||||
const qc = useQueryClient();
|
||||
@@ -67,15 +75,17 @@ export function BandPage() {
|
||||
});
|
||||
|
||||
const scanMutation = useMutation({
|
||||
mutationFn: () => api.post<SongSummary[]>(`/bands/${bandId}/nc-scan`, {}),
|
||||
onSuccess: (imported) => {
|
||||
mutationFn: () => api.post<NcScanResult>(`/bands/${bandId}/nc-scan`, {}),
|
||||
onSuccess: (result) => {
|
||||
qc.invalidateQueries({ queryKey: ["songs", bandId] });
|
||||
setScanMsg(
|
||||
imported.length > 0
|
||||
? `Imported ${imported.length} new song${imported.length !== 1 ? "s" : ""} from Nextcloud.`
|
||||
: "No new audio files found in Nextcloud."
|
||||
);
|
||||
setTimeout(() => setScanMsg(null), 4000);
|
||||
if (result.imported > 0) {
|
||||
setScanMsg(`Imported ${result.imported} new song${result.imported !== 1 ? "s" : ""} from ${result.folder} (${result.skipped} already registered).`);
|
||||
} else if (result.files_found === 0) {
|
||||
setScanMsg(`No audio files found in ${result.folder}.`);
|
||||
} else {
|
||||
setScanMsg(`All ${result.files_found} file${result.files_found !== 1 ? "s" : ""} in ${result.folder} already registered.`);
|
||||
}
|
||||
setTimeout(() => setScanMsg(null), 6000);
|
||||
},
|
||||
onError: (err) => setScanMsg(err instanceof Error ? err.message : "Scan failed"),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user