');
iframe.contentDocument.write(quill.root.innerHTML);
iframe.contentDocument.write('');
iframe.contentDocument.close();
var content = iframe.contentDocument.documentElement.outerHTML;
var asBlob = true;
var converted = htmlDocx.asBlob(content, {orientation: 'portrait'});
var link = document.createElement('a');
link.href = URL.createObjectURL(converted);
link.download = 'document.docx';
link.click();
document.body.removeChild(iframe);
});
// functions toolbar//
//miror text//
document.getElementById("mirrorButton").addEventListener("click", function() {
document.getElementById("teleprompter").classList.toggle("mirrored");
});
//cue position//
document.getElementById('toggleCuePosition').addEventListener('click', function() {
var cueMarker = document.getElementById('cueMarker');
if (cueMarker.style.left !== '0px') {
cueMarker.style.left = '0px';
cueMarker.style.right = 'auto';
} else {
cueMarker.style.left = 'auto';
cueMarker.style.right = '0px';
cueMarker.style.transform = 'rotate(180deg)';
}
});
//edit text//
document.getElementById('edit-toggle').addEventListener('click', function() {
let contentEditable = document.getElementById('text').getAttribute('contentEditable');
if(contentEditable == 'true') {
document.getElementById('text').setAttribute('contentEditable', 'false');
document.getElementById('edit-toggle').innerText = 'Edit Text';
document.getElementById('text').style.backgroundColor = "transparent"; // reset background color after editing
} else {
document.getElementById('text').setAttribute('contentEditable', 'true');
document.getElementById('edit-toggle').innerText = 'Save Text';
}
});
//full screen//
document.getElementById('toggleFullscreen').addEventListener('click', function() {
if (!document.fullscreenElement) { // if not in fullscreen mode
// Enter fullscreen mode
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) { // Mozilla
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) { // Webkit
document.documentElement.webkitRequestFullscreen();
} else if (document.documentElement.msRequestFullscreen) { // MS
document.documentElement.msRequestFullscreen();
}
} else { // if in fullscreen mode
// Exit fullscreen mode
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) { // Mozilla
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) { // Webkit
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { // MS
document.msExitFullscreen();
}
}
});
// hide controls//
document.getElementById('toggle-controls').addEventListener('click', function() {
var controls = document.getElementById('controls');
if (controls.style.display === "none") {
controls.style.display = "block";
this.innerText = "Hide Controls";
} else {
controls.style.display = "none";
this.innerText = "Unhide Controls";
}
});
var teleprompter = document.getElementById('teleprompter');
var text = document.getElementById('text');
var updateText = document.getElementById('update-text');
var scrollSpeedControl = document.getElementById('scroll-speed');
var fontSizeControl = document.getElementById('font-size');
var fontFamilyControl = document.getElementById('font-family');
var textDirectionControl = document.getElementById('text-direction');
var scrolling;
var scrollSpeed = 100 - scrollSpeedControl.value; // Inverse the value so that higher means faster
fontSizeControl.addEventListener('change', function() {
text.style.fontSize = this.value + 'px';
});
fontFamilyControl.addEventListener('change', function() {
text.style.fontFamily = this.value;
});
scrollSpeedControl.addEventListener('input', function() {
scrollSpeed = 100 - this.value;
if (scrolling) {
// if scrolling, restart it with new speed
stopAutoScroll();
startAutoScroll();
}
});
function startAutoScroll() {
stopAutoScroll();
scrolling = setInterval(function() {
teleprompter.scrollTop += 1;
}, scrollSpeed);
}
function stopAutoScroll() {
clearInterval(scrolling);
}
textDirectionControl.addEventListener('change', function() {
text.style.direction = this.value;
});
updateText.addEventListener('click', function() {
var html = quill.root.innerHTML;
text.innerHTML = html;
});
document.getElementById('returnToStart').addEventListener('click', function() {
document.getElementById('teleprompter').scrollTop = 0;
});
teleprompter.addEventListener('scroll', function() {
localStorage.setItem('teleprompterScrollTop', teleprompter.scrollTop.toString());
});
window.addEventListener('storage', function(e) {
if (e.key === 'teleprompterScrollTop') {
var newScrollTop = parseInt(e.newValue, 10);
// Mirror the scrolling
teleprompter.scrollTop = newScrollTop;
}
});
const toggleScrollBtn = document.getElementById('toggleScroll');
let isScrolling = false;
toggleScrollBtn.addEventListener('click', toggleScrollingState);
document.addEventListener('keydown', function(event) {
if (event.key === " ") {
event.preventDefault();
toggleScrollingState();
}
});
function toggleScrollingState() {
if (isScrolling) {
stopAutoScroll();
toggleScrollBtn.textContent = "Start";
exitFullscreen();
toggleControlsVisibility(true);
} else {
startAutoScroll();
toggleScrollBtn.textContent = "Stop";
enterFullscreen();
toggleControlsVisibility(false);
}
toggleScrollBtn.blur();
isScrolling = !isScrolling;
}
function enterFullscreen() {
if (!document.fullscreenElement) {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen();
} else if (document.documentElement.msRequestFullscreen) {
document.documentElement.msRequestFullscreen();
}
}
}
function exitFullscreen() {
if (document.fullscreenElement) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
}
function toggleControlsVisibility(shouldShow) {
const controls = document.getElementById('controls');
if (shouldShow) {
controls.style.display = "block";
} else {
controls.style.display = "none";
}
}
//keyboard shortcuts//
document.addEventListener('keydown', function(event) {
if (event.key === "ArrowUp") {
// Speed up by decreasing the scrollSpeed
if (scrollSpeed > 10) { // This is a minimum threshold, adjust as needed
scrollSpeed -= 5; // Decrease by 5, adjust as desired for sensitivity
}
} else if (event.key === "ArrowDown") {
// Slow down by increasing the scrollSpeed
if (scrollSpeed < 200) { // This is a maximum threshold, adjust as needed
scrollSpeed += 5; // Increase by 5, adjust as desired for sensitivity
}
} else if (event.key === "") {
// Stop the auto-scrolling
stopAutoScroll();
// Update the button's text to "Start" if you have a button for that
if (toggleScrollBtn) {
toggleScrollBtn.textContent = "Start";
isScrolling = false; // Reset the scrolling state
}
}
if (scrolling && (event.key === "ArrowUp" || event.key === "ArrowDown")) {
// If scrolling, restart with the new speed
stopAutoScroll();
startAutoScroll();
}
});
// Add handler for paste event
quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) {
delta.ops = delta.ops.map(op => {
if (op.insert && typeof op.insert === 'string') {
let attributes = op.attributes || {};
// If color is not defined, set it to white
if (!attributes.color) attributes.color = 'white';
return {
insert: op.insert,
attributes: attributes
};
} else {
return op;
}
});
return delta;
});
//story box highlightsBox//
document.getElementById('copyHighlights').addEventListener('click', function() {
var range = quill.getSelection();
var teleprompter = document.getElementById('teleprompter'); // Adjust this line to match the id of your teleprompter
if (range) {
if (range.length != 0) {
var text = quill.getText(range.index, range.length).substring(0, 10); // Limit to first 10 characters
var row = document.createElement('tr');
row.dataset.startIndex = range.index;
var noCell = document.createElement('td');
var textCell = document.createElement('td');
var actionsCell = document.createElement('td');
noCell.textContent = document.getElementById('highlightsBox').getElementsByTagName('tr').length; // Set the number
var textLink = document.createElement('a'); // create an anchor tag
textLink.href = "#";
textLink.textContent = text;
textCell.appendChild(textLink); // append the anchor tag to the cell
var deleteIcon = document.createElement('i');
deleteIcon.className = 'fas fa-trash delete-icon';
var moveUpButton = document.createElement('button');
moveUpButton.textContent = '+';
moveUpButton.className = 'move-up';
var moveDownButton = document.createElement('button');
moveDownButton.textContent = '-';
moveDownButton.className = 'move-down';
actionsCell.appendChild(deleteIcon);
actionsCell.appendChild(moveUpButton);
actionsCell.appendChild(moveDownButton);
row.appendChild(noCell);
row.appendChild(textCell);
row.appendChild(actionsCell);
document.getElementById('highlightsBox').getElementsByTagName('tbody')[0].appendChild(row);
deleteIcon.addEventListener('click', function(e) {
e.preventDefault();
var tbody = document.getElementById('highlightsBox').getElementsByTagName('tbody')[0];
tbody.removeChild(row);
});
// Event listener for moving a row up
moveUpButton.addEventListener('click', function(e) {
e.preventDefault();
var prevSibling = row.previousElementSibling;
if (prevSibling) {
row.parentNode.insertBefore(row, prevSibling);
}
});
// Event listener for moving a row down
moveDownButton.addEventListener('click', function(e) {
e.preventDefault();
var nextSibling = row.nextElementSibling;
if (nextSibling) {
row.parentNode.insertBefore(nextSibling, row);
}
});
document.getElementById('highlightsBox').addEventListener('click', function(event) {
var clickedElement = event.target;
if (clickedElement.tagName.toLowerCase() === 'a') {
var searchText = clickedElement.textContent;
var range = document.createRange();
var teleprompterNode = document.getElementById("text");
if (!teleprompterNode) {
console.warn('Teleprompter paragraph not found!');
return;
}
// Utility function to retrieve all text nodes from a parent node
function getTextNodes(node) {
var textNodes = [];
function retrieveTextNodes(subNode) {
if (subNode.nodeType === Node.TEXT_NODE) {
textNodes.push(subNode);
} else {
for (var i = 0; i < subNode.childNodes.length; i++) {
retrieveTextNodes(subNode.childNodes[i]);
}
}
}
retrieveTextNodes(node);
return textNodes;
}
var textNodes = getTextNodes(teleprompterNode);
for (var i = 0; i < textNodes.length; i++) {
var pos = textNodes[i].nodeValue.indexOf(searchText);
if (pos > -1) {
range.setStart(textNodes[i], pos);
range.setEnd(textNodes[i], pos + searchText.length);
var rect = range.getBoundingClientRect();
var teleprompter = document.getElementById('teleprompter');
var scrollOffset = rect.top + teleprompter.scrollTop - teleprompter.getBoundingClientRect().top;
teleprompter.scrollTop = scrollOffset;
return;
}
}
console.warn('Search text not found within teleprompter!');
}
});
}
}
});
//sidebar code:
document.getElementById('toggleSidebar').addEventListener('click', function() {
const sidebar = document.getElementById('sidebar');
const arrowButton = document.getElementById('toggleSidebar');
if (sidebar.style.right === '0px') {
sidebar.style.right = '-400px';
arrowButton.innerHTML = "→"; // Change arrow to pointing right
} else {
sidebar.style.right = '0px';
arrowButton.innerHTML = "←"; // Change arrow to pointing left
}
});
// story box end highlights//
//video
let video = document.querySelector("#videoElement");
let cameraSelect = document.querySelector("#cameraSelect");
let micSelect = document.querySelector("#micSelect");
let toggleRecord = document.querySelector("#toggleRecord");
let recordingTime = document.querySelector("#recordingTime");
let downloadLink = document.querySelector("#downloadLink");
let audioPlayer = document.querySelector("#audioPlayer");
let recordedBlobs;
let sourceBuffer;
let recordingInterval;
let audioContext;
let analyser;
let dataArray;
video.muted = true; // Mute the video element
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
devices.forEach(function (device) {
var option = document.createElement("option");
option.value = device.deviceId;
if (device.kind === "videoinput") {
option.text = device.label || "Camera " + (cameraSelect.length + 1);
cameraSelect.appendChild(option);
}
else if (device.kind === "audioinput") {
option.text = device.label || "Microphone " + (micSelect.length + 1);
micSelect.appendChild(option);
}
});
// Select the first camera and microphone by default
cameraSelect.value = devices.find(device => device.kind === "videoinput").deviceId;
micSelect.value = devices.find(device => device.kind === "audioinput").deviceId;
// Start streaming with the selected camera
startCameraStream();
})
.catch(function (error) {
console.log("Error retrieving media devices: ", error);
});
}
cameraSelect.addEventListener("change", startCameraStream);
micSelect.addEventListener("change", startCameraStream);
toggleRecord.addEventListener("click", toggleRecording);
function startCameraStream() {
var selectedCameraId = cameraSelect.value;
var selectedMicId = micSelect.value;
var constraints = {
video: {
deviceId: selectedCameraId
},
audio: {
deviceId: selectedMicId
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
video.srcObject = stream;
initRecorder(stream);
})
.catch(function (error) {
console.log("Error accessing camera stream: ", error);
});
}
function initRecorder(stream) {
audioContext = new AudioContext();
var input = audioContext.createMediaStreamSource(stream);
recorder = new Recorder(input);
// Create an analyser node
analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
var bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
// Connect the analyser node to our input
input.connect(analyser);
}
// Initialize wavesurfer.js
var wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
progressColor: 'purple'
});
function toggleRecording() {
if (!recorder || recorder.recording) {
recorder && recorder.stop();
clearInterval(recordingInterval);
toggleRecord.textContent = 'Start Recording';
recorder && recorder.exportWAV(function(blob) {
let url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = 'test.wav';
downloadLink.innerHTML = 'Download sound file';
// Load the recorded blob into wavesurfer
wavesurfer.loadBlob(blob);
});
} else {
recorder.record();
recordingTime.innerText = "Recording Time: 0s"; // Reset counter
toggleRecord.textContent = 'Stop Recording';
recordingInterval = setInterval(updateRecordingTime, 1000);
}
}
// Add this to your script to handle the play/pause button functionality
document.getElementById('playButton').onclick = function() {
wavesurfer.playPause();
};
// This will enable the play button once wavesurfer is ready to play the file
wavesurfer.on('ready', function() {
document.getElementById('playButton').disabled = false;
});
function updateRecordingTime() {
let time = parseInt(recordingTime.innerText.split(" ")[2]);
recordingTime.innerText = `Recording Time: ${++time}s`;
}
function updateRecordingTime() {
let time = parseInt(recordingTime.innerText.split(" ")[2]);
recordingTime.innerText = `Recording Time: ${++time}s`;
}
// file load
document.getElementById('file-input').addEventListener('change', function(e) {
var file = e.target.files[0];
if (!file) {
return;
}
if (file.name.endsWith(".txt")) {
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
quill.setContents([]);
quill.clipboard.dangerouslyPasteHTML(0, contents);
};
reader.readAsText(file);
}
else if (file.name.endsWith(".docx") || file.name.endsWith(".doc")) {
convertToHtml(file).then(function(html){
quill.setContents([]);
quill.clipboard.dangerouslyPasteHTML(0, html);
});
}
});
function convertToHtml(file) {
return new Promise(function(resolve, reject){
var reader = new FileReader();
reader.onload = function(e) {
var arrayBuffer = e.target.result;
mammoth.convertToHtml({arrayBuffer: arrayBuffer})
.then(function(resultHtml) {
resolve(resultHtml.value);
}).done();
};
reader.readAsArrayBuffer(file);
});
}
//dual screen
fontSizeControl.addEventListener('change', function() {
text.style.fontSize = this.value + 'px';
mirroredTeleprompterElement.style.fontSize = this.value + 'px'; // Update dual screen
});
fontFamilyControl.addEventListener('change', function() {
text.style.fontFamily = this.value;
mirroredTeleprompterElement.style.fontFamily = this.value; // Update dual screen
});
document.getElementById('dualScreenBtn').addEventListener('click', function() {
var teleprompterContent = document.getElementById('teleprompter').innerHTML;
var newWindow = window.open('', '_blank');
newWindow.document.write(`
Mirrored Teleprompter‣
${teleprompterContent}
`);
newWindow.document.close();
var teleprompterElement = document.getElementById('teleprompter');
var mirroredTeleprompterElement = newWindow.document.getElementById('teleprompterContent');
// Synchronize the initial styles
mirroredTeleprompterElement.style.fontSize = fontSizeControl.value + 'px';
mirroredTeleprompterElement.style.fontFamily = fontFamilyControl.value;
teleprompterElement.addEventListener('scroll', function() {
mirroredTeleprompterElement.scrollTop = this.scrollTop;
});
mirroredTeleprompterElement.addEventListener('scroll', function() {
teleprompterElement.scrollTop = this.scrollTop;
});
// Update the dual screen when the text is updated
updateText.addEventListener('click', function() {
var html = quill.root.innerHTML;
text.innerHTML = html;
mirroredTeleprompterElement.innerHTML = html; // Update the dual screen
});
});
/* save to PDF
document.querySelector("#saveAsPDF").addEventListener("click", function() {
var element = quill.container.firstChild;
var opt = {
margin: 1,
filename: 'teleprompter.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
// New Promise-based usage:
html2pdf().set(opt).from(element).save();
});
*/
// save to text
document.getElementById('save-text-file').addEventListener('click', function() {
// Get Quill editor content
let quillContent = quill.container.firstChild.innerHTML;
// Remove HTML tags using a regular expression
let cleanedContent = quillContent.replace(/<[^>]*>?/gm, '');
// Remove HTML entities
cleanedContent = cleanedContent.replace(/ /g, ' ');
// Create a blob from the cleaned content
let blob = new Blob([cleanedContent], {type: "text/plain;charset=utf-8"});
// Create a link element
let downloadLink = document.createElement("a");
// Create a data URL for the blob
let url = window.URL.createObjectURL(blob);
downloadLink.href = url;
// Set the download attribute of the link to the text file name
downloadLink.download = "teleprompter_content.txt";
// Append the link to the document body
document.body.appendChild(downloadLink);
// Simulate a click of the download link
downloadLink.click();
// Remove the link from the document body
document.body.removeChild(downloadLink);
});