feat(i18n): Arabic, Hebrew, Persian and Urdu, and a layout that mirrors; release v6.4.0
CodeQL Analysis / Analyze CodeQL (push) Canceled after 0s
Deploy Application / deploy (push) Canceled after 0s
Mirror to Codeberg / mirror (push) Canceled after 0s
Mirror to PrivacyGuides / mirror (push) Canceled after 0s

Four right-to-left languages at /ar/, /he/, /fa/ and /ur/ — thirteen in all.

The layout no longer has a left and a right, it has a start and an end: the
margins, insets and corners are CSS logical properties now, so they follow
dir on <html>. Directional glyphs flip; keys, safety codes and session
descriptors are pinned left-to-right so bidi cannot reorder what two people
compare against each other's screens.

Also fixed: the Service Worker was registered as './sw.js', which 404s from
every locale subdirectory, so twelve of the thirteen pages had no worker at
all. And the bundler ran before the dictionaries were generated, so a newly
added language could reach the page ahead of the app that renders it.
This commit is contained in:
lockbitchat
2026-08-29 18:05:20 -04:00
parent 98d42ac2fb
commit 5e32f547b9
68 changed files with 15147 additions and 500 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ window.showUpdateNotification = function showUpdateNotification() {
<h2 style="margin:0 0 9px; font-size:26px; font-weight:800; letter-spacing:-0.7px; color:#f4f4f6;">Update available</h2>
<p style="margin:0 0 24px; font-size:14.5px; line-height:1.55; color:#9a9aa2;">A newer version of SecureBit has been detected.</p>
<div style="border-radius:14px; background:#0c0c0e; border:1px solid rgba(255,255,255,0.06); padding:16px 18px; margin-bottom:24px; text-align:left;">
<div style="border-radius:14px; background:#0c0c0e; border:1px solid rgba(255,255,255,0.06); padding:16px 18px; margin-bottom:24px; text-align:start;">
<div style="display:flex; align-items:center; justify-content:space-between; gap:14px; padding:5px 0;">
<span style="font-size:13.5px; font-weight:500; color:#8a8a92;">Current version</span>
<span class="cur-ver" style="font-family:'JetBrains Mono',ui-monospace,Menlo,monospace; font-size:13px; font-weight:500; color:#9a9aa2; white-space:nowrap;">${currentStr}</span>
+1 -1
View File
@@ -145,7 +145,7 @@ class PWAOfflineTester {
modal.innerHTML = `
<div class="bg-gray-800 rounded-xl p-6 max-w-2xl w-full max-h-[80vh] overflow-y-auto">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-blue-500/10 rounded-full flex items-center justify-center mr-4">
<div class="w-12 h-12 bg-blue-500/10 rounded-full flex items-center justify-center me-4">
<i class="fas fa-vial text-blue-400 text-xl"></i>
</div>
<h3 class="text-xl font-semibold text-white">PWA Offline Test Results</h3>
+8 -2
View File
@@ -2,8 +2,14 @@
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const registration = await navigator.serviceWorker.register('./sw.js', {
scope: './',
// Root-absolute, both of them. Every locale is its own page in its own
// subdirectory, so './sw.js' asks /ar/ for /ar/sw.js — a 404, and no Service
// Worker at all on twelve of the thirteen pages. There is one worker for the
// whole site and it needs the whole site as its scope, or an installed app
// that started at /ar/ would stop being offline-capable the moment it
// navigated to the root.
const registration = await navigator.serviceWorker.register('/sw.js', {
scope: '/',
});
// Store registration for use in other modules