Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/quiz functionality #564

Merged
merged 75 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
9918844
quiz squash #3
aidanpscott May 21, 2024
19f769b
quiz squash #2
aidanpscott May 22, 2024
62f4677
quiz squash #1
aidanpscott May 28, 2024
fcb6a73
Fix formatting
chrisvire Jun 5, 2024
fb0c468
remove accidentally added static files
aidanpscott Jun 5, 2024
53b1632
Removed unneeded lines
aidanpscott Jun 5, 2024
16618df
Got the audio button added to the navbar for quizzes
aidanpscott Jun 5, 2024
5edbad2
The audio icon is now properly placed in the navbar for quizzes
aidanpscott Jun 5, 2024
f1a7c0c
Added a quizAudioActive store to the audio.js file
aidanpscott Jun 6, 2024
ac1d54e
Quiz: switch from book.type to url in events
chrisvire Jun 6, 2024
9e88056
Fix formatting
chrisvire Jun 6, 2024
4d60345
I think I've been able to implement most of what's needed for
aidanpscott Jun 6, 2024
cfb1435
For the playQuizAnswerAudio function, I put back both the highlighted
aidanpscott Jun 6, 2024
30ca245
I think I almost got the audio file pathing sorted out, but it doesn't
aidanpscott Jun 6, 2024
d1dfb3e
Quick change in quizzes page from answer.hasAudio to answer.audio
aidanpscott Jun 6, 2024
acb6369
Set the quiz answer images to a maximum size and width to keep one set
aidanpscott Jun 6, 2024
197b7ee
Removed unnecessary comments
aidanpscott Jun 6, 2024
9aa4b15
got rid of the currentAnswerIndex stuff in onNextQuestion function for
aidanpscott Jun 6, 2024
f482891
Streamlined quiz answer and question audio to play from the playSound
aidanpscott Jun 6, 2024
8e31506
Add listener back into the quiz page
aidanpscott Jun 6, 2024
b8cfdb3
audio.js quizAudioActive is now set to true by default
aidanpscott Jun 6, 2024
b2c5ec6
audio for quiz questions and answers fully works
aidanpscott Jun 6, 2024
05fa1e7
Quiz answers are now highlighted when audio is played
aidanpscott Jun 7, 2024
64c8a62
For quizzes, the audio now cuts off when an answer is selected.
aidanpscott Jun 7, 2024
0569019
Removed or commented out some console logs. Set textHighlightIndex to
aidanpscott Jun 7, 2024
a94e342
text highlighting bugs for the quizzes has been fixed.
aidanpscott Jun 7, 2024
b071787
Removed console.logs from quiz svelte page
aidanpscott Jun 7, 2024
fa84af2
Quiz questions now shuffle
aidanpscott Jun 7, 2024
fe521db
Reviewed the code and got rid of some unused variables and console logs
aidanpscott Jun 7, 2024
68952df
Corrected an issue where the first quiz question wasn't getting shuffled
aidanpscott Jun 11, 2024
91134ea
removed an unused quizzes variable from the bookSelector
aidanpscott Jun 11, 2024
4d895bd
I implemented onDestory for the quiz page so the audio stops playing
aidanpscott Jun 11, 2024
c71d405
Restore delay in display correct answer when wrong
chrisvire Jun 11, 2024
c336781
For quizzes, I added the ability for an explanation to an answer to be
aidanpscott Jun 12, 2024
402d6eb
Took out old shuffle toggle stuff from quiz page. The explanation is
aidanpscott Jun 12, 2024
896d837
I believe I got explanation audio to work for quizzes. Need to test it
aidanpscott Jun 12, 2024
8f2edf4
Removed unneeded comments
aidanpscott Jun 12, 2024
53ae154
Removed more unneeded comments
aidanpscott Jun 12, 2024
8b200b9
Quiz page now checks if explanations are on the question or answer level
aidanpscott Jun 12, 2024
5fa0e56
Convert Quiz to put explanation at correct level
chrisvire Jun 12, 2024
97597b2
Explanation audio now stops once the next button is clicked
aidanpscott Jun 12, 2024
279a893
Quiz right and wrong answer audio now tied to the json file
aidanpscott Jun 13, 2024
82c2f25
Quiz right and wrong answer audio can now select one randomy based on
aidanpscott Jun 13, 2024
25ed38c
Modified it so explanations aren't given on correct answers.
aidanpscott Jun 13, 2024
0b2e2bb
Corrected the pathing of quiz right and wrong answer audio files
aidanpscott Jun 14, 2024
3eb89d5
ConvertBooks now has default right and wrong quiz audio files if other
aidanpscott Jun 14, 2024
347af86
Got rid of an unneeded comment in the quiz svelte page
aidanpscott Jun 14, 2024
645cbef
Display quiz book in list of books converted
chrisvire Jun 14, 2024
a70d2a6
Fix answer audio sound location
chrisvire Jun 14, 2024
b37223d
For quizzes, put back the answer audio and highlights
aidanpscott Jun 14, 2024
2ee24c1
For quizzes, got the right and wrong answer audio working again
aidanpscott Jun 14, 2024
8267cf0
Audio is no longer stopping like it's supposed to. Need to fix
aidanpscott Jun 14, 2024
908bef1
Corrected an issue where the audio wasn't stopping when onDestroy
aidanpscott Jun 18, 2024
a8fce1d
changed quiz right/wrong audio pathing to clips instead of assets
aidanpscott Jun 19, 2024
a2e6be5
Made some more corrections to quiz right/wrong audio pathing
aidanpscott Jun 19, 2024
6471169
for quizzes, right/wrong audio plays, and then explanation audio
aidanpscott Jun 19, 2024
5ec5737
Fix runtime a11y and unused style warnings
chrisvire Jun 19, 2024
1f8ca3c
Change columns (\ac) to be per-question
chrisvire Jun 19, 2024
81d8b18
Quiz answers are now divided into columns based on what's in the JSON
aidanpscott Jun 25, 2024
fa2eb34
Fixed the quiz column changes so everything is now there.
aidanpscott Jun 25, 2024
6d1381f
Got rid of an extra bracket in a div class
aidanpscott Jun 25, 2024
588f3e3
The default number of columns is now 2 for quiz answers
aidanpscott Jun 25, 2024
448b745
quiz answers can now be divided into 3 columns
aidanpscott Jun 25, 2024
b5d0fa7
Removed tables from quiz page and converted to tailwind grid
aidanpscott Jun 25, 2024
0e38031
Quiz answer sizes now accommodate for columns
aidanpscott Jun 25, 2024
3de21ab
Made some changes to quiz answer div classes
aidanpscott Jun 25, 2024
74d0c5b
Made some changes to the sizing of quiz answers
aidanpscott Jun 25, 2024
23b681d
Styled the quiz answers again
aidanpscott Jun 26, 2024
78d518a
fixed a columns typo in the quiz page
aidanpscott Jun 26, 2024
d05f488
I think I've finished touching up the quiz answer styling
aidanpscott Jun 26, 2024
35c3571
Ignore ally warning
chrisvire Jun 26, 2024
0f85f17
Tightening up quiz classes
aidanpscott Jun 26, 2024
c62158f
Finished tightening up quiz classes
aidanpscott Jun 26, 2024
1b245b8
Made one last change to quiz class tightening
aidanpscott Jun 26, 2024
3acf024
Added the h-40 back into quiz question images
aidanpscott Jun 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 52 additions & 17 deletions convert/convertBooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,9 @@ export async function convertBooks(
'quizzes',
book.id + '.json'
),
content: JSON.stringify(convertQuizBook(context, book))
content: JSON.stringify(convertQuizBook(context, book), null, 2)
});
process.stdout.write(` ${book.id}`);
chrisvire marked this conversation as resolved.
Show resolved Hide resolved
break;
default:
bookConverted = true;
Expand Down Expand Up @@ -291,28 +292,30 @@ export async function convertBooks(
};
}

type QuizAnswer = {
export type QuizExplanation = {
text?: string;
audio?: string;
};

export type QuizAnswer = {
//\aw or \ar
correct: boolean;
text?: string;
image?: string;
audio?: string;
explanation?: {
//\ae
text: string;
audio?: string;
};
explanation?: QuizExplanation;
};

type QuizQuestion = {
export type QuizQuestion = {
//\qu
text: string;
image?: string;
audio?: string;
explanation?: QuizExplanation;
answers: QuizAnswer[];
};

type Quiz = {
export type Quiz = {
id: string; //\id
name?: string; //\qn
shortName?: string; //\qs
Expand Down Expand Up @@ -359,7 +362,7 @@ function convertQuizBook(context: ConvertBookContext, book: Book): Quiz {
const parsed = m.match(/([0-9]+)( *- *[0-9]+)? ([^\\\r\n]+)/i)!;
return {
rangeMin: parseInt(parsed[1]),
rangeMax: parsed[2] ? parseInt(parsed[2]) : undefined,
rangeMax: parsed[2] ? parseInt(parsed[2].replace('-', '')) : parseInt(parsed[1]),
message: parsed[3]
};
}),
Expand Down Expand Up @@ -409,13 +412,30 @@ function convertQuizBook(context: ConvertBookContext, book: Book): Quiz {
}
break;
case 'ae':
if (!question.answers[aCount - 1].explanation) {
question.answers[aCount - 1].explanation = { text: '' };
}
if (hasAudioExtension(parsed[2])) {
question.answers[aCount - 1].explanation!.audio = parsed[2];
} else {
question.answers[aCount - 1].explanation!.text = parsed[2];
{
const isAudio = hasAudioExtension(parsed[2]);
const hasExplanationsInAnswers = isAudio
? question.answers.some((answer) => answer.explanation?.audio !== undefined)
: question.answers.some((answer) => answer.explanation?.text != undefined);

if (aCount == 0) {
// Question-level explanation
question.explanation = updateExplanation(question.explanation, parsed[2]);
} else {
if (aCount == 1 || hasExplanationsInAnswers) {
// Answer-specific explanation
question.answers[aCount - 1].explanation = updateExplanation(
question.answers[aCount - 1].explanation,
parsed[2]
);
} else {
// Question-level explanation (same for all answers)
question.explanation = updateExplanation(
question.explanation,
parsed[2]
);
}
}
}
break;
}
Expand All @@ -424,6 +444,21 @@ function convertQuizBook(context: ConvertBookContext, book: Book): Quiz {
return quiz;
}

function updateExplanation(
explanation: QuizExplanation | undefined,
text: string
): QuizExplanation {
if (!explanation) {
explanation = {};
}
if (hasAudioExtension(text)) {
explanation.audio = text;
} else {
explanation.text = text;
}
return explanation;
}

function convertScriptureBook(
pk: SABProskomma,
context: ConvertBookContext,
Expand Down
50 changes: 40 additions & 10 deletions src/lib/components/BookSelector.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ The navbar component.
import config from '$lib/data/config';
import SelectList from './SelectList.svelte';
import * as numerals from '$lib/scripts/numeralSystem';
import { goto } from '$app/navigation';
import { base } from '$app/paths';

export let displayLabel;
$: book = $nextRef.book === '' ? $refs.book : $nextRef.book;
$: chapter = $nextRef.chapter === '' ? $refs.chapter : $nextRef.chapter;
$: verseCount = getVerseCount(chapter, chapters);
Expand All @@ -29,9 +32,11 @@ The navbar component.
$: v = $t.Selector_Verse;

let bookSelector;
$: label = config.bookCollections
.find((x) => x.id === $refs.collection)
.books.find((x) => x.id === book).name;
$: label =
displayLabel ??
config.bookCollections
.find((x) => x.id === $refs.collection)
.books.find((x) => x.id === book).name;

function chapterCount(book) {
let count = Object.keys(books.find((x) => x.bookCode === book).versesByChapters).length;
Expand All @@ -48,7 +53,20 @@ The navbar component.
/**
* Pushes reference changes to nextRef. Pushes final change to default reference.
*/

async function navigateReference(e) {
// Handle special book navigation first
if (e.detail.tab === b && e.detail?.url) {
const book = e.detail.text;
addHistory({
collection: $refs.collection,
book,
chapter: '',
url: e.detail.url
});
goto(e.detail.url);
return;
}
if (!showChapterSelector) {
$nextRef.book = e.detail.text;
await refs.set({ book: $nextRef.book, chapter: 1 });
Expand Down Expand Up @@ -104,6 +122,7 @@ The navbar component.
verse: $nextRef.verse
});
document.activeElement.blur();
goto(`${base}/`);
}

function resetNavigation() {
Expand All @@ -113,24 +132,35 @@ The navbar component.
nextRef.reset();
}

/**list of books in current docSet*/
/**list of books, quizzes, and quiz groups in current docSet*/
$: books = $refs.catalog.documents;
/**list of chapters in current book*/
$: chapters = books.find((d) => d.bookCode === book).versesByChapters;

function getBookUrl(book) {
let url;
if (book.type === 'quiz') {
url = `${base}/quiz/${$refs.collection}/${book.id}`;
}
return url;
}

let bookGridGroup = ({ colId, bookLabel = 'abbreviation' }) => {
let groups = [];
var lastGroup = null;

config.bookCollections
.find((x) => x.id === colId)
.books.forEach((book) => {
// Include books only in the catalog (i.e. only supported book types)
if (books.find((x) => x.bookCode === book.id)) {
const url = getBookUrl(book);
if (books.find((x) => x.bookCode === book.id) || url) {
let label = book[bookLabel] || book.name;
let cell = { label: label, id: book.id };
let cell = { label, id: book.id, url };
let group = book.testament || '';
if ((lastGroup == null || group !== lastGroup) && config.mainFeatures['book-group-titles']) {
if (
(lastGroup == null || group !== lastGroup) &&
config.mainFeatures['book-group-titles']
) {
// Create new group
groups.push({
header: book.testament
Expand All @@ -143,8 +173,8 @@ The navbar component.
lastGroup = group;
} else {
// Add Book to last group
let cells = groups[groups.length - 1].cells;
groups[groups.length - 1].cells = [...cells, cell];
let cells = groups.at(-1).cells;
groups.at(-1).cells = [...cells, cell];
}
}
});
Expand Down
29 changes: 19 additions & 10 deletions src/lib/components/HistoryCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TODO:
import { formatDateAndTime } from '$lib/scripts/dateUtils';
import { base } from '$app/paths';
import config from '$lib/data/config';
import { goto } from '$app/navigation';
export let history: HistoryItem;

$: bc = config.bookCollections.find((x) => x.id === history.collection);
Expand All @@ -22,21 +23,29 @@ TODO:
: history.chapter;
$: dateFormat = formatDateAndTime(new Date(history.date));
$: textDirection = bc.style.textDirection;
</script>

<!-- history cards are alway LTR with the reference following the text direction -->
<div class="history-item-block dy-card w-100 bg-base-100 shadow-lg my-4" style:direction="ltr">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<a
style="text-decoration:none;"
href="{base}/"
on:click={() =>
function onHistoryClick() {
if (history.url) {
chrisvire marked this conversation as resolved.
Show resolved Hide resolved
goto(history.url);
} else {
refs.set({
docSet,
book: history.book,
chapter: history.chapter,
verse: history.verse
})}
})
goto(`${base}/`);
}
}
</script>

<!-- history cards are alway LTR with the reference following the text direction -->
<div class="history-item-block dy-card w-100 bg-base-100 shadow-lg my-4" style:direction="ltr">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
style="text-decoration:none;"
on:click={onHistoryClick}
>
<div
class="history-card grid grid-cols-1"
Expand All @@ -55,5 +64,5 @@ TODO:
</div>
<div class="history-item-date justify-self-start">{dateFormat}</div>
</div>
</a>
</div>
</div>
9 changes: 6 additions & 3 deletions src/lib/components/SelectGrid.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ A component to display menu options in a grid.
return color;
};

function handleClick(opt: string) {
function handleClick(opt: any) {
const text = opt.id;
const url = opt?.url;
dispatch('menuaction', {
text: opt
text,
url
});
}
</script>
Expand Down Expand Up @@ -114,7 +117,7 @@ A component to display menu options in a grid.
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span
on:click={() => handleClick(cell.id)}
on:click={() => handleClick(cell)}
id={cell.id}
class="dy-btn dy-btn-square dy-btn-ghost normal-case truncate text-clip"
style={cellStyle}
Expand Down
9 changes: 6 additions & 3 deletions src/lib/components/SelectList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ A component to display menu options in a list.

const dispatch = createEventDispatcher();

function handleClick(opt: string) {
function handleClick(opt: any) {
const text = opt.id;
const url = opt?.url;
dispatch('menuaction', {
text: opt
text,
url
});
}

Expand All @@ -32,7 +35,7 @@ A component to display menu options in a list.
<!-- svelte-ignore a11y-interactive-supports-focus -->
<span
on:click={() =>
handleClick(group.cells[ri * group.cells.length + ci].id)}
handleClick(group.cells[ri * group.cells.length + ci])}
class="menu p-0 cursor-pointer hover:bg-base-100 min-w-[16rem]"
role="button"
>
Expand Down
1 change: 1 addition & 0 deletions src/lib/components/TabsMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ A component to display tabbed menus.
function handleMenuaction({ detail }: CustomEvent) {
dispatch('menuaction', {
text: detail.text,
url: detail?.url,
tab: active
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/data/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface HistoryItem {
book: string;
chapter: string;
verse?: string;
url?: string;
}
interface History extends DBSchema {
history: {
Expand Down Expand Up @@ -39,6 +40,7 @@ export async function addHistory(item: {
book: string;
chapter: string;
verse?: string;
url?: string;
}) {
let history = await openHistory();
if (nextTimer) {
Expand Down
5 changes: 5 additions & 0 deletions src/lib/data/stores/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import config from '../config';
setDefaultStorage('audioActive', config.mainFeatures['audio-turn-on-at-startup']);
export const audioActive = writable(localStorage.audioActive === 'true');
audioActive.subscribe((value) => (localStorage.audioActive = value));

setDefaultStorage('quizAudioActive', true);
export const quizAudioActive = writable(localStorage.quizAudioActive);
quizAudioActive.subscribe((value) => (localStorage.quizAudioActive = value));

/**which element should be highlighted as the audio is playing*/
function createaudioHighlightElements() {
const external = writable([]);
Expand Down
21 changes: 21 additions & 0 deletions src/routes/quiz/[collection]/[id]/+page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { base } from '$app/paths';

/** @type {import('./$types').PageLoad} */
export async function load({ params, fetch }) {
const id = params.id;
const collection = params.collection;

try {
const response = await fetch(`${base}/collections/${collection}/quizzes/${id}.json`);

if (!response.ok) {
throw new Error('Failed to fetch quiz JSON file');
}

const quizData = await response.json();
return { quiz: quizData };
} catch (error) {
console.error('Error fetching quiz JSON file:', error);
return {};
}
}
Loading
Loading