Skip to content

Commit

Permalink
Refactor file paths for CSS and JavaScript resources
Browse files Browse the repository at this point in the history
  • Loading branch information
TMHSDigital committed Dec 26, 2024
1 parent 3e80eea commit 17bec48
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 15 deletions.
10 changes: 6 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Digital Services Hub - Web Tools for Digital Tasks</title>
<meta name="description" content="A collection of free web-based tools for everyday digital tasks including text-to-speech, image resizing, color palettes, ASCII art, QR codes, and secure password generation.">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="css/components/about.css">
<link rel="stylesheet" href="/css/styles.css">
<link rel="stylesheet" href="/css/components/about.css">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
<header class="hero">
<nav id="main-nav" class="nav-container">
<div class="logo">
<h1>Digital Services Hub</h1>
<a href="/">
<h1>Digital Services Hub</h1>
</a>
</div>
<div class="theme-toggle">
<button id="theme-button" aria-label="Toggle theme">
Expand Down Expand Up @@ -183,6 +185,6 @@ <h4>Legal</h4>
</div>
</footer>

<script src="js/features/about.js" type="module"></script>
<script src="/js/features/about.js" type="module"></script>
</body>
</html>
190 changes: 190 additions & 0 deletions js/api/text-to-speech-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/**
* Text-to-Speech API wrapper for the Digital Services Hub
* Provides a clean interface for using text-to-speech functionality in other applications
*/
export default class TextToSpeechAPI {
constructor() {
this.synth = window.speechSynthesis;
this.voices = [];
this.currentVoice = null;
this.loadVoices();
}

/**
* Load available voices and set up voice change listener
* @private
*/
loadVoices() {
// Load initial voices
this.voices = this.synth.getVoices();

// Chrome loads voices asynchronously
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = () => {
this.voices = this.synth.getVoices();
};
}
}

/**
* Get all available voices
* @returns {Array} Array of SpeechSynthesisVoice objects
*/
getVoices() {
return this.voices;
}

/**
* Get voices for a specific language
* @param {string} langCode - Language code (e.g., 'en-US', 'es-ES')
* @returns {Array} Array of voices matching the language code
*/
getVoicesForLanguage(langCode) {
return this.voices.filter(voice => voice.lang.startsWith(langCode));
}

/**
* Set the voice to use for speech
* @param {string|SpeechSynthesisVoice} voice - Voice name or SpeechSynthesisVoice object
* @returns {boolean} True if voice was set successfully
*/
setVoice(voice) {
if (typeof voice === 'string') {
const foundVoice = this.voices.find(v => v.name === voice);
if (foundVoice) {
this.currentVoice = foundVoice;
return true;
}
return false;
}

if (voice instanceof SpeechSynthesisVoice) {
this.currentVoice = voice;
return true;
}

return false;
}

/**
* Speak the provided text
* @param {string} text - Text to speak
* @param {Object} options - Speech options
* @param {number} options.rate - Speech rate (0.1 to 10)
* @param {number} options.pitch - Speech pitch (0 to 2)
* @param {number} options.volume - Speech volume (0 to 1)
* @returns {Promise} Resolves when speech is complete, rejects on error
*/
speak(text, options = {}) {
return new Promise((resolve, reject) => {
if (!text) {
reject(new Error('No text provided'));
return;
}

// Stop any current speech
this.stop();

const utterance = new SpeechSynthesisUtterance(text);

// Set voice if one is selected
if (this.currentVoice) {
utterance.voice = this.currentVoice;
}

// Set options with defaults
utterance.rate = options.rate || 1;
utterance.pitch = options.pitch || 1;
utterance.volume = options.volume || 1;

// Handle events
utterance.onend = () => resolve();
utterance.onerror = (event) => reject(new Error(event.error));

// Start speaking
this.synth.speak(utterance);
});
}

/**
* Stop any current speech
*/
stop() {
this.synth.cancel();
}

/**
* Check if currently speaking
* @returns {boolean} True if speaking
*/
isSpeaking() {
return this.synth.speaking;
}

/**
* Pause speech
*/
pause() {
this.synth.pause();
}

/**
* Resume speech
*/
resume() {
this.synth.resume();
}

/**
* Get supported languages
* @returns {Array} Array of unique language codes
*/
getSupportedLanguages() {
const languages = new Set();
this.voices.forEach(voice => {
languages.add(voice.lang);
});
return Array.from(languages);
}
}

// Usage example:
/*
import TextToSpeechAPI from './text-to-speech-api.js';
const tts = new TextToSpeechAPI();
// Basic usage
tts.speak('Hello, world!');
// Advanced usage
tts.speak('Custom voice and options', {
rate: 1.2,
pitch: 1.0,
volume: 0.8
}).then(() => {
console.log('Speech completed');
}).catch(error => {
console.error('Speech error:', error);
});
// Get available voices
const voices = tts.getVoices();
// Get voices for a specific language
const englishVoices = tts.getVoicesForLanguage('en-US');
// Set a specific voice
tts.setVoice('Microsoft David - English (United States)');
// Control playback
tts.pause();
tts.resume();
tts.stop();
// Check status
const isSpeaking = tts.isSpeaking();
// Get supported languages
const languages = tts.getSupportedLanguages();
*/
16 changes: 8 additions & 8 deletions js/config/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const TOOLS = [
description: 'Convert text to natural-sounding speech with multiple voices and languages.',
icon: 'fa-volume-up',
features: ['Multiple voices', 'Download audio'],
path: './pages/text-to-speech.html',
path: 'pages/text-to-speech.html',
category: TOOL_CATEGORIES.AUDIO,
order: 1
},
Expand All @@ -42,7 +42,7 @@ export const TOOLS = [
description: 'Resize and optimize your images while maintaining quality.',
icon: 'fa-image',
features: ['Preserve ratio', 'Multiple formats'],
path: './pages/image-resizer.html',
path: 'pages/image-resizer.html',
category: TOOL_CATEGORIES.IMAGE,
order: 2
},
Expand All @@ -52,7 +52,7 @@ export const TOOLS = [
description: 'Generate beautiful color harmonies for your designs.',
icon: 'fa-palette',
features: ['Color harmony', 'Export options'],
path: './pages/color-palette.html',
path: 'pages/color-palette.html',
category: TOOL_CATEGORIES.DESIGN,
order: 3
},
Expand All @@ -62,7 +62,7 @@ export const TOOLS = [
description: 'Convert images into creative ASCII art with customization options.',
icon: 'fa-font',
features: ['Custom styles', 'Export text'],
path: './pages/ascii-art.html',
path: 'pages/ascii-art.html',
category: TOOL_CATEGORIES.IMAGE,
order: 4
},
Expand All @@ -72,7 +72,7 @@ export const TOOLS = [
description: 'Generate customizable QR codes for your links and data.',
icon: 'fa-qrcode',
features: ['Custom styles', 'Download PNG'],
path: './pages/qr-code.html',
path: 'pages/qr-code.html',
category: TOOL_CATEGORIES.UTILITY,
order: 5
},
Expand All @@ -82,7 +82,7 @@ export const TOOLS = [
description: 'Create strong, secure passwords with advanced customization.',
icon: 'fa-key',
features: ['Custom options', 'Strength meter'],
path: './pages/password-generator.html',
path: 'pages/password-generator.html',
category: TOOL_CATEGORIES.SECURITY,
order: 6
},
Expand All @@ -92,7 +92,7 @@ export const TOOLS = [
description: 'Create short, memorable links for easy sharing and tracking.',
icon: 'fa-link',
features: ['Click analytics', 'Custom aliases'],
path: './pages/url-shortener.html',
path: 'pages/url-shortener.html',
category: TOOL_CATEGORIES.UTILITY,
order: 7
}
Expand Down Expand Up @@ -154,4 +154,4 @@ export const TOOL_STATS = {
TOOLS.filter(tool => tool.category === category).length
])
)
};
};
6 changes: 3 additions & 3 deletions js/features/about.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { generateToolList } from '../utils/template-generator.js';
import { initializeTheme } from '../utils/theme.js';
import { generateToolList } from '/js/utils/template-generator.js';
import { initializeTheme } from '/js/utils/theme.js';

// Initialize theme
initializeTheme();
Expand All @@ -8,4 +8,4 @@ initializeTheme();
const toolsContainer = document.getElementById('tools-container');
if (toolsContainer) {
toolsContainer.innerHTML = generateToolList();
}
}

0 comments on commit 17bec48

Please sign in to comment.