/// Was für ein Knoten im Browse-Baum von Android Auto und dem /// Sprachassistenten gemeint ist. enum AutoArt { favoriten('Favoriten'), zuletzt('Zuletzt hinzugefügt'), kategorien('Kategorien'), kuenstlerListe('Künstler'), kategorie(''), kuenstler(''), titel(''); const AutoArt(this.anzeige); /// Beschriftung eines Ordners der obersten Ebene. final String anzeige; } /// Die Ordner, die im Auto auf der obersten Ebene stehen — dieselben Wege, /// die auch die App anbietet. const wurzelArten = [ AutoArt.favoriten, AutoArt.zuletzt, AutoArt.kategorien, AutoArt.kuenstlerListe, ]; /// Ein aufgelöster Knoten: seine Art und, wo nötig, sein Name. class AutoKnoten { const AutoKnoten(this.art, this.name); final AutoArt art; /// Kategorie- oder Künstlername, bei einem Titel dessen UUID. final String? name; } const _praefix = 'melo:'; /// Adresse eines Knotens. /// /// Der Name steht **hinter** dem ersten Doppelpunkt nach der Art und wird /// nicht weiter zerlegt: „Intro: Der Anfang" ist ein normaler Albumtitel, /// und Schrägstriche kommen in Künstlernamen wie „AC/DC" vor. Würde hier /// gesplittet, verlöre man beides. String knotenId(AutoArt art, [String? name]) => name == null ? '$_praefix${art.name}' : '$_praefix${art.name}:$name'; /// Löst eine Adresse wieder auf, oder `null`, wenn sie nicht von uns stammt. AutoKnoten? knotenAus(String mediaId) { if (!mediaId.startsWith(_praefix)) return null; final rest = mediaId.substring(_praefix.length); final trenner = rest.indexOf(':'); final artName = trenner == -1 ? rest : rest.substring(0, trenner); final name = trenner == -1 ? null : rest.substring(trenner + 1); for (final art in AutoArt.values) { if (art.name == artName) return AutoKnoten(art, name); } return null; }