fix(ci): restore sanity checks

This commit is contained in:
edde746
2026-07-05 08:34:55 +02:00
parent 87eaafe3c4
commit c4184c6148
13 changed files with 46 additions and 43 deletions
+1 -2
View File
@@ -252,8 +252,7 @@ class DiscoverProvider extends ChangeNotifier with DisposableChangeNotifierMixin
safeNotifyListeners();
return;
}
if (fetchedHubs.succeededServerIds.isEmpty &&
(fetchedHubs.cancelledServerIds.isNotEmpty || isProfileBinding())) {
if (fetchedHubs.succeededServerIds.isEmpty && (fetchedHubs.cancelledServerIds.isNotEmpty || isProfileBinding())) {
appLogger.d('DiscoverProvider: hub pass disrupted with no prior content; keeping loading state');
return;
}
+1 -2
View File
@@ -93,8 +93,7 @@ class PlaybackStateProvider with ChangeNotifier, DisposableChangeNotifierMixin {
/// The queue item the cursor currently points at, or null when no queue
/// is active or the cursor is outside the loaded window.
MediaItem? get currentQueueItem =>
_currentPlayQueueItemID == null ? null : _findLoadedItem(_currentPlayQueueItemID!);
MediaItem? get currentQueueItem => _currentPlayQueueItemID == null ? null : _findLoadedItem(_currentPlayQueueItemID!);
/// Set the client reference for loading more items
void setPlayQueueWindowFetcher(PlayQueueWindowFetcher? fetcher) {
+15 -3
View File
@@ -13,9 +13,17 @@ import '../utils/global_key_utils.dart';
import '../utils/search_relevance.dart';
import 'multi_server_manager.dart';
typedef OnDeckAggregationResult = ({List<MediaItem> items, Set<String> succeededServerIds, Set<String> cancelledServerIds});
typedef OnDeckAggregationResult = ({
List<MediaItem> items,
Set<String> succeededServerIds,
Set<String> cancelledServerIds,
});
typedef HubAggregationResult = ({List<MediaHub> hubs, Set<String> succeededServerIds, Set<String> cancelledServerIds});
typedef LibraryAggregationResult = ({List<MediaLibrary> libraries, Set<String> succeededServerIds, Set<String> cancelledServerIds});
typedef LibraryAggregationResult = ({
List<MediaLibrary> libraries,
Set<String> succeededServerIds,
Set<String> cancelledServerIds,
});
/// Whether [error] is a client-side abort (client teardown mid-request)
/// rather than a genuine server failure. Aggregation reports these servers
@@ -62,7 +70,11 @@ class DataAggregationService {
final clients = _clientsFor(serverIds);
if (clients.isEmpty) {
appLogger.w('No online servers available for fetching libraries (neutral)');
return (libraries: const <MediaLibrary>[], succeededServerIds: const <String>{}, cancelledServerIds: const <String>{});
return (
libraries: const <MediaLibrary>[],
succeededServerIds: const <String>{},
cancelledServerIds: const <String>{},
);
}
final succeededServerIds = <String>{};
final cancelledServerIds = <String>{};
+1
View File
@@ -118,6 +118,7 @@ class _SharedHttpClient extends http.BaseClient {
void close() {}
}
// ignore: unused-code
/// Test hook: builds the throttled artwork client with an isolated limiter.
@visibleForTesting
http.Client createArtworkHttpClientForTest(http.Client inner, {int maxConcurrent = 6}) =>
@@ -136,11 +136,7 @@ class PlaybackInitializationService {
}
appLogger.d('Found offline video: $readablePath');
return (
path: readablePath,
mediaIndex: downloadedItem.mediaIndex,
mediaSourceId: downloadedItem.mediaSourceId,
);
return (path: readablePath, mediaIndex: downloadedItem.mediaIndex, mediaSourceId: downloadedItem.mediaSourceId);
} catch (e) {
appLogger.w('Error checking offline video path', error: e);
return null;
+1 -3
View File
@@ -105,9 +105,7 @@ class DeviceIdentityService {
/// usable remains.
String? sanitizeHeaderValue(String? value) {
if (value == null) return null;
final filtered = String.fromCharCodes(
value.codeUnits.where((unit) => unit != 0x0D && unit != 0x0A && unit <= 0xFF),
);
final filtered = String.fromCharCodes(value.codeUnits.where((unit) => unit != 0x0D && unit != 0x0A && unit <= 0xFF));
final trimmed = filtered.trim();
return trimmed.isEmpty ? null : trimmed;
}
+1 -5
View File
@@ -8,11 +8,7 @@ import '../database/app_database.dart';
/// trustworthy discriminator there. Otherwise fall back to the media index.
/// A null [requestedMediaIndex] means "any version" (the caller has no
/// version opinion, e.g. external-player launches keyed by item only).
bool downloadedVersionMatches(
DownloadedMediaItem row, {
int? requestedMediaIndex,
String? requestedMediaSourceId,
}) {
bool downloadedVersionMatches(DownloadedMediaItem row, {int? requestedMediaIndex, String? requestedMediaSourceId}) {
final downloadedSourceId = row.mediaSourceId;
final requestedSourceId = requestedMediaSourceId?.trim();
final comparedBySourceId =
+1 -2
View File
@@ -177,8 +177,7 @@ Future<bool?> navigateToVideoPlayer(
}
}
final mediaIndex =
selectedMediaIndex ?? downloadedMediaIndex ?? await savedMediaVersionIndexFor(metadata) ?? 0;
final mediaIndex = selectedMediaIndex ?? downloadedMediaIndex ?? await savedMediaVersionIndexFor(metadata) ?? 0;
final mediaSourceId = selectedMediaSourceId ?? downloadedMediaSourceId;
var markedInFlight = false;
@@ -118,7 +118,9 @@ class _PlayerPerformanceOverlayState extends State<PlayerPerformanceOverlay> {
// On height-limited screens (landscape phones) widen the card so the Wrap
// packs sections side by side instead of stacking into an off-screen column.
final compactHeight = constraints.hasBoundedHeight && constraints.maxHeight < 500;
final cardMaxWidth = compactHeight && constraints.hasBoundedWidth ? math.min(constraints.maxWidth, 560.0) : 400.0;
final cardMaxWidth = compactHeight && constraints.hasBoundedWidth
? math.min(constraints.maxWidth, 560.0)
: 400.0;
// Text scaling only inflates the intrinsic size that FittedBox scales right
// back down, trading layout sharpness for nothing on this diagnostics card.
+3 -11
View File
@@ -8,14 +8,10 @@ import 'package:plezy/focus/input_mode_tracker.dart';
/// must only exist in keyboard/d-pad mode: on touch it is pure dead weight
/// multiplied by every card in a grid (see library scroll jank).
void main() {
Finder chromeIn(Type type) =>
find.descendant(of: find.byType(FocusableWrapper), matching: find.byType(type));
Finder chromeIn(Type type) => find.descendant(of: find.byType(FocusableWrapper), matching: find.byType(type));
Widget buildWrapper() => Scaffold(
body: FocusableWrapper(
onSelect: () {},
child: const SizedBox(width: 10, height: 10),
),
body: FocusableWrapper(onSelect: () {}, child: const SizedBox(width: 10, height: 10)),
);
testWidgets('pointer mode builds no focus chrome around the child', (tester) async {
@@ -46,11 +42,7 @@ void main() {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: FocusableWrapper(
focusNode: node,
onSelect: () {},
child: const SizedBox(width: 10, height: 10),
),
body: FocusableWrapper(focusNode: node, onSelect: () {}, child: const SizedBox(width: 10, height: 10)),
),
),
);
+4 -1
View File
@@ -360,7 +360,10 @@ void main() {
final heroFades = tester
.widgetList<Container>(
find.byWidgetPredicate(
(w) => w is Container && w.decoration is BoxDecoration && (w.decoration! as BoxDecoration).gradient is LinearGradient,
(w) =>
w is Container &&
w.decoration is BoxDecoration &&
(w.decoration! as BoxDecoration).gradient is LinearGradient,
),
)
.map((c) => (c.decoration! as BoxDecoration).gradient! as LinearGradient)
+8 -2
View File
@@ -390,14 +390,20 @@ void main() {
test('changed access token requires recreation', () {
expect(
MultiServerManager.canReuseJellyfinClient(live: base, incoming: base.copyWith(accessToken: 'rotated')),
MultiServerManager.canReuseJellyfinClient(
live: base,
incoming: base.copyWith(accessToken: 'rotated'),
),
isFalse,
);
});
test('changed device id requires recreation', () {
expect(
MultiServerManager.canReuseJellyfinClient(live: base, incoming: base.copyWith(deviceId: 'other-device')),
MultiServerManager.canReuseJellyfinClient(
live: base,
incoming: base.copyWith(deviceId: 'other-device'),
),
isFalse,
);
});
+6 -6
View File
@@ -385,8 +385,9 @@ void MpvPlayer::TryAudioReload(const char* reason, int attempt) {
std::string reason_str = reason;
CommandAsync({"ao-reload"}, [this, reason_str, attempt](int error) {
audio_reload_pending_ = false;
LogRecovery("ao-reload completed (reason=" + reason_str + ", attempt " + std::to_string(attempt) +
", error=" + std::to_string(error) + ")");
LogRecovery(
"ao-reload completed (reason=" + reason_str + ", attempt " + std::to_string(attempt) +
", error=" + std::to_string(error) + ")");
});
}
@@ -397,8 +398,7 @@ void MpvPlayer::MaybeRunAudioRecovery() {
if (file_loaded_) {
resume_attempts_left_ = kResumeReloadAttempts;
resume_next_attempt_ = now + kResumeFirstDelay;
LogRecovery("power resume detected; scheduling ao-reload in " + std::to_string(kResumeFirstDelay.count()) +
"ms");
LogRecovery("power resume detected; scheduling ao-reload in " + std::to_string(kResumeFirstDelay.count()) + "ms");
} else {
LogRecovery("power resume detected; no file loaded, nothing to recover");
}
@@ -545,8 +545,8 @@ void MpvPlayer::HandleMpvEvent(mpv_event* event) {
null_attempts_left_ = kNullRetryBudget;
null_backoff_ = kNullFirstDelay;
null_next_attempt_ = std::chrono::steady_clock::now() + kNullFirstDelay;
LogRecovery("current-ao fell back to null; starting recovery (budget " + std::to_string(kNullRetryBudget) +
")");
LogRecovery(
"current-ao fell back to null; starting recovery (budget " + std::to_string(kNullRetryBudget) + ")");
} else if (!is_null && current_ao_is_null_) {
null_attempts_left_ = 0;
LogRecovery(std::string("current-ao is now '") + (current_ao ? current_ao : "") + "'");