Merge 05c51e5f60 into 5732483fc2
				
					
				
			This commit is contained in:
		
						commit
						a434bbcd8d
					
				
							
								
								
									
										5
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -128,12 +128,11 @@ declare module '@vue/runtime-core' { | ||||
|     MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default'] | ||||
|     MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] | ||||
|     MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] | ||||
|     MicTester: typeof import('./src/tools/mic-tester/mic-tester.vue')['default'] | ||||
|     MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] | ||||
|     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] | ||||
|     NCheckbox: typeof import('naive-ui')['NCheckbox'] | ||||
|     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] | ||||
|     NConfigProvider: typeof import('naive-ui')['NConfigProvider'] | ||||
|     NDivider: typeof import('naive-ui')['NDivider'] | ||||
|     NEllipsis: typeof import('naive-ui')['NEllipsis'] | ||||
|     NH1: typeof import('naive-ui')['NH1'] | ||||
|     NH3: typeof import('naive-ui')['NH3'] | ||||
| @ -141,8 +140,6 @@ declare module '@vue/runtime-core' { | ||||
|     NLayout: typeof import('naive-ui')['NLayout'] | ||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||
|     NMenu: typeof import('naive-ui')['NMenu'] | ||||
|     NSpace: typeof import('naive-ui')['NSpace'] | ||||
|     NTable: typeof import('naive-ui')['NTable'] | ||||
|     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] | ||||
|     OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] | ||||
|     PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] | ||||
|  | ||||
| @ -281,6 +281,11 @@ tools: | ||||
|   mime-types: | ||||
|     title: MIME-Typen | ||||
|     description: Konvertiere MIME-Typen in Erweiterungen und umgekehrt. | ||||
|   mic-tester: | ||||
|     title: Mikrofonprufung | ||||
|     description: Wiedergabe und Visualisierung des Tons von Ihrem Mikrofon, mit einer Sekunde Verzögerung hinzugefügt | ||||
|     start-button-text: Mikrofon-Wiedergabe Starten | ||||
|     stop-button-text: Mikrofon-Wiedergabe Stoppen | ||||
|   toml-to-json: | ||||
|     title: TOML zu JSON | ||||
|     description: Parse und konvertiere TOML zu JSON. | ||||
|  | ||||
| @ -240,6 +240,12 @@ tools: | ||||
|     title: MIME types | ||||
|     description: Convert MIME types to file extensions and vice-versa. | ||||
| 
 | ||||
|   mic-tester: | ||||
|     title: Microphone Tester | ||||
|     description: Replay and Visualize sound from Your microphone, with added one second of delay | ||||
|     start-button-text: Start replaying microphone | ||||
|     stop-button-text: Stop replaying microphone | ||||
| 
 | ||||
|   toml-to-json: | ||||
|     title: TOML to JSON | ||||
|     description: Parse and convert TOML to JSON. | ||||
|  | ||||
							
								
								
									
										87
									
								
								locales/pl.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								locales/pl.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| home: | ||||
|   categories: | ||||
|     newestTools: 'Najnowsze narzędzia' | ||||
|     favoriteTools: 'Twoje ulubione narzędzia' | ||||
|     allTools: 'Wszystkie narzędzia' | ||||
|   subtitle: 'Narzędzia dla programistów' | ||||
|   toggleMenu: 'Menu' | ||||
|   home: Strona główna | ||||
|   uiLib: 'UI Lib' | ||||
|   buyMeACoffee: 'Wesprzyj IT-Tools' | ||||
|   follow: | ||||
|     title: 'Podoba Ci się it-tools?' | ||||
|     p1: 'Wesprzyj nas gwiazdką na' | ||||
|     githubRepository: "repozytorium GitHub IT-Tools" | ||||
|     p2: 'lub śledź nas na' | ||||
|     twitterAccount: "koncie Twitter IT-Tools" | ||||
|     thankYou: 'Dziękujemy!' | ||||
|   nav: | ||||
|     github: 'Repozytorium GitHub' | ||||
|     githubRepository: "Repozytorium GitHub IT-Tools" | ||||
|     twitter: 'Konto Twitter' | ||||
|     twitterAccount: "Konto Twitter IT-Tools" | ||||
|     about: "O IT-Tools" | ||||
|     aboutLabel: 'O nas' | ||||
|     darkMode: 'Tryb ciemny' | ||||
|     lightMode: 'Tryb jasny' | ||||
|     mode: 'Przełącz tryb ciemny/jasny' | ||||
| about: | ||||
|   content: > | ||||
|     # O IT-Tools | ||||
| 
 | ||||
|     Ta wspaniała strona, stworzona z ❤ przez [Corentina Thomasseta](https://corentin.tech?utm_source=it-tools&utm_medium=about), zbiera przydatne narzędzia dla programistów i osób pracujących w IT. Jeśli uznasz ją za pomocną, nie zapomnij się nią podzielić i dodać do ulubionych! | ||||
| 
 | ||||
|     IT Tools jest open-source (na licencji MIT) i darmowe, i takie pozostanie, ale koszty związane z jego hostingiem i odnawianiem domeny spoczywają na mnie. Jeśli chcesz wesprzeć moją pracę i zmotywować mnie do dodania kolejnych narzędzi, zachęcam do [wsparcia](https://www.buymeacoffee.com/cthmsst). | ||||
| 
 | ||||
|     ## Technologie | ||||
| 
 | ||||
|     IT Tools zostało stworzone w Vue.js (Vue 3) z wykorzystaniem biblioteki komponentów Naive UI i jest hostowane oraz ciągle wdrażane przez Vercel. Niektóre narzędzia korzystają z zewnętrznych bibliotek open-source, pełną listę znajdziesz w pliku [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) repozytorium. | ||||
| 
 | ||||
|     ## Znalazłeś błąd? Brakuje jakiegoś narzędzia? | ||||
| 
 | ||||
|     Jeśli potrzebujesz narzędzia, które nie jest jeszcze dostępne, a uważasz, że mogłoby być przydatne, zapraszam do zgłoszenia propozycji funkcji w [sekcji issue](https://github.com/CorentinTh/it-tools/issues/new/choose) repozytorium GitHub. | ||||
| 
 | ||||
| 404: | ||||
|   notFound: '404 Nie znaleziono' | ||||
|   sorry: "Przepraszamy, ta strona nie istnieje" | ||||
|   maybe: 'Może to problem z cachem, spróbuj wymusić odświeżenie?' | ||||
|   backHome: "Powrót na stronę główną" | ||||
| toolCard: | ||||
|   new: Nowe | ||||
| search: | ||||
|   label: Szukaj | ||||
| tools: | ||||
|   categories: | ||||
|     favorite-tools: 'Twoje ulubione narzędzia' | ||||
|     crypto: Kryptografia | ||||
|     converter: Konwerter | ||||
|     web: Web | ||||
|     images and videos: 'Obrazy i wideo' | ||||
|     development: Programowanie | ||||
|     network: Sieć | ||||
|     math: Matematyka | ||||
|     measurement: Pomiary | ||||
|     text: Tekst | ||||
|     data: Dane | ||||
| 
 | ||||
|   token-generator: | ||||
|     title: Generator tokenów | ||||
|     description: >- | ||||
|       Generuje losowy ciąg znaków z wybranych przez Ciebie znaków: wielkie | ||||
|       lub małe litery, cyfry i/lub symbole. | ||||
|     uppercase: Wielkie litery (ABC...) | ||||
|     lowercase: Małe litery (abc...) | ||||
|     numbers: Cyfry (123...) | ||||
|     symbols: Symbole (!-;...) | ||||
|     button: | ||||
|       copy: Kopiuj | ||||
|       refresh: Odśwież | ||||
|     copied: Token został skopiowany | ||||
|     length: Długość | ||||
|     tokenPlaceholder: Token... | ||||
| 
 | ||||
|   mic-tester: | ||||
|     title: Tester mikrofonu | ||||
|     description: Odtwórz i wizualizuj dźwięk z Twojego mikrofonu, z dodaną jedną sekundą opóźnienia | ||||
|     start-button-text: Odtwarzaj mikrofonu | ||||
|     stop-button-text: Zatrzymaj odtwarzanie mikrofonu | ||||
| @ -6,6 +6,7 @@ const localesLong: Record<string, string> = { | ||||
|   de: 'Deutsch', | ||||
|   es: 'Español', | ||||
|   fr: 'Français', | ||||
|   pl: 'Polski', | ||||
|   pt: 'Português', | ||||
|   ru: 'Русский', | ||||
|   uk: 'Українська', | ||||
|  | ||||
| @ -87,6 +87,7 @@ import { tool as uuidGenerator } from './uuid-generator'; | ||||
| import { tool as macAddressLookup } from './mac-address-lookup'; | ||||
| import { tool as xmlFormatter } from './xml-formatter'; | ||||
| import { tool as yamlViewer } from './yaml-viewer'; | ||||
| import { tool as micTester } from './mic-tester'; | ||||
| 
 | ||||
| export const toolsByCategory: ToolCategory[] = [ | ||||
|   { | ||||
| @ -137,6 +138,7 @@ export const toolsByCategory: ToolCategory[] = [ | ||||
|       httpStatusCodes, | ||||
|       jsonDiff, | ||||
|       safelinkDecoder, | ||||
|       micTester, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/tools/mic-tester/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/mic-tester/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { Microphone } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| import { translate } from '@/plugins/i18n.plugin'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: translate('tools.mic-tester.title'), | ||||
|   path: '/mic-tester', | ||||
|   description: translate('tools.mic-tester.description'), | ||||
|   keywords: ['mic', 'microphone', 'test', 'check', 'troubleshoot', 'sound'], | ||||
|   component: () => import('./mic-tester.vue'), | ||||
|   icon: Microphone, | ||||
| }); | ||||
							
								
								
									
										91
									
								
								src/tools/mic-tester/mic-tester.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/tools/mic-tester/mic-tester.service.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | ||||
| import { onBeforeUnmount, ref } from 'vue'; | ||||
| 
 | ||||
| interface IMessageSender { | ||||
|   error: (...messages: any[]) => void | ||||
| } | ||||
| 
 | ||||
| export function useMicrophoneService(messageSender: IMessageSender) { | ||||
|   let audioContext: AudioContext | null = null; | ||||
|   let delayNode: DelayNode | null = null; | ||||
|   let sourceNode: MediaStreamAudioSourceNode | null = null; | ||||
|   let analyserNode: AnalyserNode | null = null; | ||||
|   let stream: MediaStream | null = null; | ||||
| 
 | ||||
|   const isPlaying = ref(false); | ||||
|   const loudnessLevel = ref(0); // Observable for loudness
 | ||||
| 
 | ||||
|   // Measure loudness and update loudness bar
 | ||||
|   function measureLoudness() { | ||||
|     const dataArray = new Uint8Array(analyserNode!.frequencyBinCount); | ||||
| 
 | ||||
|     const updateLoudness = () => { | ||||
|       analyserNode!.getByteFrequencyData(dataArray); | ||||
| 
 | ||||
|       // Calculate average loudness
 | ||||
|       let sum = 0; | ||||
|       dataArray.forEach(value => sum += value); | ||||
|       const average = sum / dataArray.length; | ||||
| 
 | ||||
|       // Update the observable loudness level
 | ||||
|       loudnessLevel.value = average; | ||||
| 
 | ||||
|       if (isPlaying.value) { | ||||
|         requestAnimationFrame(updateLoudness); | ||||
|       } | ||||
|     }; | ||||
|     updateLoudness(); | ||||
|   }; | ||||
| 
 | ||||
|   const startMicReplay = async () => { | ||||
|     if (!audioContext) { | ||||
|       audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       stream = await navigator.mediaDevices.getUserMedia({ audio: true }); | ||||
|     } | ||||
|     catch (err) { | ||||
|       console.error('Microphone access denied:', err); | ||||
|       messageSender.error('Microphone access denied (the error is also in the console):', err); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     sourceNode = audioContext.createMediaStreamSource(stream); | ||||
|     delayNode = audioContext.createDelay(1.0); | ||||
|     delayNode.delayTime.value = 1.0; | ||||
| 
 | ||||
|     analyserNode = audioContext.createAnalyser(); | ||||
|     analyserNode.fftSize = 256; | ||||
| 
 | ||||
|     // Connect nodes: mic -> delay -> speakers
 | ||||
|     sourceNode.connect(delayNode); | ||||
|     delayNode.connect(audioContext.destination); | ||||
|     sourceNode.connect(analyserNode); | ||||
| 
 | ||||
|     isPlaying.value = true; | ||||
|     measureLoudness(); | ||||
|   }; | ||||
| 
 | ||||
|   function stopMicReplay() { | ||||
|     if (audioContext && stream) { | ||||
|       const tracks = stream.getTracks(); | ||||
|       tracks.forEach(track => track.stop()); | ||||
|       audioContext.close(); | ||||
|       audioContext = null; | ||||
|       isPlaying.value = false; | ||||
|       loudnessLevel.value = 0; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   // Cleanup on service destruction
 | ||||
|   onBeforeUnmount(() => { | ||||
|     stopMicReplay(); | ||||
|   }); | ||||
| 
 | ||||
|   return { | ||||
|     startMicReplay, | ||||
|     stopMicReplay, | ||||
|     loudnessLevel, | ||||
|     isPlaying, | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										50
									
								
								src/tools/mic-tester/mic-tester.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/tools/mic-tester/mic-tester.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| <script setup lang="ts"> | ||||
| import { useI18n } from 'vue-i18n'; | ||||
| import { useMessage } from 'naive-ui'; | ||||
| import { useMicrophoneService } from './mic-tester.service'; | ||||
| 
 | ||||
| const message = useMessage(); | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
| const { startMicReplay, stopMicReplay, loudnessLevel, isPlaying } = useMicrophoneService(message); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <c-card> | ||||
|       <div class="control-buttons"> | ||||
|         <c-button :disabled="isPlaying" @click="startMicReplay"> | ||||
|           {{ t('tools.mic-tester.start-button-text') }} | ||||
|         </c-button> | ||||
|         <c-button :disabled="!isPlaying" @click="stopMicReplay"> | ||||
|           {{ t('tools.mic-tester.stop-button-text') }} | ||||
|         </c-button> | ||||
|       </div> | ||||
| 
 | ||||
|       <!-- Loudness Meter --> | ||||
|       <div id="loudnessMeter"> | ||||
|         <div id="loudnessBar" :style="{ width: `${loudnessLevel}%` }" /> | ||||
|       </div> | ||||
|     </c-card> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| #loudnessMeter { | ||||
| width: 100%; | ||||
| height: 30px; | ||||
| background-color: rgba(46, 51, 56, 0.05); | ||||
| margin-top: 20px; | ||||
| position: relative; | ||||
| } | ||||
| #loudnessBar { | ||||
| height: 100%; | ||||
| background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%); | ||||
| } | ||||
| .control-buttons { | ||||
| display: flex; | ||||
| gap: 10px; | ||||
| margin-bottom: 20px; | ||||
| justify-content: space-between; | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user