From 826d4c0184fddc31951c0d5bcc5259662dc7c580 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Wed, 1 May 2024 20:19:06 -0700 Subject: [PATCH 01/21] Update .gitignore to exclude node_modules --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 496ee2ca6..646ac519e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +node_modules/ From 19ed83db248da4d0797272fa791cd0db90acb2d9 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 15:08:36 -0700 Subject: [PATCH 02/21] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index f211f6f26..c2b4ddb66 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ # Lab 5 - Starter + +## Check Your Understanding + +### Question 1 +Would you use a unit test to test the “message” feature of a messaging application? Why or why not? For this question, assume the “message” feature allows a user to write and send a message to another user. + +**Answer:** +Unit testing might not be the best choice for testing the entire "message" feature due to its reliance on multiple interacting components. However, unit tests are suitable for testing individual parts of the feature such as the message formatting and validation functions. + +### Question 2 +Would you use a unit test to test the “max message length” feature of a messaging application? Why or why not? For this question, assume the “max message length” feature prevents the user from typing more than 80 characters. + +**Answer:** +Yes, unit testing is appropriate for the "max message length" feature. This feature's functionality is isolated and can be precisely defined and tested without external dependencies, making it ideal for unit testing. From 5ce9bbad93494e14c07f2c987a15239e55ce76f6 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 18:53:19 -0700 Subject: [PATCH 03/21] Explore and expose --- __tests__/sum.test.js | 1 + __tests__/unit.test.js | 49 ++++++++++++++++++++++++++++++++++++++ assets/scripts/explore.js | 50 +++++++++++++++++++++++++++++++++++++++ assets/scripts/expose.js | 35 +++++++++++++++++++++++++++ 4 files changed, 135 insertions(+) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index a98ab36e7..fb253d65c 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -2,4 +2,5 @@ test('adds 1 + 2 to equal 3', () => { // TODO + expect(sum(1, 2)).toBe(3); }); diff --git a/__tests__/unit.test.js b/__tests__/unit.test.js index 118a476e0..5b687c00f 100644 --- a/__tests__/unit.test.js +++ b/__tests__/unit.test.js @@ -9,3 +9,52 @@ import { } from '../code-to-unit-test/unit-test-me'; // TODO - Part 2 +// Tests for isPhoneNumber +describe('isPhoneNumber', () => { + test('validates correct phone number', () => { + expect(isPhoneNumber('123-456-7890')).toBe(true); + }); + test('rejects incorrect phone number', () => { + expect(isPhoneNumber('123-45-6789')).toBe(false); + }); +}); + +// Tests for isEmail +describe('isEmail', () => { + test('validates correct email', () => { + expect(isEmail('test@example.com')).toBe(true); + }); + test('rejects incorrect email', () => { + expect(isEmail('test@example')).toBe(false); + }); +}); + +// Tests for isStrongPassword +describe('isStrongPassword', () => { + test('validates strong password', () => { + expect(isStrongPassword('Example123!')).toBe(true); + }); + test('rejects weak password', () => { + expect(isStrongPassword('examp')).toBe(false); + }); +}); + +// Tests for isDate +describe('isDate', () => { + test('validates correct date', () => { + expect(isDate('2021-04-12')).toBe(true); + }); + test('rejects incorrect date', () => { + expect(isDate('April 12, 2021')).toBe(false); + }); +}); + +// Tests for isHexColor +describe('isHexColor', () => { + test('validates correct hex color', () => { + expect(isHexColor('#FFFFFF')).toBe(true); + }); + test('rejects incorrect hex color', () => { + expect(isHexColor('FFFFFF')).toBe(false); + }); +}); diff --git a/assets/scripts/explore.js b/assets/scripts/explore.js index 777f5ee3a..77cb5e38d 100644 --- a/assets/scripts/explore.js +++ b/assets/scripts/explore.js @@ -4,4 +4,54 @@ window.addEventListener('DOMContentLoaded', init); function init() { // TODO + const textArea = document.getElementById('text-to-speak'); + const voiceSelect = document.getElementById('voice-select'); + const talkButton = document.querySelector('button'); + const faceImage = document.querySelector('img'); + + function populateVoiceList() { + if (typeof speechSynthesis === 'undefined') { + return; + } + let voices = speechSynthesis.getVoices(); + + for (let i = 0; i < voices.length; i++) { + let option = document.createElement('option'); + option.textContent = voices[i].name + ' (' + voices[i].lang + ')'; + if (voices[i].default) { + option.textContent += ' — DEFAULT'; + } + option.setAttribute('data-name', voices[i].name); + option.setAttribute('data-lang', voices[i].lang); + voiceSelect.appendChild(option); + } + } + + populateVoiceList(); + if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== null) { + speechSynthesis.onvoiceschanged = populateVoiceList; + } + + function speak() { + if (speechSynthesis.speaking) { + console.error('speechSynthesis.speaking'); + return; + } + if (textArea.value !== '') { + let utterance = new SpeechSynthesisUtterance(textArea.value); + let selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name'); + utterance.voice = speechSynthesis.getVoices().find(voice => voice.name === selectedOption); + + utterance.onstart = function () { + faceImage.src = 'assets/images/smiling-open.png'; + }; + utterance.onend = function () { + faceImage.src = 'assets/images/smiling.png'; + }; + + speechSynthesis.speak(utterance); + } + } + + talkButton.addEventListener('click', speak); } \ No newline at end of file diff --git a/assets/scripts/expose.js b/assets/scripts/expose.js index 962d7a33c..80dccb123 100644 --- a/assets/scripts/expose.js +++ b/assets/scripts/expose.js @@ -4,4 +4,39 @@ window.addEventListener('DOMContentLoaded', init); function init() { // TODO + const hornSelect = document.getElementById('horn-select'); + const volumeSlider = document.getElementById('volume'); + const playButton = document.querySelector('button'); + const audioElement = document.querySelector('audio'); + const imageElement = document.querySelector('#expose img'); + const volumeIcon = document.querySelector('#volume-controls img'); + + hornSelect.addEventListener('change', function() { + const selectedOption = hornSelect.options[hornSelect.selectedIndex].value; + imageElement.src = `assets/images/${selectedOption}.svg`; + audioElement.src = `assets/audio/${selectedOption}.mp3`; + }); + + volumeSlider.addEventListener('input', function() { + const volume = parseInt(volumeSlider.value); + audioElement.volume = volume / 100; + + if (volume === 0) { + volumeIcon.src = 'assets/icons/volume-level-0.svg'; + } else if (volume < 33) { + volumeIcon.src = 'assets/icons/volume-level-1.svg'; + } else if (volume < 67) { + volumeIcon.src = 'assets/icons/volume-level-2.svg'; + } else { + volumeIcon.src = 'assets/icons/volume-level-3.svg'; + } + }); + + playButton.addEventListener('click', function() { + audioElement.play(); + if (hornSelect.value === 'party-horn') { + const jsConfetti = new JSConfetti(); + jsConfetti.addConfetti(); + } + }); } \ No newline at end of file From 110bc5918f281613058239539dcf42e29c464aa8 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:00:45 -0700 Subject: [PATCH 04/21] Update sum.test.js --- __tests__/sum.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index fb253d65c..4d826777d 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -2,5 +2,5 @@ test('adds 1 + 2 to equal 3', () => { // TODO - expect(sum(1, 2)).toBe(3); + expect(sum(1 + 2)).toBe(3); }); From 2efe1be07509759af745fb060557380fdd8f05ac Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:05:59 -0700 Subject: [PATCH 05/21] Update sum.test.js --- __tests__/sum.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index 4d826777d..e3aea66f9 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -4,3 +4,8 @@ test('adds 1 + 2 to equal 3', () => { // TODO expect(sum(1 + 2)).toBe(3); }); +import { sum } from '../code-to-unit-test/sum'; +// Test adding zero +test('adds 0 + 5 to equal 5', () => { + expect(sum(0, 5)).toBe(5); +}); \ No newline at end of file From 5930b952f24e2d686576c29dea80580c46d0ecd7 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:07:15 -0700 Subject: [PATCH 06/21] Update sum.test.js --- __tests__/sum.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index e3aea66f9..858d42fe7 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -1,10 +1,9 @@ // sum.test.js - +import { sum } from '../code-to-unit-test/sum'; test('adds 1 + 2 to equal 3', () => { // TODO expect(sum(1 + 2)).toBe(3); }); -import { sum } from '../code-to-unit-test/sum'; // Test adding zero test('adds 0 + 5 to equal 5', () => { expect(sum(0, 5)).toBe(5); From aec3e1999efd31d73795aa3b58b44d09959d23b0 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:09:16 -0700 Subject: [PATCH 07/21] Update sum.test.js --- __tests__/sum.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index 858d42fe7..51f755797 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -4,7 +4,7 @@ test('adds 1 + 2 to equal 3', () => { // TODO expect(sum(1 + 2)).toBe(3); }); -// Test adding zero -test('adds 0 + 5 to equal 5', () => { - expect(sum(0, 5)).toBe(5); + +test('adds 1 + 2 to equal 3', () => { + expect(sum(1,2)).toBe(3); }); \ No newline at end of file From 0dab01486589493d975e221a26004b4c910b48c1 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:15:19 -0700 Subject: [PATCH 08/21] Update sum.test.js --- __tests__/sum.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index 51f755797..92e2ec070 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -1,5 +1,6 @@ // sum.test.js import { sum } from '../code-to-unit-test/sum'; + test('adds 1 + 2 to equal 3', () => { // TODO expect(sum(1 + 2)).toBe(3); From 6ac1ce36a63691e614e43d49b89ef2f2a8c32d6f Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:16:17 -0700 Subject: [PATCH 09/21] Create main.yml --- .github/workflows/main.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..0f9ccffe6 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,13 @@ +name: Unit Tests # name of the test + +on: [push] # the Github Action will activate "on" the event that you "push" to the repo + +jobs: # the things being executed + tests: # the name of your status check, will become important when you do branch protection + runs-on: ubuntu-latest # which device on Github's server that you are running the Actions on + steps: + - uses: actions/checkout@v4 # using version 4 of Actions + - name: Install Dependencies + run: npm install + - name: Unit Test + run: npm test ./__tests__/sum.test.js # the actual testing line From e450f39d021fb2a3b0dd5b385eaa7c9b7c10d088 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:17:31 -0700 Subject: [PATCH 10/21] Update sum.test.js --- __tests__/sum.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index 92e2ec070..17d5d7543 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -7,5 +7,5 @@ test('adds 1 + 2 to equal 3', () => { }); test('adds 1 + 2 to equal 3', () => { - expect(sum(1,2)).toBe(3); + expect(sum(1,2)).toBe(4); //should be wrong }); \ No newline at end of file From 94080b6445f82d49d4c115bca9f13bb0679623d5 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:28:31 -0700 Subject: [PATCH 11/21] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c2b4ddb66..e4eb523bf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Lab 5 - Starter +Members: David De Santiago - A17001592 + +- My "expose.js" [here](expose.html) +- My "explore.js" [here](explore.html) +- ## Check Your Understanding ### Question 1 From d4178731658be23c3466d35765bc1545e98201f6 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:28:40 -0700 Subject: [PATCH 12/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4eb523bf..80edce1d7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Members: David De Santiago - A17001592 - My "expose.js" [here](expose.html) - My "explore.js" [here](explore.html) -- + ## Check Your Understanding ### Question 1 From be72e07c1b0131166ca3034d0b5171f4bc00708f Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:38:05 -0700 Subject: [PATCH 13/21] Update unit.test.js --- __tests__/unit.test.js | 54 ++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/__tests__/unit.test.js b/__tests__/unit.test.js index 5b687c00f..b1f2bac6d 100644 --- a/__tests__/unit.test.js +++ b/__tests__/unit.test.js @@ -11,50 +11,80 @@ import { // TODO - Part 2 // Tests for isPhoneNumber describe('isPhoneNumber', () => { - test('validates correct phone number', () => { + test('validates correct phone number format', () => { expect(isPhoneNumber('123-456-7890')).toBe(true); }); - test('rejects incorrect phone number', () => { + test('validates another correct phone number format', () => { + expect(isPhoneNumber('(123) 456-7890')).toBe(true); + }); + test('rejects incorrect phone number without dashes', () => { + expect(isPhoneNumber('1234567890')).toBe(false); + }); + test('rejects incorrect phone number with too few digits', () => { expect(isPhoneNumber('123-45-6789')).toBe(false); }); }); // Tests for isEmail describe('isEmail', () => { - test('validates correct email', () => { + test('validates correct email format', () => { expect(isEmail('test@example.com')).toBe(true); }); - test('rejects incorrect email', () => { - expect(isEmail('test@example')).toBe(false); + test('validates another correct email format', () => { + expect(isEmail('hello.world@domain.co.uk')).toBe(true); + }); + test('rejects missing domain email', () => { + expect(isEmail('test@')).toBe(false); + }); + test('rejects email without "@" symbol', () => { + expect(isEmail('testexample.com')).toBe(false); }); }); // Tests for isStrongPassword describe('isStrongPassword', () => { - test('validates strong password', () => { + test('validates strong password with special characters', () => { expect(isStrongPassword('Example123!')).toBe(true); }); - test('rejects weak password', () => { + test('validates strong password with underscore', () => { + expect(isStrongPassword('Strong_Pass1')).toBe(true); + }); + test('rejects weak password with fewer characters', () => { expect(isStrongPassword('examp')).toBe(false); }); + test('rejects password without numbers or special characters', () => { + expect(isStrongPassword('WeakPassword')).toBe(false); + }); }); // Tests for isDate describe('isDate', () => { - test('validates correct date', () => { - expect(isDate('2021-04-12')).toBe(true); + test('validates correct date format MM/DD/YYYY', () => { + expect(isDate('04/12/2021')).toBe(true); + }); + test('validates correct date format MM/D/YYYY', () => { + expect(isDate('04/2/2021')).toBe(true); }); - test('rejects incorrect date', () => { + test('rejects incorrect date format with month name', () => { expect(isDate('April 12, 2021')).toBe(false); }); + test('rejects incorrect format without year', () => { + expect(isDate('04/12')).toBe(false); + }); }); // Tests for isHexColor describe('isHexColor', () => { - test('validates correct hex color', () => { + test('validates correct 6-digit hex color', () => { expect(isHexColor('#FFFFFF')).toBe(true); }); - test('rejects incorrect hex color', () => { + test('validates correct 3-digit hex color', () => { + expect(isHexColor('#FFF')).toBe(true); + }); + test('rejects hex color without #', () => { expect(isHexColor('FFFFFF')).toBe(false); }); + test('rejects incorrect hex color with non-hex characters', () => { + expect(isHexColor('#ZZZZZZ')).toBe(false); + }); }); From 915b783e4410fd062deb4c03b486dcd5321b3e3d Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Tue, 7 May 2024 19:38:23 -0700 Subject: [PATCH 14/21] Update sum.test.js --- __tests__/sum.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/sum.test.js b/__tests__/sum.test.js index 17d5d7543..e5618b256 100644 --- a/__tests__/sum.test.js +++ b/__tests__/sum.test.js @@ -7,5 +7,5 @@ test('adds 1 + 2 to equal 3', () => { }); test('adds 1 + 2 to equal 3', () => { - expect(sum(1,2)).toBe(4); //should be wrong + expect(sum(1,2)).toBe(3); //should be wrong }); \ No newline at end of file From 9b2a8415d0f3a511d96e4458bbd252dcc78c3b57 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:04:34 -0700 Subject: [PATCH 15/21] Update explore.js --- assets/scripts/explore.js | 89 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/assets/scripts/explore.js b/assets/scripts/explore.js index 77cb5e38d..1cd5adebc 100644 --- a/assets/scripts/explore.js +++ b/assets/scripts/explore.js @@ -1,57 +1,54 @@ // explore.js +// resources: https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis window.addEventListener('DOMContentLoaded', init); +const synth = window.speechSynthesis; function init() { - // TODO - const textArea = document.getElementById('text-to-speak'); - const voiceSelect = document.getElementById('voice-select'); - const talkButton = document.querySelector('button'); - const faceImage = document.querySelector('img'); + // populate the select options on page load + let availableVoices = []; + const voiceDropdown = document.querySelector('select'); - function populateVoiceList() { - if (typeof speechSynthesis === 'undefined') { - return; - } - let voices = speechSynthesis.getVoices(); - - for (let i = 0; i < voices.length; i++) { - let option = document.createElement('option'); - option.textContent = voices[i].name + ' (' + voices[i].lang + ')'; - if (voices[i].default) { - option.textContent += ' — DEFAULT'; - } - option.setAttribute('data-name', voices[i].name); - option.setAttribute('data-lang', voices[i].lang); - voiceSelect.appendChild(option); - } + function populateVoiceOptions() { + availableVoices = synth.getVoices(); + for (let i = 0; i < availableVoices.length; i++) { + const option = document.createElement('option'); + option.textContent = `${availableVoices[i].name} (${availableVoices[i].lang})`; + if (availableVoices[i].default) { + option.textContent += ' — DEFAULT'; + } + option.setAttribute('data-lang', availableVoices[i].lang); + option.setAttribute('data-name', availableVoices[i].name); + voiceDropdown.appendChild(option); } + } - populateVoiceList(); - if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== null) { - speechSynthesis.onvoiceschanged = populateVoiceList; - } + populateVoiceOptions(); + if (synth.onvoiceschanged !== undefined) { + synth.onvoiceschanged = populateVoiceOptions; + } + + const textInput = document.getElementById('text-to-speak'); + + const speakButton = document.querySelector('button'); - function speak() { - if (speechSynthesis.speaking) { - console.error('speechSynthesis.speaking'); - return; - } - if (textArea.value !== '') { - let utterance = new SpeechSynthesisUtterance(textArea.value); - let selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name'); - utterance.voice = speechSynthesis.getVoices().find(voice => voice.name === selectedOption); - - utterance.onstart = function () { - faceImage.src = 'assets/images/smiling-open.png'; - }; - utterance.onend = function () { - faceImage.src = 'assets/images/smiling.png'; - }; - - speechSynthesis.speak(utterance); - } + speakButton.addEventListener('click', () => { + const utterance = new SpeechSynthesisUtterance(textInput.value); + const selectedVoice = voiceDropdown.selectedOptions[0].getAttribute('data-name'); + for (let i = 0; i < availableVoices.length; i++) { + if (availableVoices[i].name === selectedVoice) { + utterance.voice = availableVoices[i]; + break; + } } - talkButton.addEventListener('click', speak); -} \ No newline at end of file + const faceImage = document.querySelector('img'); + faceImage.src = 'assets/images/smiling-open.png'; + + utterance.onend = () => { + faceImage.src = 'assets/images/smiling.png'; + }; + + synth.speak(utterance); + }); +} From 3228381258bc0021487829be5dee2bfc79c9ade3 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:12:11 -0700 Subject: [PATCH 16/21] Update expose.js --- assets/scripts/expose.js | 57 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/assets/scripts/expose.js b/assets/scripts/expose.js index 80dccb123..705bfd8fb 100644 --- a/assets/scripts/expose.js +++ b/assets/scripts/expose.js @@ -3,40 +3,49 @@ window.addEventListener('DOMContentLoaded', init); function init() { - // TODO - const hornSelect = document.getElementById('horn-select'); - const volumeSlider = document.getElementById('volume'); - const playButton = document.querySelector('button'); + //TODO + // Get references to DOM elements + const hornSelectElement = document.getElementById('horn-select'); + const volumeSliderElement = document.getElementById('volume'); + const playButtonElement = document.querySelector('button'); const audioElement = document.querySelector('audio'); - const imageElement = document.querySelector('#expose img'); - const volumeIcon = document.querySelector('#volume-controls img'); + const hornImageElement = document.querySelector('#expose img'); + const volumeIconElement = document.querySelector('#volume-controls img'); - hornSelect.addEventListener('change', function() { - const selectedOption = hornSelect.options[hornSelect.selectedIndex].value; - imageElement.src = `assets/images/${selectedOption}.svg`; - audioElement.src = `assets/audio/${selectedOption}.mp3`; + // Event listener for horn selection + hornSelectElement.addEventListener('change', function() { + const selectedHorn = hornSelectElement.value; + hornImageElement.src = `assets/images/${selectedHorn}.svg`; + hornImageElement.alt = selectedHorn; + audioElement.src = `assets/audio/${selectedHorn}.mp3`; }); - volumeSlider.addEventListener('input', function() { - const volume = parseInt(volumeSlider.value); - audioElement.volume = volume / 100; + // Event listener for volume slider + volumeSliderElement.addEventListener('input', function() { + const volumeValue = volumeSliderElement.value; + audioElement.volume = volumeValue / 100; - if (volume === 0) { - volumeIcon.src = 'assets/icons/volume-level-0.svg'; - } else if (volume < 33) { - volumeIcon.src = 'assets/icons/volume-level-1.svg'; - } else if (volume < 67) { - volumeIcon.src = 'assets/icons/volume-level-2.svg'; + if (volumeValue == 0) { + volumeIconElement.src = 'assets/icons/volume-level-0.svg'; + volumeIconElement.alt = 'Volume level 0'; + } else if (volumeValue < 33) { + volumeIconElement.src = 'assets/icons/volume-level-1.svg'; + volumeIconElement.alt = 'Volume level 1'; + } else if (volumeValue < 67) { + volumeIconElement.src = 'assets/icons/volume-level-2.svg'; + volumeIconElement.alt = 'Volume level 2'; } else { - volumeIcon.src = 'assets/icons/volume-level-3.svg'; + volumeIconElement.src = 'assets/icons/volume-level-3.svg'; + volumeIconElement.alt = 'Volume level 3'; } }); - playButton.addEventListener('click', function() { + // Event listener for play button + playButtonElement.addEventListener('click', function() { audioElement.play(); - if (hornSelect.value === 'party-horn') { - const jsConfetti = new JSConfetti(); + if (hornSelectElement.value === 'party-horn') { + const jsConfetti = new JSConfetti(); jsConfetti.addConfetti(); } }); -} \ No newline at end of file +} From d6c773725c79edd0edd7696140e97f94c5a3d0ae Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:14:13 -0700 Subject: [PATCH 17/21] Update expose.js --- assets/scripts/expose.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/scripts/expose.js b/assets/scripts/expose.js index 705bfd8fb..80287b3f7 100644 --- a/assets/scripts/expose.js +++ b/assets/scripts/expose.js @@ -3,7 +3,6 @@ window.addEventListener('DOMContentLoaded', init); function init() { - //TODO // Get references to DOM elements const hornSelectElement = document.getElementById('horn-select'); const volumeSliderElement = document.getElementById('volume'); @@ -45,7 +44,13 @@ function init() { audioElement.play(); if (hornSelectElement.value === 'party-horn') { const jsConfetti = new JSConfetti(); - jsConfetti.addConfetti(); + jsConfetti.addConfetti({ + confettiRadius: 6, + confettiNumber: 300, + spread: 120, + startVelocity: 50, + gravity: 1, + }); } }); } From 09e372bb48cd86977e305207ea0c236df7e1381a Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:15:16 -0700 Subject: [PATCH 18/21] Update expose.js --- assets/scripts/expose.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/scripts/expose.js b/assets/scripts/expose.js index 80287b3f7..972d8d0dd 100644 --- a/assets/scripts/expose.js +++ b/assets/scripts/expose.js @@ -47,10 +47,14 @@ function init() { jsConfetti.addConfetti({ confettiRadius: 6, confettiNumber: 300, - spread: 120, + spread: 360, startVelocity: 50, gravity: 1, + origin: { + x: 0.5, + y: 0.5 + } }); } }); -} +} \ No newline at end of file From e28563ab8121ca406f19c20e06558f39de645eea Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:16:34 -0700 Subject: [PATCH 19/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 80edce1d7..e0af07a7d 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Members: David De Santiago - A17001592 -- My "expose.js" [here](expose.html) -- My "explore.js" [here](explore.html) +- My "expose.js" [here]([expose.html](https://ddesantiag0.github.io/Lab5_Starter/expose.html)) +- My "explore.js" [here]([explore.html](https://ddesantiag0.github.io/Lab5_Starter/explore.html)) ## Check Your Understanding From 5ccbccee70cb7aad1c09b075cdb1440913080a4d Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:17:37 -0700 Subject: [PATCH 20/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e0af07a7d..b565dbe10 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Members: David De Santiago - A17001592 -- My "expose.js" [here]([expose.html](https://ddesantiag0.github.io/Lab5_Starter/expose.html)) -- My "explore.js" [here]([explore.html](https://ddesantiag0.github.io/Lab5_Starter/explore.html)) +- My "expose.js" [here](https://ddesantiag0.github.io/Lab5_Starter/expose.html) +- My "explore.js" [here](https://ddesantiag0.github.io/Lab5_Starter/explore.html) ## Check Your Understanding From 87a089011eb370a2543c49891a8a116b3e6680c2 Mon Sep 17 00:00:00 2001 From: David De Santiago <107174944+ddesantiag0@users.noreply.github.com> Date: Fri, 31 May 2024 11:31:38 -0700 Subject: [PATCH 21/21] Update explore.js --- assets/scripts/explore.js | 77 +++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/assets/scripts/explore.js b/assets/scripts/explore.js index 1cd5adebc..cea7faec7 100644 --- a/assets/scripts/explore.js +++ b/assets/scripts/explore.js @@ -1,54 +1,53 @@ // explore.js // resources: https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis -window.addEventListener('DOMContentLoaded', init); -const synth = window.speechSynthesis; +window.addEventListener("DOMContentLoaded", init); function init() { - // populate the select options on page load - let availableVoices = []; - const voiceDropdown = document.querySelector('select'); + const synth = window.speechSynthesis; + const textArea = document.getElementById('text-to-speak'); + const voiceSelect = document.getElementById('voice-select'); + const speakButton = document.querySelector('button'); + const faceImage = document.querySelector('img'); + let voices = []; - function populateVoiceOptions() { - availableVoices = synth.getVoices(); - for (let i = 0; i < availableVoices.length; i++) { + function populateVoices() { + voices = synth.getVoices(); + voiceSelect.innerHTML = ''; + voices.forEach((voice) => { const option = document.createElement('option'); - option.textContent = `${availableVoices[i].name} (${availableVoices[i].lang})`; - if (availableVoices[i].default) { - option.textContent += ' — DEFAULT'; - } - option.setAttribute('data-lang', availableVoices[i].lang); - option.setAttribute('data-name', availableVoices[i].name); - voiceDropdown.appendChild(option); - } + option.textContent = `${voice.name} (${voice.lang})${voice.default ? ' — DEFAULT' : ''}`; + option.setAttribute('data-name', voice.name); + option.setAttribute('data-lang', voice.lang); + voiceSelect.appendChild(option); + }); } - populateVoiceOptions(); + populateVoices(); if (synth.onvoiceschanged !== undefined) { - synth.onvoiceschanged = populateVoiceOptions; + synth.onvoiceschanged = populateVoices; } - const textInput = document.getElementById('text-to-speak'); - - const speakButton = document.querySelector('button'); - - speakButton.addEventListener('click', () => { - const utterance = new SpeechSynthesisUtterance(textInput.value); - const selectedVoice = voiceDropdown.selectedOptions[0].getAttribute('data-name'); - for (let i = 0; i < availableVoices.length; i++) { - if (availableVoices[i].name === selectedVoice) { - utterance.voice = availableVoices[i]; - break; - } + function speak() { + if (synth.speaking) { + console.error('speechSynthesis.speaking'); + return; } + if (textArea.value !== '') { + const utterance = new SpeechSynthesisUtterance(textArea.value); + const selectedVoiceName = voiceSelect.selectedOptions[0].getAttribute('data-name'); + utterance.voice = voices.find(voice => voice.name === selectedVoiceName); + + utterance.onstart = () => { + faceImage.src = 'assets/images/smiling-open.png'; + }; + utterance.onend = () => { + faceImage.src = 'assets/images/smiling.png'; + }; + + synth.speak(utterance); + } + } - const faceImage = document.querySelector('img'); - faceImage.src = 'assets/images/smiling-open.png'; - - utterance.onend = () => { - faceImage.src = 'assets/images/smiling.png'; - }; - - synth.speak(utterance); - }); + speakButton.addEventListener('click', speak); }