diff --git a/routes/create/controllers/h5pPreviewController.js b/routes/create/controllers/h5pPreviewController.js index c37e1cd..a2dac84 100644 --- a/routes/create/controllers/h5pPreviewController.js +++ b/routes/create/controllers/h5pPreviewController.js @@ -195,7 +195,7 @@ body { margin:0; padding:40px; font-family:-apple-system,BlinkMacSystemFont,"Seg const basePath = `/h5p-preview-files/${previewId}`; const cssTags = cssFiles.map(f => ` `).join('\n'); - const jsTags = jsFiles.map(f => ` `).join('\n'); + const jsTags = jsFiles.map(f => ` `).join('\n'); // Build per-question HTML blocks and H5P.newRunnable() calls const questionBlocks = []; @@ -281,6 +281,15 @@ ${cssTags} ${questionBlocks.join('\n')} + ${jsTags} @@ -291,6 +300,14 @@ ${jsTags} H5P.$window = jQuery(window); jQuery(document).ready(function() { + // Log load failures and available constructors for debugging + if (window.__h5pLoadErrors.length > 0) { + console.error('H5P: Failed to load scripts:', window.__h5pLoadErrors); + } + if (window.__h5pErrors.length > 0) { + console.error('H5P: JS errors during loading:', window.__h5pErrors); + } + ${runnableCalls.join('\n')} }); diff --git a/routes/create/services/h5pExportService.js b/routes/create/services/h5pExportService.js index 6efb581..4000e51 100644 --- a/routes/create/services/h5pExportService.js +++ b/routes/create/services/h5pExportService.js @@ -891,6 +891,72 @@ export function convertQuestionToH5P(question, quiz) { "title": "Cloze question" } }; + } else if (question.type === 'flashcard') { + const front = question.content?.front || question.questionText || "Front of card"; + const back = question.content?.back || question.correctAnswer || "Back of card"; + const escapedFront = front.replace(//g, '>'); + const escapedBack = back.replace(//g, '>'); + + return { + "params": { + "mode": "normal", + "dialogs": [ + { + "text": `
${escapedFront}
`, + "answer": `${escapedBack}
`, + "tips": {}, + "imageAltText": "" + } + ], + "behaviour": { + "enableRetry": true, + "disableBackwardsNavigation": false, + "scaleTextNotCard": false, + "randomCards": false, + "maxProficiency": 5, + "quickProgression": false + }, + "answer": "Turn", + "next": "Next", + "prev": "Previous", + "retry": "Retry", + "correctAnswer": "I got it right!", + "incorrectAnswer": "I got it wrong", + "round": "Round @round", + "cardsLeft": "Cards left: @number", + "nextRound": "Proceed to round @round", + "startOver": "Start over", + "showSummary": "Next", + "summary": "Summary", + "summaryCardsRight": "Cards you got right:", + "summaryCardsWrong": "Cards you got wrong:", + "summaryCardsNotShown": "Cards in pool not shown:", + "summaryOverallScore": "Overall Score", + "summaryCardsCompleted": "Cards you have completed learning:", + "summaryCompletedRounds": "Completed rounds:", + "summaryAllDone": "Well done! You have mastered all @cards cards!", + "progressText": "Card @card of @total", + "cardFrontLabel": "Card front", + "cardBackLabel": "Card back", + "tipButtonLabel": "Show tip", + "audioNotSupported": "Your browser does not support this audio", + "confirmStartingOver": { + "header": "Start over?", + "body": "All progress will be lost. Are you sure you want to start over?", + "cancelLabel": "Cancel", + "confirmLabel": "Start over" + }, + "title": "", + "description": "" + }, + "library": "H5P.Dialogcards 1.9", + "subContentId": crypto.randomBytes(16).toString('hex'), + "metadata": { + "contentType": "Dialog Cards", + "license": "U", + "title": "Flashcard" + } + }; } else if (question.type === 'discussion') { return { "params": {