Files
sm-emby-share/lib/providers/detail_palette_provider.dart
2026-07-14 11:11:36 +08:00

76 lines
2.2 KiB
Dart

import 'dart:math' as math;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@immutable
class DetailPaletteRequest {
DetailPaletteRequest({required this.url, Map<String, String>? headers})
: headers = headers == null
? null
: Map<String, String>.unmodifiable(headers);
final String url;
final Map<String, String>? headers;
@override
bool operator ==(Object other) {
return identical(this, other) ||
other is DetailPaletteRequest &&
other.url == url &&
mapEquals(other.headers, headers);
}
@override
int get hashCode {
final sortedHeaderEntries = headers?.entries.toList(growable: false)
?..sort((left, right) => left.key.compareTo(right.key));
final headersHash = sortedHeaderEntries == null
? null
: Object.hashAll(
sortedHeaderEntries.map(
(entry) => Object.hash(entry.key, entry.value),
),
);
return Object.hash(url, headersHash);
}
}
final detailPaletteProvider =
FutureProvider.family<Color?, DetailPaletteRequest>((ref, request) async {
try {
final sourceProvider = CachedNetworkImageProvider(
request.url,
headers: request.headers,
);
final resizedProvider = ResizeImage.resizeIfNeeded(
100,
null,
sourceProvider,
);
final colorScheme = await ColorScheme.fromImageProvider(
provider: resizedProvider,
brightness: Brightness.dark,
).timeout(const Duration(seconds: 6));
final sourceColor = HSLColor.fromColor(colorScheme.primary);
return sourceColor
.withSaturation(math.min(sourceColor.saturation, 0.3))
.withLightness(0.11)
.toColor();
} catch (_) {
return null;
}
});
Color createDetailNavigationColor(Color backgroundColor) {
final backgroundHsl = HSLColor.fromColor(backgroundColor);
return backgroundHsl
.withSaturation(math.min(backgroundHsl.saturation, 0.26))
.withLightness(0.07)
.toColor();
}