Add optional styling system and disable custom styling for this repo
- Added USE_CUSTOM_STYLING configuration flag to uncloseai.js - TTS modal now uses clean HTML elements when custom styling disabled - Updated index.html and demo.html to disable custom styling - This repo will now use clean PicoCSS styling instead of custom gradients - Other sites can still enable custom styling by setting window.UNCLOSEAI_CUSTOM_STYLING = true
This commit is contained in:
parent
888910c8b4
commit
459291addf
3 changed files with 117 additions and 160 deletions
|
|
@ -33,6 +33,9 @@
|
|||
document.documentElement.setAttribute('data-theme', theme);
|
||||
}
|
||||
}
|
||||
|
||||
// Disable custom styling for uncloseai.js - use PicoCSS instead
|
||||
window.UNCLOSEAI_CUSTOM_STYLING = false;
|
||||
</script>
|
||||
|
||||
<script src="https://uncloseai.com/uncloseai.js" type="module"></script>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
document.documentElement.setAttribute('data-theme', theme);
|
||||
}
|
||||
}
|
||||
|
||||
// Disable custom styling for uncloseai.js - use PicoCSS instead
|
||||
window.UNCLOSEAI_CUSTOM_STYLING = false;
|
||||
</script>
|
||||
|
||||
<script src="https://uncloseai.com/uncloseai.js" type="module"></script>
|
||||
|
|
|
|||
271
uncloseai.js
271
uncloseai.js
|
|
@ -1359,127 +1359,104 @@ function openHermesModal() {
|
|||
messageInput.focus();
|
||||
}
|
||||
|
||||
// Configuration for styling - set to false to disable custom styling
|
||||
const USE_CUSTOM_STYLING = window.UNCLOSEAI_CUSTOM_STYLING !== false;
|
||||
|
||||
// Function to open TTS modal
|
||||
function openTTSModal() {
|
||||
// Check if Hermes modal is open to set appropriate z-index
|
||||
const hermesModal = document.getElementById('hermes-modal-backdrop');
|
||||
const zIndex = hermesModal ? '2001' : '1001';
|
||||
|
||||
// Create modal backdrop (similar to Hermes modal)
|
||||
const modalBackdrop = document.createElement('div');
|
||||
modalBackdrop.id = 'tts-modal-backdrop';
|
||||
modalBackdrop.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: ${zIndex};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
const modal = document.createElement('dialog');
|
||||
modal.open = true;
|
||||
modal.style.zIndex = zIndex;
|
||||
modal.style.position = 'fixed';
|
||||
|
||||
const modal = document.createElement('div');
|
||||
modal.id = 'tts-modal';
|
||||
modal.style.cssText = `
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
width: 90%;
|
||||
max-width: 720px;
|
||||
max-height: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
|
||||
overflow: hidden;
|
||||
`;
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
modal.style.cssText += `
|
||||
max-width: 720px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
||||
background: white;
|
||||
`;
|
||||
}
|
||||
|
||||
// Create modal header (matching Hermes modal style)
|
||||
const header = document.createElement('div');
|
||||
header.style.cssText = `
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
const article = document.createElement('article');
|
||||
modal.appendChild(article);
|
||||
|
||||
const title = document.createElement('h2');
|
||||
title.textContent = 'TTS Anything!';
|
||||
title.style.cssText = `
|
||||
margin: 0;
|
||||
font-family: 'ChunkFiveRegular', monospace;
|
||||
font-size: 20px;
|
||||
`;
|
||||
const header = document.createElement('header');
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
header.style.cssText = `
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 16px 20px;
|
||||
margin: -1em -1em 1em -1em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
}
|
||||
article.appendChild(header);
|
||||
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.textContent = '×';
|
||||
closeButton.style.cssText = `
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
closeButton.onclick = () => document.body.removeChild(modalBackdrop);
|
||||
|
||||
header.appendChild(title);
|
||||
closeButton.textContent = 'X';
|
||||
closeButton.onclick = () => document.body.removeChild(modal);
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
closeButton.style.cssText = `
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
`;
|
||||
} else {
|
||||
closeButton.style.float = 'right';
|
||||
}
|
||||
header.appendChild(closeButton);
|
||||
|
||||
// Create content area
|
||||
const content = document.createElement('div');
|
||||
content.style.cssText = `
|
||||
padding: 20px;
|
||||
flex: 1;
|
||||
`;
|
||||
const h1 = document.createElement('h1');
|
||||
h1.textContent = 'TTS Anything!';
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
h1.style.cssText = `
|
||||
margin: 0;
|
||||
font-family: 'ChunkFiveRegular', monospace;
|
||||
font-size: 20px;
|
||||
`;
|
||||
}
|
||||
header.appendChild(h1);
|
||||
|
||||
const textArea = document.createElement('textarea');
|
||||
textArea.style.cssText = `
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
`;
|
||||
textArea.style.width = '100%';
|
||||
textArea.style.height = '240px';
|
||||
textArea.placeholder = 'text-to-speech: write any message & have the artificial intelligence speak it!';
|
||||
content.appendChild(textArea);
|
||||
article.appendChild(textArea);
|
||||
|
||||
// Voice selection
|
||||
const voiceLabel = document.createElement('div');
|
||||
voiceLabel.textContent = 'Voice:';
|
||||
voiceLabel.style.cssText = `
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
content.appendChild(voiceLabel);
|
||||
|
||||
const voices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'];
|
||||
const voiceSelection = document.createElement('div');
|
||||
voiceSelection.style.cssText = `
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 16px;
|
||||
`;
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
voiceSelection.style.cssText = `
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin: 16px 0;
|
||||
`;
|
||||
}
|
||||
voices.forEach((voice) => {
|
||||
const label = document.createElement('label');
|
||||
label.style.cssText = `
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
label.style.cssText = `
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
} else {
|
||||
label.style.display = 'inline-block';
|
||||
label.style.marginRight = '10px';
|
||||
}
|
||||
const radio = document.createElement('input');
|
||||
radio.type = 'radio';
|
||||
radio.name = 'tts-voice';
|
||||
|
|
@ -1489,58 +1466,43 @@ function openTTSModal() {
|
|||
label.appendChild(document.createTextNode(voice));
|
||||
voiceSelection.appendChild(label);
|
||||
});
|
||||
content.appendChild(voiceSelection);
|
||||
article.appendChild(voiceSelection);
|
||||
|
||||
// Speed selection
|
||||
const speedContainer = document.createElement('div');
|
||||
speedContainer.style.marginBottom = '16px';
|
||||
|
||||
const speedLabel = document.createElement('label');
|
||||
speedLabel.style.cssText = `
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
speedLabel.textContent = 'Speed: 0.9';
|
||||
const speedValue = document.createElement('span');
|
||||
speedValue.textContent = '0.9';
|
||||
|
||||
speedLabel.textContent = `Speed: ${speedValue.textContent}`;
|
||||
const speedSlider = document.createElement('input');
|
||||
speedSlider.type = 'range';
|
||||
speedSlider.min = '0.25';
|
||||
speedSlider.max = '4.0';
|
||||
speedSlider.step = '0.05';
|
||||
speedSlider.value = '0.9';
|
||||
speedSlider.style.cssText = `
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
|
||||
speedSlider.oninput = () => {
|
||||
speedValue.textContent = speedSlider.value;
|
||||
speedLabel.textContent = `Speed: ${speedSlider.value}`;
|
||||
};
|
||||
|
||||
speedContainer.appendChild(speedLabel);
|
||||
speedContainer.appendChild(speedSlider);
|
||||
content.appendChild(speedContainer);
|
||||
|
||||
// Button container
|
||||
const buttonContainer = document.createElement('div');
|
||||
buttonContainer.style.cssText = `
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
`;
|
||||
article.appendChild(speedLabel);
|
||||
article.appendChild(speedSlider);
|
||||
|
||||
const playButton = document.createElement('button');
|
||||
playButton.textContent = 'Play Text';
|
||||
playButton.style.cssText = `
|
||||
padding: 12px 24px;
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
`;
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
playButton.style.cssText = `
|
||||
padding: 12px 24px;
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
margin: 16px 10px 0 0;
|
||||
`;
|
||||
}
|
||||
|
||||
let ttsAudio = null;
|
||||
let ttsBlob = null;
|
||||
|
|
@ -1564,26 +1526,29 @@ function openTTSModal() {
|
|||
playButton.disabled = false;
|
||||
|
||||
// Add download button if not exists
|
||||
let downloadButton = buttonContainer.querySelector('.download-btn');
|
||||
let downloadButton = article.querySelector('.download-btn');
|
||||
if (!downloadButton) {
|
||||
downloadButton = document.createElement('button');
|
||||
downloadButton.className = 'download-btn';
|
||||
downloadButton.textContent = '💾 Download MP3';
|
||||
downloadButton.style.cssText = `
|
||||
padding: 12px 24px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
`;
|
||||
downloadButton.textContent = 'Download MP3';
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
downloadButton.style.cssText = `
|
||||
padding: 12px 24px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
margin: 16px 0 0 10px;
|
||||
`;
|
||||
}
|
||||
downloadButton.onclick = () => {
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(ttsBlob);
|
||||
a.download = `tts-${Date.now()}.mp3`;
|
||||
a.click();
|
||||
};
|
||||
buttonContainer.appendChild(downloadButton);
|
||||
article.appendChild(downloadButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1600,22 +1565,8 @@ function openTTSModal() {
|
|||
};
|
||||
};
|
||||
|
||||
buttonContainer.appendChild(playButton);
|
||||
content.appendChild(buttonContainer);
|
||||
|
||||
// Assemble modal
|
||||
modal.appendChild(header);
|
||||
modal.appendChild(content);
|
||||
modalBackdrop.appendChild(modal);
|
||||
|
||||
// Close on backdrop click
|
||||
modalBackdrop.onclick = (e) => {
|
||||
if (e.target === modalBackdrop) {
|
||||
document.body.removeChild(modalBackdrop);
|
||||
}
|
||||
};
|
||||
|
||||
document.body.appendChild(modalBackdrop);
|
||||
article.appendChild(playButton);
|
||||
document.body.appendChild(modal);
|
||||
}
|
||||
|
||||
// Helper function to integrate file upload response to modal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue