utils
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
47005a357a
commit
8b754bbd9f
2 changed files with 116 additions and 6 deletions
|
|
@ -283,15 +283,22 @@ class PackDao extends DatabaseAccessor<AppDatabase> with _$PackDaoMixin {
|
|||
Future<List<VoiceModel>> getCardVoices(String cardId) async {
|
||||
print('🔍 DAO getCardVoices: Querying voices for card $cardId');
|
||||
|
||||
// First, check if there are any voices in CardVoices table for this card
|
||||
// First, check if there are any voices in VoiceModels table with direct cardId link
|
||||
final directVoicesQuery = select(voiceModels)
|
||||
..where((v) => v.cardId.equals(cardId));
|
||||
final directVoices = await directVoicesQuery.get();
|
||||
print('🔍 DAO getCardVoices: Found ${directVoices.length} voices in VoiceModels with direct cardId link');
|
||||
|
||||
// Check if there are any voices in CardVoices table for this card
|
||||
final countExpr = cardVoices.cardId.count();
|
||||
final countQuery = selectOnly(cardVoices)
|
||||
..addColumns([countExpr])
|
||||
..where(cardVoices.cardId.equals(cardId));
|
||||
final countResult = await countQuery.getSingle();
|
||||
final count = countResult.read(countExpr) ?? 0;
|
||||
print('🔍 DAO getCardVoices: Found $count entries in CardVoices table for card $cardId');
|
||||
print('🔍 DAO getCardVoices: Found $count entries in CardVoices junction table for card $cardId');
|
||||
|
||||
// Query through junction table
|
||||
final query = select(voiceModels).join([
|
||||
innerJoin(
|
||||
cardVoices,
|
||||
|
|
@ -301,7 +308,13 @@ class PackDao extends DatabaseAccessor<AppDatabase> with _$PackDaoMixin {
|
|||
]);
|
||||
|
||||
final result = await query.map((row) => row.readTable(voiceModels)).get();
|
||||
print('🔍 DAO getCardVoices: Query returned ${result.length} voices');
|
||||
print('🔍 DAO getCardVoices: Query through junction table returned ${result.length} voices');
|
||||
|
||||
// If junction table query returns nothing but direct link exists, return direct voices
|
||||
if (result.isEmpty && directVoices.isNotEmpty) {
|
||||
print('⚠️ DAO getCardVoices: Junction table is empty but direct link exists! Using direct voices.');
|
||||
return directVoices;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -310,16 +323,44 @@ class PackDao extends DatabaseAccessor<AppDatabase> with _$PackDaoMixin {
|
|||
Future<void> addVoiceToCard(String cardId, String voiceId) async {
|
||||
print('🔍 DAO addVoiceToCard: Linking voice $voiceId to card $cardId');
|
||||
try {
|
||||
await into(cardVoices).insert(
|
||||
// Check if voice exists
|
||||
final voice = await getVoiceById(voiceId);
|
||||
if (voice == null) {
|
||||
print('❌ DAO addVoiceToCard: Voice $voiceId does not exist!');
|
||||
throw Exception('Voice $voiceId does not exist');
|
||||
}
|
||||
print('✅ DAO addVoiceToCard: Voice $voiceId exists with cardId=${voice.cardId}');
|
||||
|
||||
// Check if card exists
|
||||
final card = await getCardById(cardId);
|
||||
if (card == null) {
|
||||
print('❌ DAO addVoiceToCard: Card $cardId does not exist!');
|
||||
throw Exception('Card $cardId does not exist');
|
||||
}
|
||||
print('✅ DAO addVoiceToCard: Card $cardId exists');
|
||||
|
||||
// Insert into junction table
|
||||
final result = await into(cardVoices).insert(
|
||||
CardVoicesCompanion.insert(
|
||||
cardId: cardId,
|
||||
voiceId: voiceId,
|
||||
),
|
||||
mode: InsertMode.insertOrIgnore,
|
||||
);
|
||||
print('✅ DAO addVoiceToCard: Successfully linked voice $voiceId to card $cardId');
|
||||
} catch (e) {
|
||||
print('✅ DAO addVoiceToCard: Insert result: $result');
|
||||
|
||||
// Verify the insert
|
||||
final verifyQuery = select(cardVoices)
|
||||
..where((cv) => cv.cardId.equals(cardId) & cv.voiceId.equals(voiceId));
|
||||
final verifyResult = await verifyQuery.getSingleOrNull();
|
||||
if (verifyResult == null) {
|
||||
print('❌ DAO addVoiceToCard: Verification failed! Link was not created.');
|
||||
} else {
|
||||
print('✅ DAO addVoiceToCard: Successfully linked and verified voice $voiceId to card $cardId');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
print('❌ DAO addVoiceToCard: Error linking voice $voiceId to card $cardId: $e');
|
||||
print('Stack trace: $stackTrace');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
69
mnemo_cards_web_v2/lib/utils/card_image_utils.dart
Normal file
69
mnemo_cards_web_v2/lib/utils/card_image_utils.dart
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||
import '../domain/config/api_config_v2.dart';
|
||||
|
||||
/// Utility functions for working with card images
|
||||
class CardImageUtils {
|
||||
/// Get the display URL for a card's image
|
||||
///
|
||||
/// Priority:
|
||||
/// 1. imageUrl (presigned URL from backend)
|
||||
/// 2. image if it's a full URL (starts with http/https)
|
||||
/// 3. image if it's a filename - convert to API endpoint URL
|
||||
///
|
||||
/// Returns null if no image is available
|
||||
static String? getCardImageUrl(
|
||||
GameCardDto card,
|
||||
String packId,
|
||||
) {
|
||||
// First priority: use presigned URL if available
|
||||
if (card.imageUrl != null && card.imageUrl!.isNotEmpty) {
|
||||
return card.imageUrl;
|
||||
}
|
||||
|
||||
// Second priority: check if image is a full URL
|
||||
final image = card.image;
|
||||
if (image != null && image.isNotEmpty) {
|
||||
// If it's already a full URL, use it
|
||||
if (image.startsWith('http://') || image.startsWith('https://')) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// If it's a filename, convert to API endpoint URL
|
||||
return ApiConfigV2.getCardImageUrl(packId, card.id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get the display URL for a card's back image
|
||||
///
|
||||
/// Priority:
|
||||
/// 1. imageBackUrl (presigned URL from backend)
|
||||
/// 2. imageBack if it's a full URL (starts with http/https)
|
||||
/// 3. imageBack if it's a filename - convert to API endpoint URL
|
||||
///
|
||||
/// Returns null if no back image is available
|
||||
static String? getCardImageBackUrl(
|
||||
GameCardDto card,
|
||||
String packId,
|
||||
) {
|
||||
// First priority: use presigned URL if available
|
||||
if (card.imageBackUrl != null && card.imageBackUrl!.isNotEmpty) {
|
||||
return card.imageBackUrl;
|
||||
}
|
||||
|
||||
// Second priority: check if imageBack is a full URL
|
||||
final imageBack = card.imageBack;
|
||||
if (imageBack != null && imageBack.isNotEmpty) {
|
||||
// If it's already a full URL, use it
|
||||
if (imageBack.startsWith('http://') || imageBack.startsWith('https://')) {
|
||||
return imageBack;
|
||||
}
|
||||
|
||||
// If it's a filename, convert to API endpoint URL
|
||||
return ApiConfigV2.getCardImageBackUrl(packId, card.id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue