1.0 library + player settings: Jellyfin/Link/Files library with details panel, player gear, settings cards, host flag
Library: source switch, selectable cards with a details panel, one merged Continue row, Latest grouped per series without re-releases, Link page with previews and recent links, Files embedded. Player: gear popover in both designs, progress line while controls hide, live hwdec. Settings rebuilt as cards. State marks the host member (proto stays 9, unreleased); hosting shows LAN invite addresses; window buttons in fullscreen. fadeThrough keeps the outgoing view's state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
99cda7ed04
commit
d092ea371a
54 files changed
+4963
-1825
No files matched your search
@@ -164,6 +164,28 @@ void main() {
|
||||
expect(http.last.uri.queryParameters['parentId'], 'a656b907eb3a73532e40e44b968d0225');
|
||||
});
|
||||
|
||||
test('latest ungrouped and recently played: query params, dates', () async {
|
||||
http.on('GET', '/Items/Latest', body: '[{"Id":"e","Type":"Episode",'
|
||||
'"PremiereDate":"2010-01-01T00:00:00.0000000Z","DateCreated":"2026-10-01T12:00:00.0000000Z"}]');
|
||||
final latest = await client.latest('lib', limit: 100, groupItems: false);
|
||||
expect(http.last.uri.queryParameters['groupItems'], 'false');
|
||||
expect(http.last.uri.queryParameters['fields'], contains('DateCreated'));
|
||||
expect(latest.single.premiereDate, DateTime.utc(2010));
|
||||
expect(latest.single.dateCreated, DateTime.utc(2026, 10, 1, 12));
|
||||
|
||||
http.on('GET', '/Items', body: '{"Items":[{"Id":"p","Type":"Episode","SeriesId":"s",'
|
||||
'"UserData":{"Played":true,"LastPlayedDate":"2026-10-07T20:00:00Z"}}],"TotalRecordCount":1}');
|
||||
final played = await client.recentlyPlayed(limit: 50);
|
||||
final q = http.last.uri.queryParameters;
|
||||
expect(q['filters'], 'IsPlayed');
|
||||
expect(q['sortBy'], 'DatePlayed');
|
||||
expect(q['sortOrder'], 'Descending');
|
||||
expect(q['includeItemTypes'], 'Episode,Movie');
|
||||
expect(q['recursive'], 'true');
|
||||
expect(q['limit'], '50');
|
||||
expect(played.single.userData.lastPlayedDate, DateTime.utc(2026, 10, 7, 20));
|
||||
});
|
||||
|
||||
test('library page: query params and paging', () async {
|
||||
http.on('GET', '/Items', fixture: 'series_page');
|
||||
const q = JellyfinItemQuery(
|
||||
|
||||
@@ -538,6 +538,21 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
test('host flag: only the marked member, on the wire as host:true', () {
|
||||
join('a', 'alice');
|
||||
join('b', 'bob');
|
||||
engine.members['a']!.host = true;
|
||||
final members = {for (final m in engine.broadcast().members) m.name: m};
|
||||
expect(members['alice']!.host, isTrue);
|
||||
expect(members['bob']!.host, isFalse);
|
||||
final json = engine.broadcast().toJson()['members'] as List;
|
||||
expect((json.first as Map)['host'], isTrue);
|
||||
expect((json.last as Map).containsKey('host'), isFalse);
|
||||
final back = StateBroadcast.fromJson(
|
||||
Map<String, Object?>.from(jsonDecode(jsonEncode(engine.broadcast().toJson())) as Map));
|
||||
expect([for (final m in back.members) m.host], [true, false]);
|
||||
});
|
||||
|
||||
group('profile + avatars', () {
|
||||
// Real magic bytes: anything that is not PNG/JPEG/WebP/GIF is dropped.
|
||||
final png = base64Encode([0x89, 0x50, 0x4E, 0x47, ...List<int>.generate(60, (i) => i)]);
|
||||
|
||||
Reference in new issue
Block a user