feat: prepare for i18n
This commit is contained in:
		
							parent
							
								
									7a7dcd3662
								
							
						
					
					
						commit
						ba6e54d7d5
					
				
					 18 changed files with 115 additions and 74 deletions
				
			
		|  | @ -43,9 +43,11 @@ | |||
| 		"@sveltejs/vite-plugin-svelte": "^3.0.0", | ||||
| 		"@tabler/icons-webfont": "^2.47.0", | ||||
| 		"debug": "^4.3.4", | ||||
| 		"i18next": "^23.10.0", | ||||
| 		"lodash": "^4.17.21", | ||||
| 		"normalize.css": "^8.0.1", | ||||
| 		"svelte": "^4.2.7", | ||||
| 		"svelte-i18next": "^2.2.2", | ||||
| 		"tslib": "^2.4.1", | ||||
| 		"typescript": "^5.0.0", | ||||
| 		"vite": "^5.0.3" | ||||
|  |  | |||
							
								
								
									
										24
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										24
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							|  | @ -26,6 +26,9 @@ dependencies: | |||
|   debug: | ||||
|     specifier: ^4.3.4 | ||||
|     version: 4.3.4 | ||||
|   i18next: | ||||
|     specifier: ^23.10.0 | ||||
|     version: 23.10.0 | ||||
|   lodash: | ||||
|     specifier: ^4.17.21 | ||||
|     version: 4.17.21 | ||||
|  | @ -35,6 +38,9 @@ dependencies: | |||
|   svelte: | ||||
|     specifier: ^4.2.7 | ||||
|     version: 4.2.9 | ||||
|   svelte-i18next: | ||||
|     specifier: ^2.2.2 | ||||
|     version: 2.2.2(i18next@23.10.0)(svelte@4.2.9) | ||||
|   tslib: | ||||
|     specifier: ^2.4.1 | ||||
|     version: 2.6.2 | ||||
|  | @ -139,7 +145,6 @@ packages: | |||
|     engines: {node: '>=6.9.0'} | ||||
|     dependencies: | ||||
|       regenerator-runtime: 0.14.1 | ||||
|     dev: true | ||||
| 
 | ||||
|   /@esbuild/aix-ppc64@0.19.12: | ||||
|     resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} | ||||
|  | @ -1802,6 +1807,12 @@ packages: | |||
|       - supports-color | ||||
|     dev: true | ||||
| 
 | ||||
|   /i18next@23.10.0: | ||||
|     resolution: {integrity: sha512-/TgHOqsa7/9abUKJjdPeydoyDc0oTi/7u9F8lMSj6ufg4cbC1Oj3f/Jja7zj7WRIhEQKB7Q4eN6y68I9RDxxGQ==} | ||||
|     dependencies: | ||||
|       '@babel/runtime': 7.23.9 | ||||
|     dev: false | ||||
| 
 | ||||
|   /ieee754@1.2.1: | ||||
|     resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} | ||||
|     dev: true | ||||
|  | @ -2396,7 +2407,6 @@ packages: | |||
| 
 | ||||
|   /regenerator-runtime@0.14.1: | ||||
|     resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /require-directory@2.1.1: | ||||
|     resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} | ||||
|  | @ -2683,6 +2693,16 @@ packages: | |||
|       svelte: 4.2.9 | ||||
|     dev: false | ||||
| 
 | ||||
|   /svelte-i18next@2.2.2(i18next@23.10.0)(svelte@4.2.9): | ||||
|     resolution: {integrity: sha512-IpJDZCH5cCgKfHQHgiLmGT4j9HCdg4fqsP3oP2deLu8PxmNj0Ui6khMiDoxAxedAiYEhr0xendv2xqh3Rq+uQQ==} | ||||
|     peerDependencies: | ||||
|       i18next: '*' | ||||
|       svelte: '*' | ||||
|     dependencies: | ||||
|       i18next: 23.10.0 | ||||
|       svelte: 4.2.9 | ||||
|     dev: false | ||||
| 
 | ||||
|   /svelte-preprocess@5.1.3(postcss@8.4.33)(svelte@4.2.9)(typescript@5.3.3): | ||||
|     resolution: {integrity: sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==} | ||||
|     engines: {node: '>= 16.0.0', pnpm: ^8.0.0} | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| <script lang="ts"> | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { fade } from 'svelte/transition'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	let screenResolution = '... x ...'; | ||||
| 	let windowResolution = ''; | ||||
|  | @ -24,11 +25,11 @@ | |||
| 
 | ||||
| <div class="info"> | ||||
| 	<div class="resolution"> | ||||
| 		<div class="title">Screen Resolution</div> | ||||
| 		<div class="title">{$i18n.t('Screen Resolution')}</div> | ||||
| 		<div class="value">{screenResolution}</div> | ||||
| 		{#if windowResolution && windowResolution !== screenResolution} | ||||
| 			<div class="window" transition:fade> | ||||
| 				<div class="title">Window Resolution</div> | ||||
| 				<div class="title">{$i18n.t('Window Resolution')}</div> | ||||
| 				<div class="value">{windowResolution}</div> | ||||
| 			</div> | ||||
| 		{/if} | ||||
|  |  | |||
							
								
								
									
										8
									
								
								src/lib/i18n.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/lib/i18n.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| import i18next from 'i18next'; | ||||
| import { createI18nStore } from 'svelte-i18next'; | ||||
| 
 | ||||
| i18next.init({ | ||||
| 	lng: 'en' | ||||
| }); | ||||
| 
 | ||||
| export const i18n = createI18nStore(i18next); | ||||
|  | @ -8,6 +8,7 @@ | |||
| 	import { page } from '$app/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	let idleTimeout: NodeJS.Timeout | undefined; | ||||
| 	onMount(() => { | ||||
|  | @ -25,7 +26,7 @@ | |||
| 
 | ||||
| <TestCard full={onlyCard} on:focus={() => goto('/card')} /> | ||||
| <main class:content={!onlyCard} class:sub={!$page.data.root && !onlyCard}> | ||||
| 	<a href=".." class="button button-back"><i class="ti ti-arrow-back" />Back</a> | ||||
| 	<a href=".." class="button button-back"><i class="ti ti-arrow-back" />{$i18n.t('Back')}</a> | ||||
| 	<slot /> | ||||
| </main> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script> | ||||
| 	import { version } from '../../package.json'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <nav> | ||||
|  | @ -8,39 +9,39 @@ | |||
| 	<div class="options"> | ||||
| 		<a href="card"> | ||||
| 			<i class="ti ti-device-desktop"></i> | ||||
| 			Screen | ||||
| 			{$i18n.t('Screen')} | ||||
| 		</a> | ||||
| 		<a href="audio"> | ||||
| 			<i class="ti ti-volume"></i> | ||||
| 			Audio | ||||
| 			{$i18n.t('Audio')} | ||||
| 		</a> | ||||
| 		<a href="av-sync"> | ||||
| 			<i class="ti ti-time-duration-off"></i> | ||||
| 			AV Sync | ||||
| 			{$i18n.t('AV Sync')} | ||||
| 		</a> | ||||
| 		<a href="keyboard"> | ||||
| 			<i class="ti ti-keyboard"></i> | ||||
| 			Keyboard | ||||
| 			{$i18n.t('Keyboard')} | ||||
| 		</a> | ||||
| 		<a href="mouse" class="disabled"> | ||||
| 			<i class="ti ti-mouse"></i> | ||||
| 			Mouse | ||||
| 			{$i18n.t('Mouse')} | ||||
| 		</a> | ||||
| 		<a href="gamepad"> | ||||
| 			<i class="ti ti-device-gamepad"></i> | ||||
| 			Gamepad | ||||
| 			{$i18n.t('Gamepad')} | ||||
| 		</a> | ||||
| 		<a href="camera"> | ||||
| 			<i class="ti ti-camera"></i> | ||||
| 			Camera | ||||
| 			{$i18n.t('Camera')} | ||||
| 		</a> | ||||
| 		<a href="microphone" class="disabled"> | ||||
| 			<i class="ti ti-microphone"></i> | ||||
| 			Microphone | ||||
| 			{$i18n.t('Microphone')} | ||||
| 		</a> | ||||
| 		<a href="sensors" class="disabled"> | ||||
| 			<i class="ti ti-cpu-2"></i> | ||||
| 			Sensors | ||||
| 			{$i18n.t('Sensors')} | ||||
| 		</a> | ||||
| 	</div> | ||||
| </nav> | ||||
|  | @ -63,6 +64,7 @@ | |||
| 		& a { | ||||
| 			text-align: center; | ||||
| 			text-decoration: none; | ||||
| 			white-space: nowrap; | ||||
| 
 | ||||
| 			&.disabled { | ||||
| 				pointer-events: none; | ||||
|  |  | |||
|  | @ -6,19 +6,20 @@ | |||
| 	import rearLeftUrl from '@assets/audio/5.1/Rear_Left.mp3'; | ||||
| 	import rearRightUrl from '@assets/audio/5.1/Rear_Right.mp3'; | ||||
| 	import LfeUrl from '@assets/audio/5.1/LFE_Noise.mp3'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <div class="row"> | ||||
| 	<Speaker src={frontLeftUrl} left>Front Left</Speaker> | ||||
| 	<Speaker src={frontLeftUrl} left>{$i18n.t('Front Left')}</Speaker> | ||||
| 	<div class="center"> | ||||
| 		<Speaker src={frontCenterUrl} center>Front Center</Speaker> | ||||
| 		<Speaker src={frontCenterUrl} center>{$i18n.t('Front Center')}</Speaker> | ||||
| 	</div> | ||||
| 	<Speaker src={frontRightUrl} right>Front Right</Speaker> | ||||
| 	<Speaker src={frontRightUrl} right>{$i18n.t('Front Right')}</Speaker> | ||||
| </div> | ||||
| <div class="row"> | ||||
| 	<Speaker src={rearLeftUrl} left>Rear Left</Speaker> | ||||
| 	<Speaker src={rearRightUrl} right>Rear Right</Speaker> | ||||
| 	<Speaker src={rearLeftUrl} left>{$i18n.t('Rear Left')}</Speaker> | ||||
| 	<Speaker src={rearRightUrl} right>{$i18n.t('Rear Right')}</Speaker> | ||||
| </div> | ||||
| <Speaker src={LfeUrl} lfe>LFE</Speaker> | ||||
| <Speaker src={LfeUrl} lfe>{$i18n.t('LFE')}</Speaker> | ||||
| 
 | ||||
| <div class="label">5.1</div> | ||||
|  |  | |||
|  | @ -8,24 +8,25 @@ | |||
| 	import rearLeftUrl from '@assets/audio/7.1/Rear_Left.mp3'; | ||||
| 	import rearRightUrl from '@assets/audio/7.1/Rear_Right.mp3'; | ||||
| 	import LfeUrl from '@assets/audio/7.1/LFE_Noise.mp3'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <div class="row"> | ||||
| 	<Speaker src={frontLeftUrl} left>Front Left</Speaker> | ||||
| 	<Speaker src={frontLeftUrl} left>{$i18n.t('Front Left')}</Speaker> | ||||
| 	<div class="center"> | ||||
| 		<Speaker src={frontCenterUrl} center>Front Center</Speaker> | ||||
| 		<Speaker src={frontCenterUrl} center>{$i18n.t('Front Center')}</Speaker> | ||||
| 	</div> | ||||
| 	<Speaker src={frontRightUrl} right>Front Right</Speaker> | ||||
| 	<Speaker src={frontRightUrl} right>{$i18n.t('Front Right')}</Speaker> | ||||
| </div> | ||||
| <div class="row"> | ||||
| 	<Speaker src={sideLeftUrl} left>Side Left</Speaker> | ||||
| 	<Speaker src={sideRightUrl} right>Side Right</Speaker> | ||||
| 	<Speaker src={sideLeftUrl} left>{$i18n.t('Side Left')}</Speaker> | ||||
| 	<Speaker src={sideRightUrl} right>{$i18n.t('Side Right')}</Speaker> | ||||
| </div> | ||||
| 
 | ||||
| <div class="row"> | ||||
| 	<Speaker src={rearLeftUrl} left>Rear Left</Speaker> | ||||
| 	<Speaker src={rearRightUrl} right>Rear Right</Speaker> | ||||
| 	<Speaker src={rearLeftUrl} left>{$i18n.t('Rear Left')}</Speaker> | ||||
| 	<Speaker src={rearRightUrl} right>{$i18n.t('Rear Right')}</Speaker> | ||||
| </div> | ||||
| <Speaker src={LfeUrl} lfe>LFE</Speaker> | ||||
| <Speaker src={LfeUrl} lfe>{$i18n.t('LFE')}</Speaker> | ||||
| 
 | ||||
| <div class="label">7.1</div> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script lang="ts"> | ||||
| 	import { onDestroy } from 'svelte'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	export let element: HTMLElement; | ||||
| 
 | ||||
|  | @ -46,8 +47,8 @@ | |||
| <button on:click={onClick}> | ||||
| 	<i class="ti ti-refresh"></i> | ||||
| 	{#if cycling} | ||||
| 		Stop Cycling | ||||
| 		{$i18n.t('Stop Cycling')} | ||||
| 	{:else} | ||||
| 		Cycle through | ||||
| 		{$i18n.t('Cycle through')} | ||||
| 	{/if} | ||||
| </button> | ||||
|  |  | |||
|  | @ -4,15 +4,16 @@ | |||
| 	import rightUrl from '@assets/audio/stereo/Right.mp3'; | ||||
| 	import Speaker from './speaker.svelte'; | ||||
| 	import CycleButton from './cycle-button.svelte'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	let speakersEl: HTMLElement; | ||||
| </script> | ||||
| 
 | ||||
| <div class="test"> | ||||
| 	<div class="speakers" bind:this={speakersEl}> | ||||
| 		<Speaker src={leftUrl} left inline>Left</Speaker> | ||||
| 		<Speaker src={centerUrl} center inline>Center</Speaker> | ||||
| 		<Speaker src={rightUrl} right inline>Right</Speaker> | ||||
| 		<Speaker src={leftUrl} left inline>{$i18n.t('Left')}</Speaker> | ||||
| 		<Speaker src={centerUrl} center inline>{$i18n.t('Center')}</Speaker> | ||||
| 		<Speaker src={rightUrl} right inline>{$i18n.t('Right')}</Speaker> | ||||
| 	</div> | ||||
| 	<CycleButton element={speakersEl} /> | ||||
| </div> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script lang="ts"> | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <h2><i class="ti ti-volume"></i> Audio test</h2> | ||||
| <h2><i class="ti ti-volume"></i> {$i18n.t('Audio test')}</h2> | ||||
| <slot /> | ||||
|  |  | |||
|  | @ -1,22 +1,23 @@ | |||
| <script lang="ts"> | ||||
| 	import StereoTest from './(channels)/stereo-test.svelte'; | ||||
| 	import PhaseTest from './phase.svelte'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <article> | ||||
| 	<h3>Channel tests</h3> | ||||
| 	<h4>Stereo</h4> | ||||
| 	<h3>{$i18n.t('Channel tests')}</h3> | ||||
| 	<h4>{$i18n.t('Stereo')}</h4> | ||||
| 	<section> | ||||
| 		<StereoTest /> | ||||
| 	</section> | ||||
| 	<h4>Surround audio</h4> | ||||
| 	<h4>{$i18n.t('Surround audio')}</h4> | ||||
| 	<section> | ||||
| 		<ul> | ||||
| 			<li><a class="button" href="channels-5.1">5.1 Surround</a></li> | ||||
| 			<li><a class="button" href="channels-7.1">7.1 Surround</a></li> | ||||
| 			<li><a class="button" href="channels-5.1">{$i18n.t('5.1 Surround')}</a></li> | ||||
| 			<li><a class="button" href="channels-7.1">{$i18n.t('7.1 Surround')}</a></li> | ||||
| 		</ul> | ||||
| 	</section> | ||||
| 	<h3>Phase test</h3> | ||||
| 	<h3>{$i18n.t('Phase test')}</h3> | ||||
| 	<PhaseTest /> | ||||
| </article> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script lang="ts"> | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	let frequency = 60; | ||||
| 	let playing = false; | ||||
|  | @ -53,18 +54,13 @@ | |||
| 
 | ||||
| <div class="test"> | ||||
| 	<label> | ||||
| 		Frequency <input | ||||
| 			type="number" | ||||
| 			bind:value={frequency} | ||||
| 			min="20" | ||||
| 			max="20000" | ||||
| 			disabled={playing} | ||||
| 		/>Hz | ||||
| 		{$i18n.t('Frequency')} | ||||
| 		<input type="number" bind:value={frequency} min="20" max="20000" disabled={playing} />Hz | ||||
| 	</label> | ||||
| 	<div class="controls"> | ||||
| 		<button on:click={() => start('inPhase')}>In Phase</button> | ||||
| 		<button on:click={() => start('outOfPhase')}>Out of Phase</button> | ||||
| 		<button class="stop" on:click={stop} disabled={!playing}>Stop</button> | ||||
| 		<button on:click={() => start('inPhase')}>{$i18n.t('In Phase')}</button> | ||||
| 		<button on:click={() => start('outOfPhase')}>{$i18n.t('Out of Phase')}</button> | ||||
| 		<button class="stop" on:click={stop} disabled={!playing}>{$i18n.t('Stop')}</button> | ||||
| 	</div> | ||||
| </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| <script lang="ts"> | ||||
| 	import videoUrl from '@assets/avsync.webm'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 	let paused = true; | ||||
| </script> | ||||
| 
 | ||||
| <h2><i class="ti ti-time-duration-off"></i> Audio/Video Synchronization</h2> | ||||
| <h2><i class="ti ti-time-duration-off"></i> {$i18n.t('Audio/Video Synchronization')}</h2> | ||||
| <!-- svelte-ignore a11y-media-has-caption --> | ||||
| <video | ||||
| 	class:playing={!paused} | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| 	import { onDestroy, onMount } from 'svelte'; | ||||
| 	import { browser } from '$app/environment'; | ||||
| 	import debug from 'debug'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 	const dbg = debug('app:camera'); | ||||
| 
 | ||||
| 	let video: HTMLVideoElement; | ||||
|  | @ -78,26 +79,26 @@ | |||
| 	} | ||||
| </script> | ||||
| 
 | ||||
| <h2><i class="ti ti-camera"></i> Camera test</h2> | ||||
| <h2><i class="ti ti-camera"></i> {$i18n.t('Camera test')}</h2> | ||||
| 
 | ||||
| <div class="controls"> | ||||
| 	<label> | ||||
| 		Device | ||||
| 		{$i18n.t('Device')} | ||||
| 		<select bind:value={currentDevice} disabled={!devices.length}> | ||||
| 			{#each devices as device} | ||||
| 				<option value={device.deviceId}>{device.label || '???'}</option> | ||||
| 			{:else} | ||||
| 				<option>No camera found</option> | ||||
| 				<option>{$i18n.t('No camera found')}</option> | ||||
| 			{/each} | ||||
| 		</select> | ||||
| 	</label> | ||||
| 	<button on:click={refreshDevices}> | ||||
| 		<i class="ti ti-refresh"></i> | ||||
| 		Refresh | ||||
| 		{$i18n.t('Refresh')} | ||||
| 	</button> | ||||
| 	<div class="separator"></div> | ||||
| 	<label> | ||||
| 		Resolution | ||||
| 		{$i18n.t('Resolution')} | ||||
| 		<select bind:value={requestResolution}> | ||||
| 			<option value="auto">Auto</option> | ||||
| 			<option value={[4096, 2160]}>4096x2160</option> | ||||
|  | @ -109,7 +110,7 @@ | |||
| 		</select> | ||||
| 	</label> | ||||
| 	<label> | ||||
| 		Frame rate | ||||
| 		{$i18n.t('Frame rate')} | ||||
| 		<select bind:value={requestFramerate}> | ||||
| 			<option value="auto">Auto</option> | ||||
| 			<option value={120}>120 fps</option> | ||||
|  | @ -135,29 +136,29 @@ | |||
| 
 | ||||
| <footer> | ||||
| 	{#if !currentDevice} | ||||
| 		<span class="subdued">No camera selected</span> | ||||
| 		<span class="subdued">{$i18n.t('No camera selected')}</span> | ||||
| 	{:else} | ||||
| 		<ul> | ||||
| 			{#key currentDevice} | ||||
| 				<li> | ||||
| 					Resolution: <strong>{deviceInfo.resolution || '???'}</strong> | ||||
| 					{$i18n.t('Resolution')}: <strong>{deviceInfo.resolution || '???'}</strong> | ||||
| 				</li> | ||||
| 				<li> | ||||
| 					Frame rate: <strong>{deviceInfo.frameRate || '???'}</strong> | ||||
| 					{$i18n.t('Frame rate')}: <strong>{deviceInfo.frameRate || '???'}</strong> | ||||
| 				</li> | ||||
| 			{/key} | ||||
| 		</ul> | ||||
| 		<div class="controls"> | ||||
| 			<button on:click={takeSnapshot}> | ||||
| 				<i class="ti ti-camera"></i> | ||||
| 				Take picture | ||||
| 				{$i18n.t('Take picture')} | ||||
| 			</button> | ||||
| 			<button on:click={() => (flipped = !flipped)}> | ||||
| 				<i class="ti ti-flip-vertical"></i> | ||||
| 				{#if flipped} | ||||
| 					Unflip image | ||||
| 					{$i18n.t('Unflip image')} | ||||
| 				{:else} | ||||
| 					Flip image | ||||
| 					{$i18n.t('Flip image')} | ||||
| 				{/if} | ||||
| 			</button> | ||||
| 		</div> | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| <script> | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| </script> | ||||
| 
 | ||||
| <a href="/" class="hide-idle"><i class="ti ti-arrow-back"></i> Back</a> | ||||
| <a href="/" class="hide-idle"><i class="ti ti-arrow-back"></i> {$i18n.t('Back')}</a> | ||||
| 
 | ||||
| <style> | ||||
| 	a { | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| 	import { onMount } from 'svelte'; | ||||
| 	import { browser } from '$app/environment'; | ||||
| 	import debug from 'debug'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	const dbg = debug('app:camera'); | ||||
| 
 | ||||
|  | @ -92,27 +93,27 @@ | |||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <h2><i class="ti ti-device-gamepad"></i> Gamepad & Joystick Tests</h2> | ||||
| <h2><i class="ti ti-device-gamepad"></i> {$i18n.t('Gamepad & Joystick Tests')}</h2> | ||||
| <div class="controls"> | ||||
| 	<label> | ||||
| 		Device | ||||
| 		{$i18n.t('Device')} | ||||
| 		<select disabled={!gamepads.length}> | ||||
| 			{#each gamepads as gamepad} | ||||
| 				<option value={gamepad.index}>{gamepad.id}</option> | ||||
| 			{:else} | ||||
| 				<option>No gamepads detected. (Try pressing a button)</option> | ||||
| 				<option>{$i18n.t('No gamepads detected. (Try pressing a button)')}</option> | ||||
| 			{/each} | ||||
| 		</select> | ||||
| 	</label> | ||||
| 	<button on:click={refreshGamepads}> | ||||
| 		<i class="ti ti-refresh"></i> | ||||
| 		Refresh | ||||
| 		{$i18n.t('Refresh')} | ||||
| 	</button> | ||||
| </div> | ||||
| 
 | ||||
| {#if currentGamepad} | ||||
| 	<section> | ||||
| 		<h3>Buttons</h3> | ||||
| 		<h3>{$i18n.t('Buttons')}</h3> | ||||
| 		<ul class="buttons"> | ||||
| 			{#each buttons as button, i} | ||||
| 				<li class:pressed={button.pressed}>{i}</li> | ||||
|  | @ -120,7 +121,7 @@ | |||
| 		</ul> | ||||
| 	</section> | ||||
| 	<section> | ||||
| 		<h3>Axes</h3> | ||||
| 		<h3>{$i18n.t('Axes')}</h3> | ||||
| 		<div class="axes"> | ||||
| 			{#each axes as axis, i (i)} | ||||
| 				<div class="axis"> | ||||
|  | @ -130,7 +131,7 @@ | |||
| 						<span>{axis.toFixed(2)}</span> | ||||
| 					</div> | ||||
| 					<details> | ||||
| 						<summary>History</summary> | ||||
| 						<summary>{$i18n.t('History')}</summary> | ||||
| 						<canvas width="512" height="128" data-axis={i}></canvas> | ||||
| 					</details> | ||||
| 				</div> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script lang="ts"> | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { i18n } from '$lib/i18n'; | ||||
| 
 | ||||
| 	let key: string; | ||||
| 	let code: string; | ||||
|  | @ -14,8 +15,8 @@ | |||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <h2>Keyboard testing</h2> | ||||
| <p>Press a key on the keyboard to see the event object and the key code.</p> | ||||
| <h2>{$i18n.t('Keyboard testing')}</h2> | ||||
| <p>{$i18n.t('Press a key on the keyboard to see the event object and the key code.')}</p> | ||||
| <div class="current"> | ||||
| 	{#if key} | ||||
| 		<span>{key}</span> | ||||
|  | @ -25,7 +26,7 @@ | |||
| 	{/if} | ||||
| </div> | ||||
| 
 | ||||
| <p>Pressed keys:</p> | ||||
| <p>{$i18n.t('Pressed keys:')}</p> | ||||
| <ul> | ||||
| 	{#each pressedKeys as key} | ||||
| 		<li>{key}</li> | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue