Skip to content

Commit 10fa13c

Browse files
author
mcarbonell
committed
feat: Soporte completo multiidioma para herramientas
- Copiar tools-index-en.json a extensión - loadTools(lang) carga JSON según idioma - URLs localizadas: ES con /es/, EN sin prefijo - Categorías en inglés (Image, Data, Text, Utils, AI, Files, Converters, Generators) - Herramientas locales traducidas (Capture, Notes) - Recargar herramientas al cambiar idioma
1 parent 30d5a31 commit 10fa13c

File tree

5 files changed

+298
-64
lines changed

5 files changed

+298
-64
lines changed

extension/data/tools-index-en.json

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
[
2+
{
3+
"title": "Resize Image",
4+
"slug": "tools/image/image-resizer.html",
5+
"description": "Resize images in the browser while maintaining aspect ratio.",
6+
"category": "Image",
7+
"tags": ["image", "canvas", "drag-drop"]
8+
},
9+
{
10+
"title": "Convert Image Format",
11+
"slug": "tools/image/convert-image.html",
12+
"description": "Convert JPG, PNG and WebP without uploading files.",
13+
"category": "Image",
14+
"tags": ["image", "convert", "download"]
15+
},
16+
{
17+
"title": "Format JSON",
18+
"slug": "tools/data/json-formatter.html",
19+
"description": "Format, validate and minify JSON instantly.",
20+
"category": "Data",
21+
"tags": ["json", "validator", "copy"]
22+
},
23+
{
24+
"title": "CSV ↔ JSON",
25+
"slug": "tools/data/csv-json.html",
26+
"description": "Convert CSV to JSON and JSON to CSV in the browser. Supports drag and drop.",
27+
"category": "Data",
28+
"tags": ["csv", "json", "convert", "detect"]
29+
},
30+
{
31+
"title": "Extract Text from PDF",
32+
"slug": "tools/files/pdf-to-text.html",
33+
"description": "Extract text from PDF files in the browser using PDF.js.",
34+
"category": "Files",
35+
"tags": ["pdf", "ocr-lite", "extract"]
36+
},
37+
{
38+
"title": "Merge PDFs",
39+
"slug": "tools/files/merge-pdfs.html",
40+
"description": "Combine multiple PDF files into one directly in your browser.",
41+
"category": "Files",
42+
"tags": ["pdf", "merge"]
43+
},
44+
{
45+
"title": "Split PDF",
46+
"slug": "tools/files/split-pdf.html",
47+
"description": "Split a PDF into multiple parts or extract specific pages.",
48+
"category": "Files",
49+
"tags": ["pdf", "split", "extract"]
50+
},
51+
{
52+
"title": "Compress PDF",
53+
"slug": "tools/files/compress-pdf.html",
54+
"description": "Reduce PDF size by compressing the images it contains.",
55+
"category": "Files",
56+
"tags": ["pdf", "compress", "optimize"]
57+
},
58+
{
59+
"title": "PDF to Image",
60+
"slug": "tools/files/pdf-to-image.html",
61+
"description": "Convert each PDF page to JPG or PNG images.",
62+
"category": "Converters",
63+
"tags": ["pdf", "image", "convert", "jpg", "png"]
64+
},
65+
{
66+
"title": "Image to PDF",
67+
"slug": "tools/files/image-to-pdf.html",
68+
"description": "Convert one or multiple images (JPG, PNG) to a PDF file.",
69+
"category": "Converters",
70+
"tags": ["image", "pdf", "convert", "jpg", "png"]
71+
},
72+
{
73+
"title": "Color Palette Generator",
74+
"slug": "tools/image/color-palette-generator.html",
75+
"description": "Extract the dominant color palette from any image.",
76+
"category": "Image",
77+
"tags": ["image", "colors", "palette", "design"]
78+
},
79+
{
80+
"title": "EXIF Viewer & Cleaner",
81+
"slug": "tools/image/exif-viewer-cleaner.html",
82+
"description": "View EXIF metadata from your images and remove private information.",
83+
"category": "Image",
84+
"tags": ["image", "exif", "privacy", "clean"]
85+
},
86+
{
87+
"title": "Lorem Ipsum Generator",
88+
"slug": "tools/text/lorem-ipsum-generator.html",
89+
"description": "Generate Lorem Ipsum text for your design and development projects.",
90+
"category": "Generators",
91+
"tags": ["text", "lorem ipsum", "generator", "development"]
92+
},
93+
{
94+
"title": "Crop Image",
95+
"slug": "tools/image/image-cropper.html",
96+
"description": "Crop your images online easily and precisely.",
97+
"category": "Image",
98+
"tags": ["image", "crop", "editor"]
99+
},
100+
{
101+
"title": "Clean Text",
102+
"slug": "tools/text/text-cleaner.html",
103+
"description": "Remove extra spaces, normalize line breaks and count words.",
104+
"category": "Text",
105+
"tags": ["text", "clean", "count"]
106+
},
107+
{
108+
"title": "Encode/Decode URL",
109+
"slug": "tools/text/url-encoder.html",
110+
"description": "Encode and decode URLs and parameters. Works offline in your browser.",
111+
"category": "Text",
112+
"tags": ["text", "url", "encode", "decode"]
113+
},
114+
{
115+
"title": "Encode/Decode Base64",
116+
"slug": "tools/text/base64.html",
117+
"description": "Encode and decode text in Base64. Works offline in your browser.",
118+
"category": "Text",
119+
"tags": ["text", "base64", "encode", "decode"]
120+
},
121+
{
122+
"title": "Encode/Decode HTML",
123+
"slug": "tools/text/html-encoder.html",
124+
"description": "Encode and decode HTML entities. Works offline in your browser.",
125+
"category": "Text",
126+
"tags": ["text", "html", "encode", "decode"]
127+
},
128+
{
129+
"title": "Compare Texts",
130+
"slug": "tools/text/diff.html",
131+
"description": "Compare two texts and find the differences between them.",
132+
"category": "Text",
133+
"tags": ["text", "diff", "compare"]
134+
},
135+
{
136+
"title": "YAML ↔ JSON",
137+
"slug": "tools/data/yaml-json.html",
138+
"description": "Convert YAML to JSON and JSON to YAML in the browser.",
139+
"category": "Data",
140+
"tags": ["yaml", "json", "convert", "data"]
141+
},
142+
{
143+
"title": "XML ↔ JSON",
144+
"slug": "tools/data/xml-json.html",
145+
"description": "Convert XML to JSON and JSON to XML in the browser.",
146+
"category": "Data",
147+
"tags": ["xml", "json", "convert", "data"]
148+
},
149+
{
150+
"title": "TOML ↔ JSON",
151+
"slug": "tools/data/toml-json.html",
152+
"description": "Convert TOML to JSON and JSON to TOML in the browser.",
153+
"category": "Data",
154+
"tags": ["toml", "json", "convert", "data"]
155+
},
156+
{
157+
"title": "QR Generator",
158+
"slug": "tools/utils/qr-generator.html",
159+
"description": "Generate QR codes from text or URL and download the image.",
160+
"category": "Utilities",
161+
"tags": ["qr", "image", "generator"]
162+
},
163+
{
164+
"title": "Password Generator",
165+
"slug": "tools/utils/password-generator.html",
166+
"description": "Secure password generator with length and character type options.",
167+
"category": "Utilities",
168+
"tags": ["password", "security", "generator"]
169+
},
170+
{
171+
"title": "Hash Calculator",
172+
"slug": "tools/utils/hash-calculator.html",
173+
"description": "Calculate MD5, SHA-1, SHA-256 and SHA-512 hashes for text.",
174+
"category": "Utilities",
175+
"tags": ["hash", "md5", "sha", "security"]
176+
},
177+
{
178+
"title": "Compress Image",
179+
"slug": "tools/image/image-compressor.html",
180+
"description": "Reduce the size of your images (JPG, PNG, WebP) without losing visible quality.",
181+
"category": "Image",
182+
"tags": ["image", "compress", "quality", "download"]
183+
},
184+
{
185+
"title": "Color Picker & Converter",
186+
"slug": "tools/utils/color-picker-converter.html",
187+
"description": "Pick colors and convert them between HEX, RGB and HSL formats.",
188+
"category": "Utilities",
189+
"tags": ["color", "picker", "converter", "hex", "rgb", "hsl"]
190+
},
191+
{
192+
"title": "Stopwatch & Timer",
193+
"slug": "tools/utils/stopwatch-timer.html",
194+
"description": "A simple and easy to use online stopwatch and timer.",
195+
"category": "Utilities",
196+
"tags": ["stopwatch", "timer", "time", "utility"]
197+
},
198+
{
199+
"title": "AI Chat",
200+
"slug": "tools/ai/chat-ai.html",
201+
"description": "Chat with Google Gemini. Use your own API key, 100% private in your browser.",
202+
"category": "AI",
203+
"tags": ["ai", "chat", "gemini", "conversation"]
204+
},
205+
{
206+
"title": "Summarize Text with AI",
207+
"slug": "tools/ai/summarize.html",
208+
"description": "Automatically summarize long texts with AI. Multiple summary types available.",
209+
"category": "AI",
210+
"tags": ["ai", "summarize", "text", "summary"]
211+
},
212+
{
213+
"title": "Improve Text with AI",
214+
"slug": "tools/ai/improve-text.html",
215+
"description": "Improve grammar, style and clarity of your texts with AI. Multi-language support.",
216+
"category": "AI",
217+
"tags": ["ai", "improve", "text", "grammar"]
218+
},
219+
{
220+
"title": "Chat with PDF",
221+
"slug": "tools/ai/chat-pdf.html",
222+
"description": "Upload a PDF and ask questions about its content with AI. Everything processed locally.",
223+
"category": "AI",
224+
"tags": ["ai", "pdf", "chat", "analyze"]
225+
},
226+
{
227+
"title": "Edit Image with AI",
228+
"slug": "tools/ai/edit-image.html",
229+
"description": "Edit images with text instructions using Gemini 2.5 Flash Image (Nano Banana).",
230+
"category": "AI",
231+
"tags": ["ai", "image", "edit", "nano-banana"]
232+
}
233+
]

extension/newtab/newtab-simple.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@ class FastToolsNewTab {
4545
// ====================
4646

4747
async loadData() {
48-
// Load tools from JSON
49-
this.tools = await loadTools();
50-
51-
// Load user data
48+
// Load user data first to get language
5249
const data = await getStorage(['settings', 'analytics', 'notes', 'colors']);
5350

5451
this.settings = data.settings || { theme: 'auto', quickAccess: [] };
@@ -57,6 +54,9 @@ class FastToolsNewTab {
5754
this.colors = data.colors || ['#13a4ec', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4', '#84cc16', '#f97316'];
5855

5956
this.quickAccess = this.settings.quickAccess || ['capture', 'notes', 'json-formatter', 'color-picker', 'password-generator', 'qr-generator'];
57+
58+
// Load tools with current language
59+
this.tools = await loadTools(this.lang);
6060
}
6161

6262
// ====================
@@ -575,6 +575,8 @@ class FastToolsNewTab {
575575
this.applyTheme();
576576

577577
if (languageChanged) {
578+
// Reload tools with new language
579+
this.tools = await loadTools(this.lang);
578580
this.render();
579581
}
580582
}

extension/popup/popup-simple.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ class FastToolsPopup {
2222
}
2323

2424
async loadData() {
25-
// Load tools
26-
this.tools = await loadTools();
27-
28-
// Load user data
29-
const data = await getStorage(['notes', 'analytics', 'recentColors']);
25+
// Load user data first to get language
26+
const data = await getStorage(['notes', 'analytics', 'recentColors', 'settings']);
3027
this.notes = data.notes?.items || [];
3128
this.analytics = data.analytics || {};
3229
this.recentColors = data.recentColors || ['#13a4ec', '#000000', '#ffffff'];
30+
31+
// Load tools with current language
32+
this.tools = await loadTools(this.lang);
3333
}
3434

3535
setupEventListeners() {

extension/shared/i18n.js

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@ const translations = {
2727
btn_delete: '🗑️ Eliminar',
2828
btn_close: 'Cerrar',
2929

30-
// Categories
30+
// Categories (using English keys from web)
3131
category_all: 'Todo',
32-
category_imagen: '🖼️ Imagen',
33-
category_datos: '📊 Datos',
34-
category_texto: '📝 Texto',
35-
category_utilidades: '🔧 Utilidades',
36-
category_ia: '🤖 IA',
37-
// English category names (fallback)
3832
category_image: '🖼️ Imagen',
3933
category_data: '📊 Datos',
4034
category_text: '📝 Texto',
4135
category_utils: '🔧 Utilidades',
4236
category_ai: '🤖 IA',
37+
category_files: '📁 Archivos',
38+
category_converters: '🔄 Conversores',
39+
category_generators: '✨ Generadores',
4340

4441
// Timer
4542
timer_title: '⏰ Temporizador',
@@ -115,19 +112,16 @@ const translations = {
115112
btn_delete: '🗑️ Delete',
116113
btn_close: 'Close',
117114

118-
// Categories
115+
// Categories (using English keys from web)
119116
category_all: 'All',
120-
category_imagen: '🖼️ Image',
121-
category_datos: '📊 Data',
122-
category_texto: '📝 Text',
123-
category_utilidades: '🔧 Utils',
124-
category_ia: '🤖 AI',
125-
// English category names (fallback)
126117
category_image: '🖼️ Image',
127118
category_data: '📊 Data',
128119
category_text: '📝 Text',
129120
category_utils: '🔧 Utils',
130121
category_ai: '🤖 AI',
122+
category_files: '📁 Files',
123+
category_converters: '🔄 Converters',
124+
category_generators: '✨ Generators',
131125

132126
// Timer
133127
timer_title: '⏰ Timer',
@@ -223,20 +217,7 @@ export function t(key, params = {}, lang = null) {
223217

224218
// Get category name
225219
export function getCategoryName(category, lang = 'es') {
226-
// Normalize category name (handle both Spanish and English)
227-
const normalized = category.toLowerCase()
228-
.replace('imagen', 'imagen')
229-
.replace('image', 'imagen')
230-
.replace('datos', 'datos')
231-
.replace('data', 'datos')
232-
.replace('texto', 'texto')
233-
.replace('text', 'texto')
234-
.replace('utilidades', 'utilidades')
235-
.replace('utils', 'utilidades')
236-
.replace('ia', 'ia')
237-
.replace('ai', 'ia');
238-
239-
const key = `category_${normalized}`;
220+
const key = `category_${category.toLowerCase()}`;
240221
return t(key, {}, lang);
241222
}
242223

0 commit comments

Comments
 (0)