From 82cfc831370b984c2936d632965d63f91093346f Mon Sep 17 00:00:00 2001 From: CreativeRiya <89841557+CreativeRiya@users.noreply.github.com> Date: Tue, 31 Aug 2021 15:51:02 +0530 Subject: [PATCH] JavaScript for NoteTaking for Cats --- javascripts/index.html | 51 +++++++++++ javascripts/script.js | 202 +++++++++++++++++++++++++++++++++++++++++ javascripts/styles.css | 92 +++++++++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 javascripts/index.html create mode 100644 javascripts/script.js create mode 100644 javascripts/styles.css diff --git a/javascripts/index.html b/javascripts/index.html new file mode 100644 index 0000000..be9988a --- /dev/null +++ b/javascripts/index.html @@ -0,0 +1,51 @@ + + + + + JAVA VOICE APP + + + + + + + + +
+ +

Voice Controlled Notes App

+

A tiny app that allows you to take notes by recording your voice

+

Click Start Recognising your Voice Notes ยป

+ +

Sorry, Your Browser Doesn't Support the Web Speech API. Try Opening This Demo In Google Chrome.

+ +
+

Add New Note

+
+ +
+ + + +

Press the Start Recognition button and allow access.

+ +

Check your Notes Here!

+ + +
+ +
+ + + + + + + + + + diff --git a/javascripts/script.js b/javascripts/script.js new file mode 100644 index 0000000..017f4db --- /dev/null +++ b/javascripts/script.js @@ -0,0 +1,202 @@ +try { + var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + var recognition = new SpeechRecognition(); +} +catch(e) { + console.error(e); + $('.no-browser-support').show(); + $('.app').hide(); +} + + +var noteTextarea = $('#note-textarea'); +var instructions = $('#recording-instructions'); +var notesList = $('ul#notes'); + +var noteContent = ''; + +// Get all notes from previous sessions and display them. +var notes = getAllNotes(); +renderNotes(notes); + + + +/*----------------------------- + Voice Recognition +------------------------------*/ + +// If false, the recording will stop after a few seconds of silence. +// When true, the silence period is longer (about 15 seconds), +// allowing us to keep recording even when the user pauses. +recognition.continuous = true; + +// This block is called every time the Speech APi captures a line. +recognition.onresult = function(event) { + + // event is a SpeechRecognitionEvent object. + // It holds all the lines we have captured so far. + // We only need the current one. + var current = event.resultIndex; + + // Get a transcript of what was said. + var transcript = event.results[current][0].transcript; + + // Add the current transcript to the contents of our Note. + // There is a weird bug on mobile, where everything is repeated twice. + // There is no official solution so far so we have to handle an edge case. + var mobileRepeatBug = (current == 1 && transcript == event.results[0][0].transcript); + + if(!mobileRepeatBug) { + noteContent += transcript; + noteTextarea.val(noteContent); + } +}; + +recognition.onstart = function() { + instructions.text('Voice recognition activated. Try speaking into the microphone.'); +} + +recognition.onspeechend = function() { + instructions.text('You were quiet for a while so voice recognition turned itself off.'); +} + +recognition.onerror = function(event) { + if(event.error == 'no-speech') { + instructions.text('No speech was detected. Try again.'); + }; +} + + + +/*----------------------------- + App buttons and input +------------------------------*/ + +$('#start-record-btn').on('click', function(e) { + if (noteContent.length) { + noteContent += ' '; + } + recognition.start(); +}); + + +$('#pause-record-btn').on('click', function(e) { + recognition.stop(); + instructions.text('Voice recognition paused.'); +}); + +// Sync the text inside the text area with the noteContent variable. +noteTextarea.on('input', function() { + noteContent = $(this).val(); +}) + +$('#save-note-btn').on('click', function(e) { + recognition.stop(); + + if(!noteContent.length) { + instructions.text('Could not save empty note. Please add a message to your note.'); + } + else { + // Save note to localStorage. + // The key is the dateTime with seconds, the value is the content of the note. + saveNote(new Date().toLocaleString(), noteContent); + + // Reset variables and update UI. + noteContent = ''; + renderNotes(getAllNotes()); + noteTextarea.val(''); + instructions.text('Note saved successfully.'); + } + +}) + + +notesList.on('click', function(e) { + e.preventDefault(); + var target = $(e.target); + + // Listen to the selected note. + if(target.hasClass('listen-note')) { + var content = target.closest('.note').find('.content').text(); + readOutLoud(content); + } + + // Delete note. + if(target.hasClass('delete-note')) { + var dateTime = target.siblings('.date').text(); + deleteNote(dateTime); + target.closest('.note').remove(); + } +}); + + + +/*----------------------------- + Speech Synthesis +------------------------------*/ + +function readOutLoud(message) { + var speech = new SpeechSynthesisUtterance(); + + // Set the text and voice attributes. + speech.text = message; + speech.volume = 1; + speech.rate = 1; + speech.pitch = 1; + + window.speechSynthesis.speak(speech); +} + + + +/*----------------------------- + Helper Functions +------------------------------*/ + +function renderNotes(notes) { + var html = ''; + if(notes.length) { + notes.forEach(function(note) { + html+= `
  • +

    + ${note.date} + Listen to Note + Delete +

    +

    ${note.content}

    +
  • `; + }); + } + else { + html = '
  • You don\'t have any notes yet.

  • '; + } + notesList.html(html); +} + + +function saveNote(dateTime, content) { + localStorage.setItem('note-' + dateTime, content); +} + + +function getAllNotes() { + var notes = []; + var key; + for (var i = 0; i < localStorage.length; i++) { + key = localStorage.key(i); + + if(key.substring(0,5) == 'note-') { + notes.push({ + date: key.replace('note-',''), + content: localStorage.getItem(localStorage.key(i)) + }); + } + } + return notes; +} + + +function deleteNote(dateTime) { + localStorage.removeItem('note-' + dateTime); +} + diff --git a/javascripts/styles.css b/javascripts/styles.css new file mode 100644 index 0000000..7a9e438 --- /dev/null +++ b/javascripts/styles.css @@ -0,0 +1,92 @@ +ul { + list-style: none; + padding: 0; +} + +p { + color: #444; +} + +button:focus { + outline: 0; +} + +.container { + max-width: 700px; + margin: 0 auto; + padding: 100px 50px; + text-align: center; +} + +.container h1 { + margin-bottom: 20px; +} + +.page-description { + font-size: 1.1rem; + margin: 0 auto; +} + +.tz-link { + font-size: 1em; + color: #1da7da; + text-decoration: none; +} + +.no-browser-support { + display: none; + font-size: 1.2rem; + color: #e64427; + margin-top: 35px; +} + +.app { + margin: 40px auto; +} + +#note-textarea { + margin: 20px 0; +} + +#recording-instructions { + margin: 15px auto 60px; +} + +#notes { + padding-top: 20px; +} + +.note .header { + font-size: 0.9em; + color: #888; + margin-bottom: 10px; +} + +.note .delete-note, +.note .listen-note { + text-decoration: none; + margin-left: 15px; +} + +.note .content { + margin-bottom: 40px; +} + +@media (max-width: 768px) { + .container { + padding: 50px 25px; + } + + button { + margin-bottom: 10px; + } + +} + + + +/* -- Demo ads -- */ + +@media (max-width: 1200px) { + #bsaHolder{ display:none;} +} \ No newline at end of file