Show scan warnings as structured cards instead of long sentences
Warnings are now stored and served as structured data (title, detail, slave/master items, total) and rendered as cards with a Slave -> Master table: the first five rows, with "Show all" for the rest. - Renamed folders highlight the characters that differ; non-ASCII characters get their code point in a tooltip, so look-alikes such as "-" (U+002D) and "‐" (U+2010) can be told apart. - Songs in a different folder are grouped by folder pair with a song count, most affected first, instead of two long examples. - Folders that only differ by name are no longer also reported as songs in a different folder. - Warnings saved as plain text by earlier scans still display. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1d31999793
commit
9e848cd765
13 files changed
+305
-92
No files matched your search
@@ -255,7 +255,7 @@ func (e *Engine) open(p store.Pair) (*libs, error) {
|
||||
|
||||
// NormalizePair fills defaults and validates a pair. It returns non-fatal
|
||||
// warnings (such as layout mismatches) for the UI.
|
||||
func (e *Engine) NormalizePair(p *store.Pair) ([]string, error) {
|
||||
func (e *Engine) NormalizePair(p *store.Pair) ([]store.Warning, error) {
|
||||
p.Name = strings.TrimSpace(p.Name)
|
||||
if p.Name == "" {
|
||||
return nil, errors.New("name is required")
|
||||
@@ -301,7 +301,7 @@ func (e *Engine) NormalizePair(p *store.Pair) ([]string, error) {
|
||||
// layoutWarnings is the quick check run when a pair is saved and at the
|
||||
// start of each scan. Content that exists in only one library is normal and
|
||||
// never warned about; only folders that are the same but named differently are.
|
||||
func layoutWarnings(l *libs) []string {
|
||||
func layoutWarnings(l *libs) []store.Warning {
|
||||
empty := true
|
||||
if ents, _ := os.ReadDir(l.slave.Path); len(ents) > 0 {
|
||||
for _, en := range ents {
|
||||
@@ -312,10 +312,11 @@ func layoutWarnings(l *libs) []string {
|
||||
}
|
||||
}
|
||||
if empty {
|
||||
return []string{"The slave library is empty. Use Build to pick songs from the master library to hardlink into it."}
|
||||
return []store.Warning{{Title: "The slave library is empty",
|
||||
Detail: "Use Build to pick songs from the master library to hardlink into it."}}
|
||||
}
|
||||
if w := renamedWarning(renamedFolders(l)); w != "" {
|
||||
return []string{w}
|
||||
if w := renamedWarning(renamedFolders(l)); w != nil {
|
||||
return []store.Warning{*w}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user