Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslint/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const astroConfig: Linter.Config = {
name: 'eslint/astro',
files: astroFiles,
plugins: {
// @ts-expect-error - just type error, no issue with the plugin
'jsx-a11y': jsxA11y,
},
rules: {
Expand Down
1 change: 0 additions & 1 deletion .eslint/import.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type Linter } from 'eslint'
// @ts-expect-error - no types available
import importPlugin from 'eslint-plugin-import'

import { sharedFiles } from './shared'
Expand Down
1 change: 1 addition & 0 deletions .eslint/jsx-a11y.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const jsxA11yConfig: Linter.Config = {
...javascriptFiles.filter(f => f.includes('jsx')),
],
plugins: {
// @ts-expect-error - just type error, no issue with the plugin
'jsx-a11y': jsxA11y,
},
rules: {
Expand Down
2 changes: 1 addition & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default defineConfig({
site: 'https://zen-browser.app',
i18n: {
defaultLocale: 'en',
locales: ['en', 'ja'],
locales: ['en', 'ja', 'es'],
routing: {
fallbackType: 'rewrite',
prefixDefaultLocale: false,
Expand Down
10 changes: 10 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"adam",
"AMOLED",
"animejs",
"Apóyanos",
"Astronav",
"brhm",
"Brhm",
Expand All @@ -14,16 +15,23 @@
"canoa",
"Canoa",
"cfasync",
"contáctanos",
"Contáctanos",
"createdAsc",
"createdDefault",
"createdDesc",
"daniel",
"donándonos",
"encriptación",
"ferrocyante",
"flatpaks",
"FMPEG",
"Galdámez",
"García",
"Garro",
"geolocalización",
"infórmalo",
"infórmanos",
"isnan",
"itro",
"jace",
Expand All @@ -45,12 +53,14 @@
"mfsa",
"mozilla",
"Nehalem",
"notarización",
"NSIS",
"OCSP",
"oscar",
"Otero",
"patreon",
"Pdzly",
"Refactorización",
"Ribaric",
"securtiy",
"taroj",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"animejs": "4.0.2",
"arktype": "^2.1.20",
"astro": "5.7.10",
"astro-navbar": "2.3.7",
"autoprefixer": "10.4.14",
Expand Down
366 changes: 196 additions & 170 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Binary file modified public/fonts/JunicodeVF-Italic-subset.woff2
Binary file not shown.
Binary file modified public/fonts/JunicodeVF-Roman-subset.woff2
Binary file not shown.
2 changes: 1 addition & 1 deletion src/components/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const {
</li>
<li>
<a href="https://github.com/zen-browser/desktop/security/policy" class="font-normal"
>{footer.securtiy}</a
>{footer.security}</a
>
</li>
</ul>
Expand Down
3 changes: 2 additions & 1 deletion src/components/ModsList.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { icon, library } from '@fortawesome/fontawesome-svg-core'
import { faSort, faSortDown, faSortUp } from '@fortawesome/free-solid-svg-icons'
import Xmark from '~/icons/XmarkIcon.astro'
import { type ZenTheme } from '~/mods'
import { getPath, type Locale } from '~/utils/i18n'
import { type Locale } from '~/types/i18n'
import { getPath } from '~/utils/i18n'

// Add icons to the library
library.add(faSort, faSortUp, faSortDown)
Expand Down
5 changes: 3 additions & 2 deletions src/components/download/release-data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { type Locale } from '~/types/i18n'
import { getUI } from '~/utils/i18n'

/**
* Returns the releases object, injecting checksums dynamically.
* @param locale The locale to use for labels
* @param checksums Record<string, string> mapping filenames to SHA-256 hashes
*/
export function getReleasesWithChecksums(locale: string) {
export function getReleasesWithChecksums(locale: Locale) {
const {
routes: {
download: {
Expand Down Expand Up @@ -60,7 +61,7 @@ export function getReleasesWithChecksums(locale: string) {
}
}

export function getReleases(locale: string) {
export function getReleases(locale: Locale) {
const {
routes: {
download: {
Expand Down
52 changes: 40 additions & 12 deletions src/constants/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
const UI_EN = (await import('~/i18n/en/translation.json', { with: { type: 'json' } })).default
const UI_JA = (await import('~/i18n/ja/translation.json', { with: { type: 'json' } })).default
import { type } from 'arktype'

import languages from '~/i18n/locales.json' with { type: 'json' }
import { i18nSchema } from '~/schemas/i18n'
import { type I18nType, type Locale } from '~/types/i18n'

/**
* List of all supported locales.
*/
export const locales = Object.keys(languages) as Locale[]

/**
* Maps locale keys to their corresponding translation objects.
*/
export const translations: Record<Locale, I18nType> = Object.fromEntries(
Object.entries(import.meta.glob('~/i18n/**/translation.json', { eager: true })).map(
([key, value]) => {
const result = i18nSchema.I18n(value)

if (result instanceof type.errors) {
throw new Error(`Invalid translation file (${key}):\n${' '.repeat(2)}${result.summary}`)
}

return [/i18n\/([A-z]{2})\/translation.json/.exec(key)?.[1], result]
}
)
)

/**
* Constants for i18n configuration.
*/
export const i18n = {
DEFAULT_LOCALE: 'en',
LOCALES: [
{ label: 'English', value: 'en', ui: UI_EN, intl: 'en-US' },
{ label: '日本語', value: 'ja', ui: UI_JA, intl: 'ja-JP' },
],
}
LOCALES: Object.entries(languages).map(([key, locale]) => {
return {
...locale,
ui: translations[key as Locale],
}
}),
} as const

/**
* Type definition for UI translations based on the English translation
* Retrieves the intl locale string for a given locale.
*/
export type UIProps = typeof UI_EN | typeof UI_JA

export const getIntlLocale = (locale: string) => {
return i18n.LOCALES.find(l => l.value === locale)?.intl
export const getIntlLocale = (locale: Locale) => {
return languages[locale]?.intl
}
4 changes: 2 additions & 2 deletions src/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
},
"securityNotice": {
"title": "Verified & Secure Downloads",
"description": "All Zen downloads are signed and verified for your security. We recommend downloading directly from our official website or GitHub repository. If your download seems broken or gets flagged by your antivirus, please <a href='https://github.com/zen-browser/desktop/issues/new/choose' class='zen-link ml-1'>report it to us</a>."
"description": "All Zen downloads are signed and verified for your security. We recommend downloading directly from our official website or GitHub repository. If your download seems broken or gets flagged by your antivirus, please <a href='https://github.com/zen-browser/desktop/issues/new/choose' class='zen-link'>report it to us</a>."
},
"platformNames": {
"mac": "macOS",
Expand Down Expand Up @@ -483,7 +483,7 @@
"zenMods": "Zen Mods",
"releaseNotes": "Release Notes",
"getHelp": "Get Help",
"securtiy": "Security",
"security": "Security",
"discord": "Discord",
"uptimeStatus": "Uptime Status",
"reportAnIssue": "Report an Issue",
Expand Down
Loading