Cover-Farbe, Teilen aus YouTube, Android Auto, geschärfte Typografie

P3-Liste aus dem UX-Review: Player nimmt Cover-Farbe auf, "Teilen" aus
YouTube trägt die Adresse in den Downloader ein, Android Auto blättert
durch die Bibliothek, Laufweite der Typografie geschärft, Überschriften
vereinheitlicht. 533 Tests grün, flutter analyze ohne Befund.
This commit is contained in:
Hermes (Server)
2026-08-25 09:09:27 +02:00
parent 490e73ce41
commit 60c57577a3
22 changed files with 1040 additions and 40 deletions
+48
View File
@@ -0,0 +1,48 @@
import 'package:flutter/services.dart';
/// Erste Web-Adresse in [text], oder `null`.
///
/// Wer ein Video an Melo teilt, schickt selten nur die Adresse — die
/// YouTube-App hängt Titel und „über @YouTube" drumherum.
///
/// Bewusst **nicht** auf youtube.com eingeschränkt: der Downloader läuft über
/// yt-dlp am Server und kann mehr als YouTube. Was davon geht, entscheidet
/// der Server, nicht diese Zeile.
String? adresseAus(String? text) {
if (text == null || text.isEmpty) return null;
final treffer = _adresse.firstMatch(text);
if (treffer == null) return null;
// Satzzeichen am Ende gehören zum Satz, nicht zur Adresse.
return treffer.group(0)!.replaceAll(RegExp(r'[.,;:!?)\]]+$'), '');
}
final _adresse = RegExp(r'https?://\S+');
/// Nimmt entgegen, was andere Apps über „Teilen" an Melo schicken.
///
/// Eigene Brücke statt eines Zusatzpakets — das Projekt hat für MediaStore
/// und Klangeffekte bereits eigene (siehe `MediaStoreBridge`).
class GeteilteAdresse {
const GeteilteAdresse({this.channel = const MethodChannel(kanalName)});
static const kanalName = 'de.baka.melo/geteilt';
final MethodChannel channel;
/// Die Adresse, mit der die App gerade geöffnet wurde, oder `null`.
///
/// Wird beim Abholen auf der Android-Seite gelöscht: sonst spränge die App
/// bei jedem Wiedereintritt erneut in den Downloader.
Future<String?> abholen() async {
try {
final text = await channel.invokeMethod<String>('hole');
return adresseAus(text);
} on PlatformException {
return null;
} on MissingPluginException {
// Andere Plattformen kennen die Brücke nicht — dort gibt es kein
// Teilen an Melo, und das ist kein Fehler.
return null;
}
}
}