refactor: share focus chrome and simplify the TV picker and browse paths

Focus chrome was implemented twice, once in the focusable wrapper and once
in the focus builders; both now go through FocusChrome. TvColorPicker's
channel row was a copy of TvNumberSpinner and is now that widget in compact
density.

Also trims unused helpers and fields and simplifies the Jellyfin browse
paths.
This commit is contained in:
edde746
2026-07-26 06:09:49 +02:00
parent c68ffe9ed0
commit 4eaf4423a1
47 changed files with 526 additions and 1133 deletions
-4
View File
@@ -95,10 +95,6 @@ void main() {
expect(ContentTypeHelper.isVideoContent('artist'), isFalse);
});
test('isMusicLibrary returns false for null and non-matching types', () {
expect(ContentTypeHelper.isMusicLibrary(null), isFalse);
});
test('getLibraryIcon normalizes type and falls back to folder', () {
expect(ContentTypeHelper.getLibraryIcon('MOVIE'), Symbols.movie_rounded);
expect(ContentTypeHelper.getLibraryIcon('show'), Symbols.tv_rounded);
-13
View File
@@ -18,13 +18,6 @@ void main() {
expect(ScreenBreakpoints.isTablet(1200), isFalse);
});
test('isWideTablet: 900 ≤ w < 1200', () {
expect(ScreenBreakpoints.isWideTablet(899.9), isFalse);
expect(ScreenBreakpoints.isWideTablet(900), isTrue);
expect(ScreenBreakpoints.isWideTablet(1199.9), isTrue);
expect(ScreenBreakpoints.isWideTablet(1200), isFalse);
});
test('isDesktop: 1200 ≤ w < 1600', () {
expect(ScreenBreakpoints.isDesktop(1199.9), isFalse);
expect(ScreenBreakpoints.isDesktop(1200), isTrue);
@@ -32,12 +25,6 @@ void main() {
expect(ScreenBreakpoints.isDesktop(1600), isFalse);
});
test('isLargeDesktop: w ≥ 1600', () {
expect(ScreenBreakpoints.isLargeDesktop(1599.9), isFalse);
expect(ScreenBreakpoints.isLargeDesktop(1600), isTrue);
expect(ScreenBreakpoints.isLargeDesktop(10000), isTrue);
});
test('isDesktopOrLarger: w ≥ 1200', () {
expect(ScreenBreakpoints.isDesktopOrLarger(1199.9), isFalse);
expect(ScreenBreakpoints.isDesktopOrLarger(1200), isTrue);
-43
View File
@@ -61,47 +61,4 @@ void main() {
expect(result, equals(first));
});
});
group('PlexCacheParser.extractChapters', () {
test('returns null for null input', () {
expect(PlexCacheParser.extractChapters(null), isNull);
});
test('returns null when no metadata', () {
expect(
PlexCacheParser.extractChapters({
'MediaContainer': {'Metadata': []},
}),
isNull,
);
});
test('returns null when first metadata has no Chapter key', () {
expect(
PlexCacheParser.extractChapters({
'MediaContainer': {
'Metadata': [
<String, dynamic>{'ratingKey': '1'},
],
},
}),
isNull,
);
});
test('returns chapter list when present', () {
final chapters = [
{'tag': 'Chapter 1'},
{'tag': 'Chapter 2'},
];
final result = PlexCacheParser.extractChapters({
'MediaContainer': {
'Metadata': [
{'ratingKey': '1', 'Chapter': chapters},
],
},
});
expect(result, equals(chapters));
});
});
}