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:
Russell Ballestrini 2025-06-29 19:22:06 -04:00
parent 888910c8b4
commit 459291addf
3 changed files with 117 additions and 160 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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