🐛 Fix update app color fail sometimes
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import 'package:audio_service/audio_service.dart';
|
import 'package:audio_service/audio_service.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart' as media_kit;
|
import 'package:media_kit/media_kit.dart' as media_kit;
|
||||||
import 'package:groovybox/data/db.dart';
|
import 'package:groovybox/data/db.dart';
|
||||||
import 'package:groovybox/providers/theme_provider.dart';
|
import 'package:groovybox/providers/theme_provider.dart';
|
||||||
|
import 'package:groovybox/logic/metadata_service.dart';
|
||||||
|
|
||||||
class AudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
class AudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||||
final media_kit.Player _player;
|
final media_kit.Player _player;
|
||||||
@@ -46,23 +47,18 @@ class AudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update theme color based on current track's album art
|
// Update theme color based on current track's album art
|
||||||
void _updateThemeFromCurrentTrack(MediaItem mediaItem) {
|
void _updateThemeFromCurrentTrack(MediaItem mediaItem) async {
|
||||||
if (_container == null) return;
|
if (_container == null) return;
|
||||||
|
|
||||||
final artUri = mediaItem.artUri;
|
try {
|
||||||
if (artUri != null &&
|
// Get metadata for the current track to access artBytes
|
||||||
artUri.scheme == 'file' &&
|
final metadataService = _container!.read(metadataServiceProvider);
|
||||||
artUri.path.isNotEmpty &&
|
final metadata = await metadataService.getMetadata(mediaItem.id);
|
||||||
!artUri.path.contains('..') && // Prevent directory traversal
|
|
||||||
(artUri.path.endsWith('.jpg') ||
|
|
||||||
artUri.path.endsWith('.jpeg') ||
|
|
||||||
artUri.path.endsWith('.png') ||
|
|
||||||
artUri.path.endsWith('.bmp') ||
|
|
||||||
artUri.path.endsWith('.webp'))) {
|
|
||||||
final seedColorNotifier = _container!.read(seedColorProvider.notifier);
|
final seedColorNotifier = _container!.read(seedColorProvider.notifier);
|
||||||
seedColorNotifier.updateFromAlbumArt(artUri.path);
|
seedColorNotifier.updateFromAlbumArtBytes(metadata.artBytes);
|
||||||
} else {
|
} catch (e) {
|
||||||
// Reset to default color if no valid album art
|
// If metadata retrieval fails, reset to default color
|
||||||
final seedColorNotifier = _container!.read(seedColorProvider.notifier);
|
final seedColorNotifier = _container!.read(seedColorProvider.notifier);
|
||||||
seedColorNotifier.resetToDefault();
|
seedColorNotifier.resetToDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flutter_media_metadata/flutter_media_metadata.dart';
|
import 'package:flutter_media_metadata/flutter_media_metadata.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
part 'metadata_service.g.dart';
|
part 'metadata_service.g.dart';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'dart:io';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:palette_generator/palette_generator.dart';
|
import 'package:palette_generator/palette_generator.dart';
|
||||||
@@ -94,32 +94,16 @@ class SeedColorNotifier extends _$SeedColorNotifier {
|
|||||||
state = color;
|
state = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateFromAlbumArt(String? imagePath) async {
|
void updateFromAlbumArtBytes(Uint8List? artBytes) async {
|
||||||
if (imagePath == null || imagePath.isEmpty) {
|
if (artBytes == null || artBytes.isEmpty) {
|
||||||
// Reset to default color if no album art
|
// Reset to default color if no album art
|
||||||
state = defaultSeedColor;
|
state = defaultSeedColor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validate that the file exists before attempting to load it
|
|
||||||
final file = File(imagePath);
|
|
||||||
if (!await file.exists()) {
|
|
||||||
// File doesn't exist, reset to default color
|
|
||||||
state = defaultSeedColor;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional validation: check if file is readable and not empty
|
|
||||||
final fileStat = await file.stat();
|
|
||||||
if (fileStat.size == 0) {
|
|
||||||
// Empty file, reset to default color
|
|
||||||
state = defaultSeedColor;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final paletteGenerator = await PaletteGenerator.fromImageProvider(
|
final paletteGenerator = await PaletteGenerator.fromImageProvider(
|
||||||
FileImage(file),
|
MemoryImage(artBytes),
|
||||||
size: const Size(200, 200),
|
size: const Size(200, 200),
|
||||||
maximumColorCount: 20, // Increase color count for better extraction
|
maximumColorCount: 20, // Increase color count for better extraction
|
||||||
);
|
);
|
||||||
@@ -140,13 +124,21 @@ class SeedColorNotifier extends _$SeedColorNotifier {
|
|||||||
// Ensure we have a valid color, otherwise use default
|
// Ensure we have a valid color, otherwise use default
|
||||||
state = extractedColor ?? defaultSeedColor;
|
state = extractedColor ?? defaultSeedColor;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Log the error for debugging (in a real app, you'd use proper logging)
|
|
||||||
// debugPrint('Failed to extract color from album art: $e');
|
|
||||||
// If color extraction fails, reset to default color
|
// If color extraction fails, reset to default color
|
||||||
state = defaultSeedColor;
|
state = defaultSeedColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep the old method for backward compatibility, but mark as deprecated
|
||||||
|
@Deprecated(
|
||||||
|
'Use updateFromAlbumArtBytes instead. File path based color extraction is unreliable.',
|
||||||
|
)
|
||||||
|
void updateFromAlbumArt(String? imagePath) async {
|
||||||
|
// This method is deprecated, but kept for compatibility
|
||||||
|
// It will always reset to default since we now use artBytes
|
||||||
|
state = defaultSeedColor;
|
||||||
|
}
|
||||||
|
|
||||||
void resetToDefault() {
|
void resetToDefault() {
|
||||||
state = defaultSeedColor;
|
state = defaultSeedColor;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user