diff --git a/app/Http/Controllers/LinuxController.php b/app/Http/Controllers/LinuxController.php new file mode 100644 index 00000000..49dd9bd2 --- /dev/null +++ b/app/Http/Controllers/LinuxController.php @@ -0,0 +1,25 @@ +find('linux')['linuxEngines'] ?? []; + + return Inertia::render('Linux', [ + 'content' => $content->page('linux', App::getLocale()), + 'engines' => $platforms->isAvailable('linux') && is_array($engines) ? $facts->engineLinks(array_values(array_filter($engines, 'is_string'))) : [], + 'links' => $facts->links(), + 'organizationProfiles' => $facts->organizationProfiles(), + ]); + } +} diff --git a/app/Http/Controllers/LlmsTxtController.php b/app/Http/Controllers/LlmsTxtController.php index 05482dd4..e31c6454 100644 --- a/app/Http/Controllers/LlmsTxtController.php +++ b/app/Http/Controllers/LlmsTxtController.php @@ -33,6 +33,7 @@ class LlmsTxtController extends Controller 'landing.teams', 'landing.download', 'landing.ios', + 'landing.linux', 'landing.integrations.index', 'landing.faq', 'landing.security', diff --git a/app/Services/Content/SiteFacts.php b/app/Services/Content/SiteFacts.php index a698a913..60d84fc1 100644 --- a/app/Services/Content/SiteFacts.php +++ b/app/Services/Content/SiteFacts.php @@ -181,6 +181,31 @@ public function iosEngines(array $pickerOrder): array return ['picker' => $picker, 'syncedOnly' => $syncedOnly]; } + /** + * @param list $ids + * @return list + */ + public function engineLinks(array $ids): array + { + $byId = []; + + foreach ($this->engines() as $engine) { + if (is_string($engine['id'] ?? null)) { + $byId[$engine['id']] = $engine; + } + } + + $links = []; + + foreach ($ids as $id) { + if (($byId[$id]['state'] ?? null) === 'published') { + $links[] = $this->engineLink($byId[$id], $byId); + } + } + + return $links; + } + /** * @return list */ diff --git a/app/Services/Releases/PlatformCatalog.php b/app/Services/Releases/PlatformCatalog.php index cfe3647c..90a0dffc 100644 --- a/app/Services/Releases/PlatformCatalog.php +++ b/app/Services/Releases/PlatformCatalog.php @@ -87,6 +87,12 @@ public function isReleased(string $id): bool return ($this->find($id)['status'] ?? null) === 'released'; } + /** A beta has installable packages even though it is not a stable release. */ + public function isAvailable(string $id): bool + { + return in_array($this->find($id)['status'] ?? null, ['released', 'beta'], true); + } + /** * The ids of the platforms with nothing to install, in data order. * @@ -97,7 +103,7 @@ public function unreleased(): array $ids = []; foreach ($this->all() as $platform) { - if (($platform['status'] ?? null) !== 'released' && is_string($platform['id'] ?? null)) { + if (! in_array($platform['status'] ?? null, ['released', 'beta'], true) && is_string($platform['id'] ?? null)) { $ids[] = $platform['id']; } } diff --git a/app/Support/Seo/StaticPages.php b/app/Support/Seo/StaticPages.php index c2c9a857..7a93dd9a 100644 --- a/app/Support/Seo/StaticPages.php +++ b/app/Support/Seo/StaticPages.php @@ -8,7 +8,7 @@ use App\Support\Pricing\Campaign; /** - * The one-off pages: home, download, iOS, pricing, teams, FAQ, about, security, sponsors, the dated sale and the blog index. + * The one-off pages: home, download, iOS, Linux, pricing, teams, FAQ, about, security, sponsors, the dated sale and the blog index. * * Each renders in a locale when `resources/data/content/{locale}/{page}.json` * exists, and is indexable there unless that file sets `seo.indexable` to @@ -27,6 +27,7 @@ final class StaticPages implements PageFamily 'landing.home' => 'home', 'landing.download' => 'download', 'landing.ios' => 'ios', + 'landing.linux' => 'linux', 'landing.pricing' => 'pricing', 'landing.teams' => 'teams', 'landing.faq' => 'faq', diff --git a/resources/data/content/de/download.json b/resources/data/content/de/download.json index dfbf1330..de76a8fb 100644 --- a/resources/data/content/de/download.json +++ b/resources/data/content/de/download.json @@ -59,5 +59,10 @@ "body": "Jede Version mit ihren Hinweisen und Disk-Images findest du auf GitHub Releases. Das Änderungsprotokoll listet die Änderungen jeder Version auf.", "releases": "Alle Versionen auf GitHub", "changelog": "Änderungsprotokoll (Englisch)" + }, + "linux": { + "title": "TablePro für Linux", + "body": "Eine Linux-Beta mit SQL-Editor und Datentabelle.", + "link": "Linux-Installationsanleitung lesen" } } diff --git a/resources/data/content/de/faq.json b/resources/data/content/de/faq.json index 724cb77e..6b0d142b 100644 --- a/resources/data/content/de/faq.json +++ b/resources/data/content/de/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Gibt es eine Version für Windows oder Linux?", + "question": "Gibt es eine Linux-Version?", "answer": [ - "Nein. Es gibt keine Windows-Version. Ein Linux-Prototyp existiert, aber es gibt nichts zum Installieren und keinen Erscheinungstermin." + "Die Linux-App ist als Beta verfügbar. Pakete und Anleitungen findest du auf der Downloadseite." ] }, { diff --git a/resources/data/content/de/home.json b/resources/data/content/de/home.json index 2855c1fa..6b8c2609 100644 --- a/resources/data/content/de/home.json +++ b/resources/data/content/de/home.json @@ -9,7 +9,7 @@ "title": "Ein nativer Datenbankclient." }, "hero": { - "title": "Ein nativer Datenbankclient.", + "title": "Ein nativer Datenbankclient für {devices}.", "subtitle": "Führe Abfragen aus, durchsuche und bearbeite Daten in {featuredEngines} und weiteren Systemen.", "native": "Native Oberflächen statt Electron oder Java-Laufzeitumgebung.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro für {devices}", "mac": "Die Desktop-App mit separaten Builds für {architectures}. Mit SQL-Editor, Schemawerkzeugen, KI-Assistent und MCP-Server.", "ios": "Führe Abfragen aus und arbeite mit unterstützten Tabellen auf {devices}. Eine separate kostenlose App mit SSH-Tunneln und optionaler Face-ID-Sperre.", - "sync": "iCloud Sync teilt Verbindungen, Gruppen und Tags zwischen Apple-Geräten. Standardmäßig aus; auf dem Mac ist {tier} erforderlich." + "sync": "iCloud Sync teilt Verbindungen, Gruppen und Tags zwischen Apple-Geräten. Standardmäßig aus; auf dem Mac ist {tier} erforderlich.", + "linux": "Eine Linux-Beta mit SQL-Editor und Datentabelle." }, "switch": { "title": "Deine Verbindungen übernehmen", diff --git a/resources/data/content/de/linux.json b/resources/data/content/de/linux.json new file mode 100644 index 00000000..a8a1b51b --- /dev/null +++ b/resources/data/content/de/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro für Linux", + "description": "Eine Linux-Beta mit SQL-Editor und Datentabelle." + }, + "hero": { + "title": "TablePro für Linux", + "lead": "Eine Linux-Beta mit SQL-Editor und Datentabelle." + }, + "install": { + "title": "Beta installieren", + "label": "Befehle für {system}", + "lead": "Pakete für {architectures}. Aktiviere das stabile und das Beta-Repository, um Updates über apt oder dnf zu erhalten.", + "stable": { + "title": "Stabile Versionen", + "body": "Aktiviere nur das stabile Repository, wenn du nur stabile Versionen möchtest. Beta-Tags veröffentlichen nur in den Beta-Repositories; stabile Tags nur in den stabilen." + }, + "releases": { + "title": "Pakete auf GitHub", + "body": "Lade .deb-, .rpm- und .flatpak-Dateien von GitHub Releases herunter. Installiere die nächste Datei zum Aktualisieren." + }, + "guide": { + "label": "Linux-Installationsanleitung lesen", + "path": "/linux/install" + } + }, + "databases": { + "title": "Datenbanken", + "lead": "Diese Treiber sind in der Linux-App enthalten." + } +} diff --git a/resources/data/content/de/pricing.json b/resources/data/content/de/pricing.json index 4dcf7a04..7782c2fb 100644 --- a/resources/data/content/de/pricing.json +++ b/resources/data/content/de/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Wo ist mein Lizenzschlüssel?", "answer": "Du brauchst keinen mehr: Melde dich mit deiner Kauf-E-Mail an. Versionen vor den TablePro-Konten nehmen den Schlüssel aus dieser E-Mail und laufen {graceDays} Tage offline." + }, + "linux": { + "question": "Funktionieren die kostenpflichtigen Funktionen unter Linux?", + "answer": "Die kostenpflichtigen Funktionen in der Tabelle oben gibt es vorerst nur auf dem Mac, spätere Versionen bringen sie auf Linux. Eine Lizenz gilt für alle Plattformen." } } }, diff --git a/resources/data/content/en/download.json b/resources/data/content/en/download.json index e23f265c..120718d6 100644 --- a/resources/data/content/en/download.json +++ b/resources/data/content/en/download.json @@ -59,5 +59,10 @@ "body": "Every release, with its notes and disk images, is on GitHub Releases. The changelog lists what changed in each version.", "releases": "All releases on GitHub", "changelog": "Changelog" + }, + "linux": { + "title": "TablePro for Linux", + "body": "A Linux beta with a SQL editor and data grid.", + "link": "Read the Linux install guide" } } diff --git a/resources/data/content/en/faq.json b/resources/data/content/en/faq.json index 45d610c3..10692ec7 100644 --- a/resources/data/content/en/faq.json +++ b/resources/data/content/en/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Is there a version for Windows or Linux?", + "question": "Is there a Linux version?", "answer": [ - "No. There is no Windows version. A Linux prototype exists, but there is nothing to install and no release date." + "The Linux app is in beta. See the download page for packages and installation instructions." ] }, { diff --git a/resources/data/content/en/home.json b/resources/data/content/en/home.json index 8d9bbbc4..1910de1a 100644 --- a/resources/data/content/en/home.json +++ b/resources/data/content/en/home.json @@ -9,7 +9,7 @@ "title": "A native database client." }, "hero": { - "title": "A native database client.", + "title": "A native database client for {devices}.", "subtitle": "Run queries, browse and edit data in {featuredEngines} and more.", "native": "Built with native interfaces, not Electron or a Java runtime.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro for {devices}", "mac": "The desktop app, with separate builds for {architectures}. Includes the SQL editor, schema tools, AI assistant and MCP server.", "ios": "Run queries and work with supported tables on {devices}. A separate, free app with SSH tunnels and an optional Face ID lock.", - "sync": "iCloud Sync shares connections, groups and tags across Apple devices. It is off by default and requires {tier} on the Mac." + "sync": "iCloud Sync shares connections, groups and tags across Apple devices. It is off by default and requires {tier} on the Mac.", + "linux": "A Linux beta with a SQL editor and data grid." }, "switch": { "title": "Bring your connections", diff --git a/resources/data/content/en/linux.json b/resources/data/content/en/linux.json new file mode 100644 index 00000000..36bc086a --- /dev/null +++ b/resources/data/content/en/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro for Linux", + "description": "A Linux beta with a SQL editor and data grid." + }, + "hero": { + "title": "TablePro for Linux", + "lead": "A Linux beta with a SQL editor and data grid." + }, + "install": { + "title": "Install the beta", + "label": "Commands for {system}", + "lead": "Packages for {architectures}. Enable both the stable and beta repositories to receive updates through apt or dnf.", + "stable": { + "title": "Stable releases", + "body": "For stable releases only, enable the stable repository. Beta tags publish only to the beta repositories; stable tags publish only to the stable ones." + }, + "releases": { + "title": "Packages on GitHub", + "body": "Get .deb, .rpm and .flatpak files from GitHub Releases. Install the next file to update." + }, + "guide": { + "label": "Read the Linux install guide", + "path": "/linux/install" + } + }, + "databases": { + "title": "Databases", + "lead": "These drivers are included in the Linux app." + } +} diff --git a/resources/data/content/en/pricing.json b/resources/data/content/en/pricing.json index 0aae35f4..c2b973ee 100644 --- a/resources/data/content/en/pricing.json +++ b/resources/data/content/en/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Where is my license key?", "answer": "You no longer need one: sign in with your purchase email. Versions before TablePro accounts take the key from that email and work {graceDays} days offline." + }, + "linux": { + "question": "Do paid features work on Linux?", + "answer": "The paid features in the table above are Mac only for now and come to Linux in later releases. One license covers every platform." } } }, diff --git a/resources/data/content/es/download.json b/resources/data/content/es/download.json index 249d6c44..2d641304 100644 --- a/resources/data/content/es/download.json +++ b/resources/data/content/es/download.json @@ -59,5 +59,10 @@ "body": "Todas las versiones, con sus notas e imágenes de disco, están en GitHub Releases. El historial de cambios enumera las novedades de cada versión.", "releases": "Todas las versiones en GitHub", "changelog": "Historial de cambios (inglés)" + }, + "linux": { + "title": "TablePro para Linux", + "body": "Una beta para Linux con editor SQL y cuadrícula de datos.", + "link": "Leer la guía de instalación en Linux" } } diff --git a/resources/data/content/es/faq.json b/resources/data/content/es/faq.json index 227a1aac..4f367862 100644 --- a/resources/data/content/es/faq.json +++ b/resources/data/content/es/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "¿Hay una versión para Windows o Linux?", + "question": "¿Hay una versión para Linux?", "answer": [ - "No. No hay versión para Windows. Existe un prototipo para Linux, pero no hay nada que instalar ni fecha de lanzamiento." + "La aplicación para Linux está en beta. Consulta los paquetes y las instrucciones en la página de descargas." ] }, { diff --git a/resources/data/content/es/home.json b/resources/data/content/es/home.json index e311239e..5401f39d 100644 --- a/resources/data/content/es/home.json +++ b/resources/data/content/es/home.json @@ -9,7 +9,7 @@ "title": "Un cliente nativo de bases de datos." }, "hero": { - "title": "Un cliente nativo de bases de datos.", + "title": "Un cliente de bases de datos nativo para {devices}.", "subtitle": "Ejecuta consultas, explora y edita datos en {featuredEngines} y más.", "native": "Interfaces nativas, sin Electron ni entorno Java.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro para {devices}", "mac": "La app de escritorio, con versiones independientes para {architectures}. Incluye editor SQL, herramientas de esquemas, asistente de IA y servidor MCP.", "ios": "Ejecuta consultas y trabaja con tablas compatibles en {devices}. Una app gratuita e independiente, con túneles SSH y bloqueo opcional con Face ID.", - "sync": "iCloud Sync comparte conexiones, grupos y etiquetas entre dispositivos Apple. Está desactivado por defecto y requiere {tier} en el Mac." + "sync": "iCloud Sync comparte conexiones, grupos y etiquetas entre dispositivos Apple. Está desactivado por defecto y requiere {tier} en el Mac.", + "linux": "Una beta para Linux con editor SQL y cuadrícula de datos." }, "switch": { "title": "Trae tus conexiones", diff --git a/resources/data/content/es/linux.json b/resources/data/content/es/linux.json new file mode 100644 index 00000000..834d6d75 --- /dev/null +++ b/resources/data/content/es/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro para Linux", + "description": "Una beta para Linux con editor SQL y cuadrícula de datos." + }, + "hero": { + "title": "TablePro para Linux", + "lead": "Una beta para Linux con editor SQL y cuadrícula de datos." + }, + "install": { + "title": "Instalar la beta", + "label": "Comandos para {system}", + "lead": "Paquetes para {architectures}. Activa los repositorios estable y beta para recibir actualizaciones mediante apt o dnf.", + "stable": { + "title": "Versiones estables", + "body": "Para recibir solo versiones estables, activa el repositorio estable. Las etiquetas beta publican solo en los repositorios beta; las estables, solo en los estables." + }, + "releases": { + "title": "Paquetes en GitHub", + "body": "Descarga archivos .deb, .rpm y .flatpak de GitHub Releases. Instala el siguiente archivo para actualizar." + }, + "guide": { + "label": "Leer la guía de instalación en Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Bases de datos", + "lead": "Estos controladores están incluidos en la aplicación para Linux." + } +} diff --git a/resources/data/content/es/pricing.json b/resources/data/content/es/pricing.json index 0449ae49..c428ae6b 100644 --- a/resources/data/content/es/pricing.json +++ b/resources/data/content/es/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "¿Dónde está mi clave de licencia?", "answer": "Ya no la necesitas: inicia sesión con tu correo de compra. Las versiones anteriores a las cuentas de TablePro toman la clave de ese correo y funcionan {graceDays} días sin conexión." + }, + "linux": { + "question": "¿Las funciones de pago funcionan en Linux?", + "answer": "Las funciones de pago de la tabla de arriba son solo para Mac por ahora y llegarán a Linux en próximas versiones. Una licencia sirve en todas las plataformas." } } }, diff --git a/resources/data/content/fr/download.json b/resources/data/content/fr/download.json index d9cf9cfa..9b267241 100644 --- a/resources/data/content/fr/download.json +++ b/resources/data/content/fr/download.json @@ -59,5 +59,10 @@ "body": "Chaque version, avec ses notes et ses images disque, figure sur GitHub Releases. Le journal des modifications liste les changements de chaque version.", "releases": "Toutes les versions sur GitHub", "changelog": "Journal des modifications (anglais)" + }, + "linux": { + "title": "TablePro pour Linux", + "body": "Une bêta Linux avec un éditeur SQL et une grille de données.", + "link": "Lire le guide d’installation Linux" } } diff --git a/resources/data/content/fr/faq.json b/resources/data/content/fr/faq.json index 8c821227..c2ce5416 100644 --- a/resources/data/content/fr/faq.json +++ b/resources/data/content/fr/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Existe-t-il une version Windows ou Linux ?", + "question": "Existe-t-il une version Linux ?", "answer": [ - "Non. Il n’y a aucune version Windows. Un prototype Linux existe, mais il n’y a rien à installer et aucune date de sortie." + "L’application Linux est en bêta. Consultez les paquets et les instructions sur la page de téléchargement." ] }, { diff --git a/resources/data/content/fr/home.json b/resources/data/content/fr/home.json index 429e6ff9..a60e0646 100644 --- a/resources/data/content/fr/home.json +++ b/resources/data/content/fr/home.json @@ -9,7 +9,7 @@ "title": "Un client natif de bases de données." }, "hero": { - "title": "Un client natif de bases de données.", + "title": "Un client de bases de données natif pour {devices}.", "subtitle": "Exécutez des requêtes, parcourez et modifiez les données dans {featuredEngines} et d’autres moteurs.", "native": "Des interfaces natives, sans Electron ni environnement Java.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro pour {devices}", "mac": "L’app de bureau, avec des versions distinctes pour {architectures}. Elle inclut l’éditeur SQL, les outils de schéma, l’assistant IA et le serveur MCP.", "ios": "Exécutez des requêtes et travaillez avec les tables compatibles sur {devices}. Une app gratuite distincte, avec tunnels SSH et verrouillage Face ID optionnel.", - "sync": "iCloud Sync partage connexions, groupes et tags entre appareils Apple. Désactivé par défaut, il nécessite {tier} sur Mac." + "sync": "iCloud Sync partage connexions, groupes et tags entre appareils Apple. Désactivé par défaut, il nécessite {tier} sur Mac.", + "linux": "Une bêta Linux avec un éditeur SQL et une grille de données." }, "switch": { "title": "Importez vos connexions", diff --git a/resources/data/content/fr/linux.json b/resources/data/content/fr/linux.json new file mode 100644 index 00000000..89bc202a --- /dev/null +++ b/resources/data/content/fr/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro pour Linux", + "description": "Une bêta Linux avec un éditeur SQL et une grille de données." + }, + "hero": { + "title": "TablePro pour Linux", + "lead": "Une bêta Linux avec un éditeur SQL et une grille de données." + }, + "install": { + "title": "Installer la bêta", + "label": "Commandes pour {system}", + "lead": "Paquets pour {architectures}. Activez les dépôts stable et bêta pour recevoir les mises à jour via apt ou dnf.", + "stable": { + "title": "Versions stables", + "body": "Pour recevoir uniquement les versions stables, activez le dépôt stable. Les tags bêta publient uniquement dans les dépôts bêta ; les tags stables, uniquement dans les dépôts stables." + }, + "releases": { + "title": "Paquets sur GitHub", + "body": "Téléchargez les fichiers .deb, .rpm et .flatpak sur GitHub Releases. Installez le fichier suivant pour mettre à jour." + }, + "guide": { + "label": "Lire le guide d’installation Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Bases de données", + "lead": "Ces pilotes sont inclus dans l’application Linux." + } +} diff --git a/resources/data/content/fr/pricing.json b/resources/data/content/fr/pricing.json index ac3961f1..e5783735 100644 --- a/resources/data/content/fr/pricing.json +++ b/resources/data/content/fr/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Où est ma clé de licence ?", "answer": "Vous n’en avez plus besoin : connectez-vous avec votre e-mail d’achat. Les versions antérieures aux comptes TablePro prennent la clé dans cet e-mail et fonctionnent {graceDays} jours hors ligne." + }, + "linux": { + "question": "Les fonctions payantes fonctionnent-elles sur Linux ?", + "answer": "Les fonctions payantes du tableau ci-dessus sont réservées au Mac pour l’instant et arriveront sur Linux dans de prochaines versions. Une licence couvre toutes les plateformes." } } }, diff --git a/resources/data/content/id/download.json b/resources/data/content/id/download.json index d6996966..b745d97b 100644 --- a/resources/data/content/id/download.json +++ b/resources/data/content/id/download.json @@ -59,5 +59,10 @@ "body": "Setiap rilis beserta catatan dan disk image-nya tersedia di GitHub Releases. Catatan perubahan mencantumkan perubahan dalam setiap versi.", "releases": "Semua rilis di GitHub", "changelog": "Catatan perubahan (bahasa Inggris)" + }, + "linux": { + "title": "TablePro untuk Linux", + "body": "Versi beta Linux dengan editor SQL dan grid data.", + "link": "Baca panduan instalasi Linux" } } diff --git a/resources/data/content/id/faq.json b/resources/data/content/id/faq.json index ca609742..517a8076 100644 --- a/resources/data/content/id/faq.json +++ b/resources/data/content/id/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Apakah ada versi Windows atau Linux?", + "question": "Apakah ada versi Linux?", "answer": [ - "Tidak. Tidak ada versi Windows. Prototipe Linux ada, tetapi tidak ada yang dapat diinstal dan tidak ada tanggal rilis." + "Aplikasi Linux tersedia dalam versi beta. Lihat paket dan petunjuk instalasi di halaman unduhan." ] }, { diff --git a/resources/data/content/id/home.json b/resources/data/content/id/home.json index c9a7b8a1..4755a77d 100644 --- a/resources/data/content/id/home.json +++ b/resources/data/content/id/home.json @@ -9,7 +9,7 @@ "title": "Klien database native." }, "hero": { - "title": "Klien database native.", + "title": "Klien database native untuk {devices}.", "subtitle": "Jalankan kueri, telusuri dan edit data di {featuredEngines} dan lainnya.", "native": "Antarmuka native, tanpa Electron atau runtime Java.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro untuk {devices}", "mac": "Aplikasi desktop, dengan build terpisah untuk {architectures}. Termasuk editor SQL, alat skema, asisten AI, dan server MCP.", "ios": "Jalankan kueri dan bekerja dengan tabel yang didukung di {devices}. Aplikasi gratis terpisah dengan terowongan SSH dan kunci Face ID opsional.", - "sync": "iCloud Sync berbagi koneksi, grup, dan tag di seluruh perangkat Apple. Ini dinonaktifkan secara default dan memerlukan {tier} di Mac." + "sync": "iCloud Sync berbagi koneksi, grup, dan tag di seluruh perangkat Apple. Ini dinonaktifkan secara default dan memerlukan {tier} di Mac.", + "linux": "Versi beta Linux dengan editor SQL dan grid data." }, "switch": { "title": "Bawa koneksi Anda", diff --git a/resources/data/content/id/linux.json b/resources/data/content/id/linux.json new file mode 100644 index 00000000..43c3e65f --- /dev/null +++ b/resources/data/content/id/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro untuk Linux", + "description": "Versi beta Linux dengan editor SQL dan grid data." + }, + "hero": { + "title": "TablePro untuk Linux", + "lead": "Versi beta Linux dengan editor SQL dan grid data." + }, + "install": { + "title": "Instal versi beta", + "label": "Perintah untuk {system}", + "lead": "Paket untuk {architectures}. Aktifkan repositori stabil dan beta untuk menerima pembaruan melalui apt atau dnf.", + "stable": { + "title": "Rilis stabil", + "body": "Untuk menerima rilis stabil saja, aktifkan repositori stabil. Tag beta hanya diterbitkan ke repositori beta; tag stabil hanya ke repositori stabil." + }, + "releases": { + "title": "Paket di GitHub", + "body": "Unduh file .deb, .rpm, dan .flatpak dari GitHub Releases. Instal file versi berikutnya untuk memperbarui." + }, + "guide": { + "label": "Baca panduan instalasi Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Database", + "lead": "Driver ini disertakan dalam aplikasi Linux." + } +} diff --git a/resources/data/content/id/pricing.json b/resources/data/content/id/pricing.json index 5ca129aa..ba659edc 100644 --- a/resources/data/content/id/pricing.json +++ b/resources/data/content/id/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Di mana kunci lisensi saya?", "answer": "Anda tidak memerlukannya lagi: masuk dengan email pembelian Anda. Versi sebelum akun TablePro mengambil kunci dari email itu dan berfungsi {graceDays} hari offline." + }, + "linux": { + "question": "Apakah fitur berbayar berfungsi di Linux?", + "answer": "Fitur berbayar pada tabel di atas untuk sementara hanya ada di Mac dan akan hadir di Linux pada rilis berikutnya. Satu lisensi mencakup semua platform." } } }, diff --git a/resources/data/content/it/download.json b/resources/data/content/it/download.json index 72ef8042..52e35f40 100644 --- a/resources/data/content/it/download.json +++ b/resources/data/content/it/download.json @@ -59,5 +59,10 @@ "body": "Ogni rilascio, con le note e le immagini disco, si trova su GitHub Releases. Il registro delle modifiche elenca le novità di ogni versione.", "releases": "Tutti i rilasci su GitHub", "changelog": "Registro delle modifiche (inglese)" + }, + "linux": { + "title": "TablePro per Linux", + "body": "Una beta per Linux con editor SQL e griglia dati.", + "link": "Leggi la guida di installazione Linux" } } diff --git a/resources/data/content/it/faq.json b/resources/data/content/it/faq.json index bb4aab9d..5f8d3790 100644 --- a/resources/data/content/it/faq.json +++ b/resources/data/content/it/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Esiste una versione per Windows o Linux?", + "question": "Esiste una versione per Linux?", "answer": [ - "No. Non esiste una versione Windows. Esiste un prototipo Linux, ma non c’è nulla da installare né una data di rilascio." + "L’app Linux è in beta. Consulta i pacchetti e le istruzioni nella pagina di download." ] }, { diff --git a/resources/data/content/it/home.json b/resources/data/content/it/home.json index cb299f16..5061f8ea 100644 --- a/resources/data/content/it/home.json +++ b/resources/data/content/it/home.json @@ -9,7 +9,7 @@ "title": "Un client database nativo." }, "hero": { - "title": "Un client database nativo.", + "title": "Un client database nativo per {devices}.", "subtitle": "Esegui query, esplora e modifica dati in {featuredEngines} e altri database.", "native": "Interfacce native, senza Electron né runtime Java.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro per {devices}", "mac": "L'app desktop, con build separate per {architectures}. Include l'editor SQL, gli strumenti dello schema, l'assistente IA e il server MCP.", "ios": "Esegui query e lavora con le tabelle supportate su {devices}. Un'app separata e gratuita con tunnel SSH e un blocco Face ID opzionale.", - "sync": "iCloud Sync condivide connessioni, gruppi e tag tra i dispositivi Apple. È disattivato per imposto predefinita e richiede {tier} su Mac." + "sync": "iCloud Sync condivide connessioni, gruppi e tag tra i dispositivi Apple. È disattivato per imposto predefinita e richiede {tier} su Mac.", + "linux": "Una beta per Linux con editor SQL e griglia dati." }, "switch": { "title": "Porta le tue connessioni", diff --git a/resources/data/content/it/linux.json b/resources/data/content/it/linux.json new file mode 100644 index 00000000..95aa983a --- /dev/null +++ b/resources/data/content/it/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro per Linux", + "description": "Una beta per Linux con editor SQL e griglia dati." + }, + "hero": { + "title": "TablePro per Linux", + "lead": "Una beta per Linux con editor SQL e griglia dati." + }, + "install": { + "title": "Installa la beta", + "label": "Comandi per {system}", + "lead": "Pacchetti per {architectures}. Abilita i repository stabile e beta per ricevere aggiornamenti tramite apt o dnf.", + "stable": { + "title": "Versioni stabili", + "body": "Per ricevere solo versioni stabili, abilita il repository stabile. I tag beta pubblicano solo nei repository beta; i tag stabili solo in quelli stabili." + }, + "releases": { + "title": "Pacchetti su GitHub", + "body": "Scarica i file .deb, .rpm e .flatpak da GitHub Releases. Installa il file successivo per aggiornare." + }, + "guide": { + "label": "Leggi la guida di installazione Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Database", + "lead": "Questi driver sono inclusi nell’app Linux." + } +} diff --git a/resources/data/content/it/pricing.json b/resources/data/content/it/pricing.json index c33bec7a..690da5ab 100644 --- a/resources/data/content/it/pricing.json +++ b/resources/data/content/it/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Dov’è la mia chiave di licenza?", "answer": "Non ti serve più: accedi con l’e-mail di acquisto. Le versioni precedenti agli account TablePro prendono la chiave da quell’e-mail e funzionano {graceDays} giorni offline." + }, + "linux": { + "question": "Le funzioni a pagamento funzionano su Linux?", + "answer": "Le funzioni a pagamento nella tabella qui sopra per ora sono solo per Mac e arriveranno su Linux nelle prossime versioni. Una licenza vale per tutte le piattaforme." } } }, diff --git a/resources/data/content/ja/download.json b/resources/data/content/ja/download.json index 2127901d..4e75eb1e 100644 --- a/resources/data/content/ja/download.json +++ b/resources/data/content/ja/download.json @@ -59,5 +59,10 @@ "body": "すべてのリリースのノートとディスクイメージは GitHub Releases にあります。各バージョンの変更内容は変更履歴で確認できます。", "releases": "GitHub の全リリース", "changelog": "変更履歴(英語)" + }, + "linux": { + "title": "Linux 向け TablePro", + "body": "SQL エディターとデータグリッドを備えた Linux ベータ版。", + "link": "Linux インストールガイドを読む" } } diff --git a/resources/data/content/ja/faq.json b/resources/data/content/ja/faq.json index f478554f..da4729c7 100644 --- a/resources/data/content/ja/faq.json +++ b/resources/data/content/ja/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Windows や Linux 版はありますか?", + "question": "Linux 版はありますか?", "answer": [ - "いいえ。Windows 版はありません。Linux のプロトタイプはありますが、インストールできるものはなく、リリース日の予定もありません。" + "Linux アプリはベータ版です。パッケージとインストール手順は ダウンロードページ をご覧ください。" ] }, { diff --git a/resources/data/content/ja/home.json b/resources/data/content/ja/home.json index 35671b6c..a7ce70d7 100644 --- a/resources/data/content/ja/home.json +++ b/resources/data/content/ja/home.json @@ -9,7 +9,7 @@ "title": "ネイティブのデータベースクライアント。" }, "hero": { - "title": "ネイティブのデータベースクライアント。", + "title": "{devices} 向けのネイティブデータベースクライアント。", "subtitle": "{featuredEngines} などのデータベースでクエリを実行し、データを閲覧・編集できます。", "native": "Electron や Java ランタイムではなく、ネイティブのインターフェースで構築しています。", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "{devices} 版 TablePro", "mac": "{architectures} 向けに別々のビルドを提供するデスクトップアプリです。SQL エディター、スキーマツール、AI アシスタント、MCP サーバーを含みます。", "ios": "{devices} でクエリを実行し、対応テーブルを操作できます。SSH トンネルと任意の Face ID ロックを備えた、別の無料アプリです。", - "sync": "iCloud Sync は Apple デバイス間で接続、グループ、タグを共有します。初期状態では無効で、Mac では {tier} が必要です。" + "sync": "iCloud Sync は Apple デバイス間で接続、グループ、タグを共有します。初期状態では無効で、Mac では {tier} が必要です。", + "linux": "SQL エディターとデータグリッドを備えた Linux ベータ版。" }, "switch": { "title": "接続を移行", diff --git a/resources/data/content/ja/linux.json b/resources/data/content/ja/linux.json new file mode 100644 index 00000000..30336fe4 --- /dev/null +++ b/resources/data/content/ja/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "Linux 向け TablePro", + "description": "SQL エディターとデータグリッドを備えた Linux ベータ版。" + }, + "hero": { + "title": "Linux 向け TablePro", + "lead": "SQL エディターとデータグリッドを備えた Linux ベータ版。" + }, + "install": { + "title": "ベータ版をインストール", + "label": "{system} 用のコマンド", + "lead": "{architectures} 用のパッケージ。安定版とベータ版の両方のリポジトリを有効にすると、apt または dnf で更新できます。", + "stable": { + "title": "安定版", + "body": "安定版のみを使う場合は安定版リポジトリを有効にしてください。ベータ版のタグはベータ版リポジトリに、安定版のタグは安定版リポジトリにのみ公開されます。" + }, + "releases": { + "title": "GitHub のパッケージ", + "body": "GitHub Releases から .deb、.rpm、.flatpak ファイルを取得してください。更新には次のファイルをインストールします。" + }, + "guide": { + "label": "Linux インストールガイドを読む", + "path": "/linux/install" + } + }, + "databases": { + "title": "データベース", + "lead": "これらのドライバーは Linux アプリに含まれています。" + } +} diff --git a/resources/data/content/ja/pricing.json b/resources/data/content/ja/pricing.json index 7e7460e6..d3aaae68 100644 --- a/resources/data/content/ja/pricing.json +++ b/resources/data/content/ja/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "ライセンスキーはどこにありますか?", "answer": "もう必要ありません。購入時のメールアドレスでログインしてください。TablePro アカウントに対応する前のバージョンは、そのメールのキーを使い、オフラインで {graceDays} 日間動作します。" + }, + "linux": { + "question": "有料機能は Linux で使えますか?", + "answer": "上の表の有料機能は現在 Mac のみで、今後のリリースで Linux にも対応します。1 つのライセンスですべてのプラットフォームに使えます。" } } }, diff --git a/resources/data/content/ko/download.json b/resources/data/content/ko/download.json index 500089da..8d0aadf3 100644 --- a/resources/data/content/ko/download.json +++ b/resources/data/content/ko/download.json @@ -59,5 +59,10 @@ "body": "모든 릴리스의 노트와 디스크 이미지는 GitHub Releases에 있습니다. 변경 기록에는 각 버전의 변경 사항이 나와 있습니다.", "releases": "GitHub의 모든 릴리스", "changelog": "변경 기록 (영어)" + }, + "linux": { + "title": "Linux용 TablePro", + "body": "SQL 편집기와 데이터 그리드를 갖춘 Linux 베타 버전.", + "link": "Linux 설치 가이드 읽기" } } diff --git a/resources/data/content/ko/faq.json b/resources/data/content/ko/faq.json index cc648e2f..1d09afe8 100644 --- a/resources/data/content/ko/faq.json +++ b/resources/data/content/ko/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Windows 또는 Linux 버전이 있나요?", + "question": "Linux 버전이 있나요?", "answer": [ - "아니요. Windows 버전은 없습니다. Linux 프로토타입은 있지만 설치 가능한 버전과 출시 일정은 없습니다." + "Linux 앱은 베타 버전입니다. 패키지와 설치 방법은 다운로드 페이지를 확인하세요." ] }, { diff --git a/resources/data/content/ko/home.json b/resources/data/content/ko/home.json index 71c548dd..00aeaaaa 100644 --- a/resources/data/content/ko/home.json +++ b/resources/data/content/ko/home.json @@ -9,7 +9,7 @@ "title": "네이티브 데이터베이스 클라이언트." }, "hero": { - "title": "네이티브 데이터베이스 클라이언트.", + "title": "{devices}용 네이티브 데이터베이스 클라이언트.", "subtitle": "{featuredEngines} 등의 데이터베이스에서 쿼리를 실행하고 데이터를 탐색하고 편집하세요.", "native": "Electron이나 Java 런타임 대신 네이티브 인터페이스로 만들었습니다.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "{devices}용 TablePro", "mac": "{architectures}용 빌드를 각각 제공하는 데스크톱 앱입니다. SQL 편집기, 스키마 도구, AI 도우미, MCP 서버가 포함됩니다.", "ios": "{devices}에서 쿼리를 실행하고 지원되는 테이블을 다루세요. SSH 터널과 선택적인 Face ID 잠금을 제공하는 별도의 무료 앱입니다.", - "sync": "iCloud Sync는 Apple 기기 간에 연결, 그룹, 태그를 공유합니다. 기본적으로 꺼져 있으며 Mac에서는 {tier}이 필요합니다." + "sync": "iCloud Sync는 Apple 기기 간에 연결, 그룹, 태그를 공유합니다. 기본적으로 꺼져 있으며 Mac에서는 {tier}이 필요합니다.", + "linux": "SQL 편집기와 데이터 그리드를 갖춘 Linux 베타 버전." }, "switch": { "title": "연결 가져오기", diff --git a/resources/data/content/ko/linux.json b/resources/data/content/ko/linux.json new file mode 100644 index 00000000..55b6ca24 --- /dev/null +++ b/resources/data/content/ko/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "Linux용 TablePro", + "description": "SQL 편집기와 데이터 그리드를 갖춘 Linux 베타 버전." + }, + "hero": { + "title": "Linux용 TablePro", + "lead": "SQL 편집기와 데이터 그리드를 갖춘 Linux 베타 버전." + }, + "install": { + "title": "베타 설치", + "label": "{system} 명령어", + "lead": "{architectures}용 패키지입니다. 안정 버전과 베타 저장소를 모두 활성화하면 apt 또는 dnf로 업데이트를 받을 수 있습니다.", + "stable": { + "title": "안정 버전", + "body": "안정 버전만 받으려면 안정 버전 저장소를 활성화하세요. 베타 태그는 베타 저장소에만, 안정 버전 태그는 안정 버전 저장소에만 게시됩니다." + }, + "releases": { + "title": "GitHub 패키지", + "body": "GitHub Releases에서 .deb, .rpm, .flatpak 파일을 받으세요. 다음 버전 파일을 설치하여 업데이트하세요." + }, + "guide": { + "label": "Linux 설치 가이드 읽기", + "path": "/linux/install" + } + }, + "databases": { + "title": "데이터베이스", + "lead": "이 드라이버는 Linux 앱에 포함되어 있습니다." + } +} diff --git a/resources/data/content/ko/pricing.json b/resources/data/content/ko/pricing.json index 689d61d1..6ea53629 100644 --- a/resources/data/content/ko/pricing.json +++ b/resources/data/content/ko/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "라이선스 키는 어디에 있나요?", "answer": "더 이상 필요하지 않습니다. 구매 이메일로 로그인하세요. TablePro 계정을 지원하기 전 버전은 그 이메일의 키를 사용하며 오프라인에서 {graceDays}일 동안 작동합니다." + }, + "linux": { + "question": "유료 기능을 Linux에서 사용할 수 있나요?", + "answer": "위 표의 유료 기능은 현재 Mac에서만 사용할 수 있으며, 이후 릴리스에서 Linux에도 제공됩니다. 라이선스 하나로 모든 플랫폼에서 사용할 수 있습니다." } } }, diff --git a/resources/data/content/pt-BR/download.json b/resources/data/content/pt-BR/download.json index d865bf29..285aa180 100644 --- a/resources/data/content/pt-BR/download.json +++ b/resources/data/content/pt-BR/download.json @@ -59,5 +59,10 @@ "body": "Todas as versões, com suas notas e imagens de disco, estão no GitHub Releases. O histórico de alterações lista o que mudou em cada versão.", "releases": "Todas as versões no GitHub", "changelog": "Histórico de alterações (inglês)" + }, + "linux": { + "title": "TablePro para Linux", + "body": "Uma versão beta para Linux com editor SQL e grade de dados.", + "link": "Ler o guia de instalação no Linux" } } diff --git a/resources/data/content/pt-BR/faq.json b/resources/data/content/pt-BR/faq.json index 56917a5b..105b8a03 100644 --- a/resources/data/content/pt-BR/faq.json +++ b/resources/data/content/pt-BR/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Existe uma versão para Windows ou Linux?", + "question": "Existe uma versão para Linux?", "answer": [ - "Não. Não há versão para Windows. Existe um protótipo para Linux, mas não há nada para instalar nem data de lançamento." + "O aplicativo Linux está em beta. Veja os pacotes e as instruções na página de download." ] }, { diff --git a/resources/data/content/pt-BR/home.json b/resources/data/content/pt-BR/home.json index 785a3d13..e46201fd 100644 --- a/resources/data/content/pt-BR/home.json +++ b/resources/data/content/pt-BR/home.json @@ -9,7 +9,7 @@ "title": "Um cliente de banco de dados nativo." }, "hero": { - "title": "Um cliente de banco de dados nativo.", + "title": "Um cliente de banco de dados nativo para {devices}.", "subtitle": "Execute consultas, explore e edite dados em {featuredEngines} e outros bancos.", "native": "Interfaces nativas, sem Electron nem runtime Java.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro para {devices}", "mac": "O aplicativo de desktop, com versões separadas para {architectures}. Inclui o editor SQL, ferramentas de esquema, assistente AI e servidor MCP.", "ios": "Execute consultas e trabalhe com tabelas suportadas em {devices}. Um aplicativo gratuito separado com túneis SSH e um bloqueio de Face ID opcional.", - "sync": "iCloud Sync compartilha conexões, grupos e tags entre dispositivos Apple. Está desativado por padrão e requer {tier} no Mac." + "sync": "iCloud Sync compartilha conexões, grupos e tags entre dispositivos Apple. Está desativado por padrão e requer {tier} no Mac.", + "linux": "Uma versão beta para Linux com editor SQL e grade de dados." }, "switch": { "title": "Traga suas conexões", diff --git a/resources/data/content/pt-BR/linux.json b/resources/data/content/pt-BR/linux.json new file mode 100644 index 00000000..13d90a9d --- /dev/null +++ b/resources/data/content/pt-BR/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro para Linux", + "description": "Uma versão beta para Linux com editor SQL e grade de dados." + }, + "hero": { + "title": "TablePro para Linux", + "lead": "Uma versão beta para Linux com editor SQL e grade de dados." + }, + "install": { + "title": "Instalar a versão beta", + "label": "Comandos para {system}", + "lead": "Pacotes para {architectures}. Ative os repositórios estável e beta para receber atualizações pelo apt ou dnf.", + "stable": { + "title": "Versões estáveis", + "body": "Para receber apenas versões estáveis, ative o repositório estável. Tags beta publicam apenas nos repositórios beta; tags estáveis, apenas nos estáveis." + }, + "releases": { + "title": "Pacotes no GitHub", + "body": "Baixe arquivos .deb, .rpm e .flatpak em GitHub Releases. Instale o próximo arquivo para atualizar." + }, + "guide": { + "label": "Ler o guia de instalação no Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Bancos de dados", + "lead": "Estes drivers estão incluídos no aplicativo Linux." + } +} diff --git a/resources/data/content/pt-BR/pricing.json b/resources/data/content/pt-BR/pricing.json index 8ee2a061..4a38b3dd 100644 --- a/resources/data/content/pt-BR/pricing.json +++ b/resources/data/content/pt-BR/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "Onde está minha chave de licença?", "answer": "Você não precisa mais dela: entre com o e-mail da compra. As versões anteriores às contas TablePro usam a chave desse e-mail e funcionam {graceDays} dias offline." + }, + "linux": { + "question": "Os recursos pagos funcionam no Linux?", + "answer": "Os recursos pagos da tabela acima são só para Mac por enquanto e chegam ao Linux em versões futuras. Uma licença vale para todas as plataformas." } } }, diff --git a/resources/data/content/vi/download.json b/resources/data/content/vi/download.json index 9211ea85..e4029039 100644 --- a/resources/data/content/vi/download.json +++ b/resources/data/content/vi/download.json @@ -59,5 +59,10 @@ "body": "Mọi bản phát hành, kèm ghi chú và file DMG, đều có trên GitHub Releases. Changelog liệt kê những gì đã thay đổi trong từng phiên bản.", "releases": "Tất cả bản phát hành trên GitHub", "changelog": "Changelog (tiếng Anh)" + }, + "linux": { + "title": "TablePro cho Linux", + "body": "Bản beta cho Linux với SQL editor và data grid.", + "link": "Đọc hướng dẫn cài đặt Linux" } } diff --git a/resources/data/content/vi/faq.json b/resources/data/content/vi/faq.json index fa9b0788..c778ebf9 100644 --- a/resources/data/content/vi/faq.json +++ b/resources/data/content/vi/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "Có phiên bản cho Windows hoặc Linux không?", + "question": "Có phiên bản Linux không?", "answer": [ - "Không. Không có phiên bản cho Windows. Có một bản prototype cho Linux, nhưng không có gì để cài đặt và không có ngày phát hành." + "Ứng dụng Linux đang ở bản beta. Xem gói cài đặt và hướng dẫn trên trang tải về." ] }, { diff --git a/resources/data/content/vi/home.json b/resources/data/content/vi/home.json index dd2610ce..b71e4a4f 100644 --- a/resources/data/content/vi/home.json +++ b/resources/data/content/vi/home.json @@ -9,7 +9,7 @@ "title": "Database client native." }, "hero": { - "title": "Database client native.", + "title": "Database client native cho {devices}.", "subtitle": "Chạy query, xem và chỉnh sửa dữ liệu trên {featuredEngines} và nhiều cơ sở dữ liệu khác.", "native": "Giao diện native, không dùng Electron hay Java runtime.", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "TablePro cho {devices}", "mac": "Ứng dụng desktop có bản build riêng cho {architectures}, gồm SQL editor, công cụ schema, trợ lý AI và MCP server.", "ios": "Chạy query và làm việc với các table được hỗ trợ trên {devices}. Ứng dụng riêng, miễn phí, có SSH tunnel và khóa Face ID tùy chọn.", - "sync": "iCloud Sync chia sẻ connection, nhóm và tag giữa các thiết bị Apple. Tắt theo mặc định và cần gói {tier} trên Mac." + "sync": "iCloud Sync chia sẻ connection, nhóm và tag giữa các thiết bị Apple. Tắt theo mặc định và cần gói {tier} trên Mac.", + "linux": "Bản beta cho Linux với SQL editor và data grid." }, "switch": { "title": "Chuyển connection sang TablePro", diff --git a/resources/data/content/vi/linux.json b/resources/data/content/vi/linux.json new file mode 100644 index 00000000..de8cf503 --- /dev/null +++ b/resources/data/content/vi/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "TablePro cho Linux", + "description": "Bản beta cho Linux với SQL editor và data grid." + }, + "hero": { + "title": "TablePro cho Linux", + "lead": "Bản beta cho Linux với SQL editor và data grid." + }, + "install": { + "title": "Cài bản beta", + "label": "Lệnh cho {system}", + "lead": "Gói cài đặt cho {architectures}. Bật cả kho stable và beta để nhận cập nhật qua apt hoặc dnf.", + "stable": { + "title": "Bản stable", + "body": "Để chỉ nhận bản stable, bật kho stable. Tag beta chỉ phát hành vào kho beta; tag stable chỉ phát hành vào kho stable." + }, + "releases": { + "title": "Gói cài đặt trên GitHub", + "body": "Tải file .deb, .rpm và .flatpak từ GitHub Releases. Cài file phiên bản tiếp theo để cập nhật." + }, + "guide": { + "label": "Đọc hướng dẫn cài đặt Linux", + "path": "/linux/install" + } + }, + "databases": { + "title": "Database", + "lead": "Các driver này có sẵn trong ứng dụng Linux." + } +} diff --git a/resources/data/content/vi/pricing.json b/resources/data/content/vi/pricing.json index 94fbd737..f38f0723 100644 --- a/resources/data/content/vi/pricing.json +++ b/resources/data/content/vi/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "License key của tôi ở đâu?", "answer": "Bạn không cần key nữa: đăng nhập bằng email đã mua. Các phiên bản trước khi có tài khoản TablePro lấy key từ email đó và hoạt động offline {graceDays} ngày." + }, + "linux": { + "question": "Tính năng trả phí có dùng được trên Linux không?", + "answer": "Các tính năng trả phí trong bảng ở trên hiện chỉ có trên Mac và sẽ có trên Linux ở các phiên bản sau. Một license dùng được trên mọi nền tảng." } } }, diff --git a/resources/data/content/zh-Hans/download.json b/resources/data/content/zh-Hans/download.json index be4a1564..89ed188f 100644 --- a/resources/data/content/zh-Hans/download.json +++ b/resources/data/content/zh-Hans/download.json @@ -59,5 +59,10 @@ "body": "每个版本的说明和磁盘映像均在 GitHub Releases 上。更新日志列出了各版本的改动。", "releases": "GitHub 上的所有版本", "changelog": "更新日志(英语)" + }, + "linux": { + "title": "适用于 Linux 的 TablePro", + "body": "带有 SQL 编辑器和数据网格的 Linux 测试版。", + "link": "阅读 Linux 安装指南" } } diff --git a/resources/data/content/zh-Hans/faq.json b/resources/data/content/zh-Hans/faq.json index d91837b1..8488e3db 100644 --- a/resources/data/content/zh-Hans/faq.json +++ b/resources/data/content/zh-Hans/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "有 Windows 或 Linux 版本吗?", + "question": "有 Linux 版本吗?", "answer": [ - "没有 Windows 版本。Linux 有原型,但没有可安装的版本,也没有发布日期。" + "Linux 应用处于测试阶段。软件包和安装说明请参阅 下载页面。" ] }, { diff --git a/resources/data/content/zh-Hans/home.json b/resources/data/content/zh-Hans/home.json index be9ca2d3..a33a4809 100644 --- a/resources/data/content/zh-Hans/home.json +++ b/resources/data/content/zh-Hans/home.json @@ -9,7 +9,7 @@ "title": "原生数据库客户端。" }, "hero": { - "title": "原生数据库客户端。", + "title": "适用于 {devices} 的原生数据库客户端。", "subtitle": "在 {featuredEngines} 等数据库中运行查询、浏览和编辑数据。", "native": "采用原生界面,不依赖 Electron 或 Java 运行时。", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "{devices} 版 TablePro", "mac": "桌面 App 为 {architectures} 提供独立版本,包含 SQL 编辑器、结构工具、AI 助手和 MCP 服务器。", "ios": "在 {devices} 上运行查询并操作支持的表。这是一款独立的免费 App,支持 SSH 隧道和可选的 Face ID 锁定。", - "sync": "iCloud Sync 在 Apple 设备间共享连接、分组和标签。默认关闭,Mac 上需要 {tier}。" + "sync": "iCloud Sync 在 Apple 设备间共享连接、分组和标签。默认关闭,Mac 上需要 {tier}。", + "linux": "带有 SQL 编辑器和数据网格的 Linux 测试版。" }, "switch": { "title": "迁移连接", diff --git a/resources/data/content/zh-Hans/linux.json b/resources/data/content/zh-Hans/linux.json new file mode 100644 index 00000000..179a94b5 --- /dev/null +++ b/resources/data/content/zh-Hans/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "适用于 Linux 的 TablePro", + "description": "带有 SQL 编辑器和数据网格的 Linux 测试版。" + }, + "hero": { + "title": "适用于 Linux 的 TablePro", + "lead": "带有 SQL 编辑器和数据网格的 Linux 测试版。" + }, + "install": { + "title": "安装测试版", + "label": "{system} 命令", + "lead": "适用于 {architectures} 的软件包。请同时启用稳定版和测试版软件仓库,通过 apt 或 dnf 获取更新。", + "stable": { + "title": "稳定版", + "body": "如只需稳定版,请启用稳定版仓库。测试版标签仅发布到测试版仓库;稳定版标签仅发布到稳定版仓库。" + }, + "releases": { + "title": "GitHub 软件包", + "body": "从 GitHub Releases 获取 .deb、.rpm 和 .flatpak 文件。安装下一个版本的文件即可更新。" + }, + "guide": { + "label": "阅读 Linux 安装指南", + "path": "/linux/install" + } + }, + "databases": { + "title": "数据库", + "lead": "Linux 应用包含这些驱动程序。" + } +} diff --git a/resources/data/content/zh-Hans/pricing.json b/resources/data/content/zh-Hans/pricing.json index 370e9716..d91ae40b 100644 --- a/resources/data/content/zh-Hans/pricing.json +++ b/resources/data/content/zh-Hans/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "许可证密钥在哪里?", "answer": "您不再需要它:用购买邮箱登录即可。支持 TablePro 账户之前的版本使用该邮件中的密钥,可离线使用 {graceDays} 天。" + }, + "linux": { + "question": "付费功能可以在 Linux 上使用吗?", + "answer": "上方表格中的付费功能目前仅限 Mac 使用,后续版本将支持 Linux。一个许可证适用于所有平台。" } } }, diff --git a/resources/data/content/zh-Hant/download.json b/resources/data/content/zh-Hant/download.json index b11eb705..4b8c0695 100644 --- a/resources/data/content/zh-Hant/download.json +++ b/resources/data/content/zh-Hant/download.json @@ -59,5 +59,10 @@ "body": "每個版本的說明與磁碟映像檔均在 GitHub Releases 上。更新紀錄列出了各版本的變更。", "releases": "GitHub 上的所有版本", "changelog": "更新紀錄(英文)" + }, + "linux": { + "title": "適用於 Linux 的 TablePro", + "body": "附有 SQL 編輯器和資料網格的 Linux 測試版。", + "link": "閱讀 Linux 安裝指南" } } diff --git a/resources/data/content/zh-Hant/faq.json b/resources/data/content/zh-Hant/faq.json index 6c54135a..a9df903a 100644 --- a/resources/data/content/zh-Hant/faq.json +++ b/resources/data/content/zh-Hant/faq.json @@ -87,9 +87,9 @@ }, { "id": "windows-linux", - "question": "有 Windows 或 Linux 版本嗎?", + "question": "有 Linux 版本嗎?", "answer": [ - "沒有 Windows 版本。Linux 有原型,但沒有可安裝的版本,也沒有發佈日期。" + "Linux 應用程式目前為測試版。套件和安裝說明請參閱 下載頁面。" ] }, { diff --git a/resources/data/content/zh-Hant/home.json b/resources/data/content/zh-Hant/home.json index 60bb9dda..5d9faadc 100644 --- a/resources/data/content/zh-Hant/home.json +++ b/resources/data/content/zh-Hant/home.json @@ -9,7 +9,7 @@ "title": "原生資料庫用戶端。" }, "hero": { - "title": "原生資料庫用戶端。", + "title": "適用於 {devices} 的原生資料庫用戶端。", "subtitle": "在 {featuredEngines} 等資料庫中執行查詢、瀏覽及編輯資料。", "native": "採用原生介面,不依賴 Electron 或 Java 執行階段。", "macCaption": "{requirement} · {architectures}", @@ -97,7 +97,8 @@ "cardTitle": "{devices} 版 TablePro", "mac": "桌面 App 為 {architectures} 提供獨立版本,包含 SQL 編輯器、結構工具、AI 助手和 MCP 伺服器。", "ios": "在 {devices} 上執行查詢並操作支援的資料表。這是一款獨立的免費 App,支援 SSH 通道和選用的 Face ID 鎖定。", - "sync": "iCloud Sync 在 Apple 裝置間共享連線、群組和標籤。預設關閉,Mac 上需要 {tier}。" + "sync": "iCloud Sync 在 Apple 裝置間共享連線、群組和標籤。預設關閉,Mac 上需要 {tier}。", + "linux": "附有 SQL 編輯器和資料網格的 Linux 測試版。" }, "switch": { "title": "移轉連線", diff --git a/resources/data/content/zh-Hant/linux.json b/resources/data/content/zh-Hant/linux.json new file mode 100644 index 00000000..f01e2445 --- /dev/null +++ b/resources/data/content/zh-Hant/linux.json @@ -0,0 +1,31 @@ +{ + "seo": { + "title": "適用於 Linux 的 TablePro", + "description": "附有 SQL 編輯器和資料網格的 Linux 測試版。" + }, + "hero": { + "title": "適用於 Linux 的 TablePro", + "lead": "附有 SQL 編輯器和資料網格的 Linux 測試版。" + }, + "install": { + "title": "安裝測試版", + "label": "{system} 指令", + "lead": "適用於 {architectures} 的套件。請同時啟用穩定版和測試版套件庫,透過 apt 或 dnf 取得更新。", + "stable": { + "title": "穩定版", + "body": "如只需穩定版,請啟用穩定版套件庫。測試版標籤僅發佈到測試版套件庫;穩定版標籤僅發佈到穩定版套件庫。" + }, + "releases": { + "title": "GitHub 套件", + "body": "從 GitHub Releases 取得 .deb、.rpm 和 .flatpak 檔案。安裝下一個版本的檔案即可更新。" + }, + "guide": { + "label": "閱讀 Linux 安裝指南", + "path": "/linux/install" + } + }, + "databases": { + "title": "資料庫", + "lead": "Linux 應用程式包含這些驅動程式。" + } +} diff --git a/resources/data/content/zh-Hant/pricing.json b/resources/data/content/zh-Hant/pricing.json index dfcffdfd..0b2b5fc9 100644 --- a/resources/data/content/zh-Hant/pricing.json +++ b/resources/data/content/zh-Hant/pricing.json @@ -44,6 +44,10 @@ "lost-key": { "question": "授權金鑰在哪裡?", "answer": "您不再需要它:用購買信箱登入即可。支援 TablePro 帳戶之前的版本使用該郵件中的金鑰,可離線使用 {graceDays} 天。" + }, + "linux": { + "question": "付費功能可以在 Linux 上使用嗎?", + "answer": "上方表格中的付費功能目前僅限 Mac 使用,後續版本將支援 Linux。一個授權適用於所有平台。" } } }, diff --git a/resources/data/platforms.json b/resources/data/platforms.json index 1c614fe2..1a6f9b40 100644 --- a/resources/data/platforms.json +++ b/resources/data/platforms.json @@ -66,7 +66,37 @@ "price": { "amount": 0, "inAppPurchases": false }, "appLanguages": ["en", "vi", "ko", "zh-Hans", "zh-Hant"] }, - { "id": "linux", "status": "prototype" }, + { + "id": "linux", + "status": "beta", + "deviceNames": ["Linux"], + "page": "/linux", + "architectures": ["amd64", "arm64"], + "destinations": [ + { + "kind": "apt", + "system": "Ubuntu", + "versions": ["26.04", "26.10"], + "orLater": false, + "beta": ["sudo add-apt-repository ppa:tablepro/tablepro", "sudo add-apt-repository ppa:tablepro/tablepro-beta", "sudo apt install tablepro"], + "stable": ["sudo add-apt-repository ppa:tablepro/tablepro", "sudo apt install tablepro"] + }, + { + "kind": "dnf", + "system": "Fedora", + "versions": ["44"], + "orLater": true, + "beta": ["sudo dnf copr enable @tablepro/tablepro", "sudo dnf copr enable @tablepro/tablepro-beta", "sudo dnf install tablepro"], + "stable": ["sudo dnf copr enable @tablepro/tablepro", "sudo dnf install tablepro"] + }, + { + "kind": "releases", + "url": "https://github.com/TableProApp/TablePro/releases" + } + ], + "linuxEngines": ["postgresql", "mysql", "mariadb", "sqlserver", "clickhouse", "cassandra", "scylladb", "sqlite", "duckdb", "redis", "mongodb"], + "appLanguages": ["en", "vi"] + }, { "id": "windows", "status": "none" } ] } diff --git a/resources/js/components/download/command-block.tsx b/resources/js/components/download/command-block.tsx index 41e560d3..55a3d11f 100644 --- a/resources/js/components/download/command-block.tsx +++ b/resources/js/components/download/command-block.tsx @@ -2,8 +2,8 @@ import CopyButton from '@/components/ui/copy-button'; import { useI18n } from '@/i18n'; interface CommandBlockProps { - /** The command exactly as it is copied, without a prompt. */ - command: string; + /** The command exactly as it is copied, without a prompt; several run one per line. */ + command: string | readonly string[]; /** The title bar's text, such as "Terminal". */ title: string; /** Names the command for the copy button and the scroll region: "Homebrew command". */ @@ -20,20 +20,23 @@ interface CommandBlockProps { */ export default function CommandBlock({ command, title, label }: CommandBlockProps) { const { m } = useI18n(); + const lines = typeof command === 'string' ? [command] : command; return (
{title} - +
-
-                    
-                    {command}
-                
+ {lines.map((line) => ( +
+                        
+                        {line}
+                    
+ ))}
); diff --git a/resources/js/components/home/hero.tsx b/resources/js/components/home/hero.tsx index e651c2de..921645fe 100644 --- a/resources/js/components/home/hero.tsx +++ b/resources/js/components/home/hero.tsx @@ -2,7 +2,9 @@ import AssetSlot, { useShownSlot } from '@/components/ui/asset-slot'; import Container from '@/components/ui/container'; import LocaleLink from '@/components/ui/locale-link'; import { textLinkClasses } from '@/components/ui/text-link'; -import { Trans } from '@/i18n'; +import { Trans, useI18n } from '@/i18n'; +import { joinList } from '@/i18n/format'; +import { availablePlatforms } from '@/lib/data/platforms'; import type { Availability } from './availability'; import PlatformActions from './platform-actions'; import type { HomeContent } from './types'; @@ -17,13 +19,6 @@ interface HeroProps { /** * Section 1, `#top` (sitemap §D; positioning §3; design-system §8.1). * - * The H1 and subtitle are identity copy: no platform, version or number, so - * they hold when a platform ships. Platforms appear only in the captions under - * the two actions, which are built from platforms.json. "and more" jumps to the - * databases section; "See pricing" to `#pricing`, where shipped Mac builds - * already send people with `/?ref=…#pricing`. What "native" means sits under - * the actions, beside the pricing line, not in the identity copy. - * * The two actions are a row of cells across the page grid, the hero's one * piece of the frame (design-system §4.7); the headline above them stays * unlined. @@ -35,13 +30,20 @@ interface HeroProps { */ export default function Hero({ content, availability, featuredEngines }: HeroProps) { const shown = useShownSlot(); + const { fmt, m } = useI18n(); + const devices = joinList( + availablePlatforms().flatMap((platform) => + platform.deviceNames.map((name) => platform.status === 'beta' ? `${name} (${m.platforms.status.beta})` : name), + ), + m.common.list, + ); return (

- {content.title} + {fmt(content.title, { devices })}

)} + + {linux !== null && ( +
+

+ {fmt(content.cardTitle, { devices: linuxDevices })} + {linux.status === 'beta' && {m.platforms.status.beta}} +

+

{content.linux}

+

+ + {fmt(content.cardTitle, { devices: linuxDevices })} + + +

+
+ )}
); diff --git a/resources/js/components/site/site-links.ts b/resources/js/components/site/site-links.ts index 6ad7c31d..eeb8482d 100644 --- a/resources/js/components/site/site-links.ts +++ b/resources/js/components/site/site-links.ts @@ -57,14 +57,17 @@ export interface PlatformPage { } /** - * One link per released platform that has a page of its own: today `/ios`, - * labelled "iPhone & iPad". The Mac's page is /download, which the header - * already links. A platform that ships with a page gets its link from data. + * One link per released or beta platform that has a page of its own: `/ios`, + * labelled "iPhone & iPad", and `/linux`. The Mac's page is /download, which + * the header already links. A platform that ships with a page gets its link + * from data. */ export const PLATFORM_PAGES: PlatformPage[] = platformData.platforms.flatMap((candidate) => { - const platform = releasedPlatform(candidate.id); + const available = candidate.status === 'released' || candidate.status === 'beta'; - return platform?.page ? [{ id: platform.id, href: platform.page, deviceNames: platform.deviceNames }] : []; + return available && typeof candidate.page === 'string' && candidate.deviceNames + ? [{ id: candidate.id, href: candidate.page, deviceNames: candidate.deviceNames }] + : []; }); /** External destinations, from facts.json. */ diff --git a/resources/js/i18n/messages/de/platforms.ts b/resources/js/i18n/messages/de/platforms.ts index a5141fe8..b8f2e8a5 100644 --- a/resources/js/i18n/messages/de/platforms.ts +++ b/resources/js/i18n/messages/de/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Kostenlos, ohne In-App-Käufe", "status": { "released": "Verfügbar", + "beta": "Beta", "prototype": "Nur ein Prototyp. Nichts zum Installieren und kein Erscheinungstermin.", "none": "Nicht verfügbar, kein Erscheinungstermin." }, diff --git a/resources/js/i18n/messages/en/platforms.ts b/resources/js/i18n/messages/en/platforms.ts index 21fb75b0..c64f47f6 100644 --- a/resources/js/i18n/messages/en/platforms.ts +++ b/resources/js/i18n/messages/en/platforms.ts @@ -30,6 +30,7 @@ export default { free: 'Free, with no in-app purchases', status: { released: 'Available', + beta: 'Beta', prototype: 'A prototype only. Nothing to install, and no release date.', none: 'Not available, and no release date.', }, diff --git a/resources/js/i18n/messages/es/platforms.ts b/resources/js/i18n/messages/es/platforms.ts index f2cd63c7..1016d77d 100644 --- a/resources/js/i18n/messages/es/platforms.ts +++ b/resources/js/i18n/messages/es/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Gratis, sin compras dentro de la app", "status": { "released": "Disponible", + "beta": "Beta", "prototype": "Solo un prototipo. No hay nada que instalar ni fecha de lanzamiento.", "none": "No disponible, sin fecha de lanzamiento." }, diff --git a/resources/js/i18n/messages/fr/platforms.ts b/resources/js/i18n/messages/fr/platforms.ts index b04f1e4b..fa743ba0 100644 --- a/resources/js/i18n/messages/fr/platforms.ts +++ b/resources/js/i18n/messages/fr/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Gratuit, sans achats intégrés", "status": { "released": "Disponible", + "beta": "Bêta", "prototype": "Un prototype uniquement. Rien à installer, aucune date de sortie.", "none": "Non disponible, aucune date de sortie." }, diff --git a/resources/js/i18n/messages/id/platforms.ts b/resources/js/i18n/messages/id/platforms.ts index a54e0b28..d3ada165 100644 --- a/resources/js/i18n/messages/id/platforms.ts +++ b/resources/js/i18n/messages/id/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Gratis, tanpa pembelian dalam aplikasi", "status": { "released": "Tersedia", + "beta": "Beta", "prototype": "Hanya prototipe. Tidak ada yang dapat diinstal dan tidak ada tanggal rilis.", "none": "Tidak tersedia dan tidak ada tanggal rilis." }, diff --git a/resources/js/i18n/messages/it/platforms.ts b/resources/js/i18n/messages/it/platforms.ts index 7c01468b..c0ffe9af 100644 --- a/resources/js/i18n/messages/it/platforms.ts +++ b/resources/js/i18n/messages/it/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Gratuita, senza acquisti in-app", "status": { "released": "Disponibile", + "beta": "Beta", "prototype": "Solo un prototipo. Nulla da installare e nessuna data di rilascio.", "none": "Non disponibile e nessuna data di rilascio." }, diff --git a/resources/js/i18n/messages/ja/platforms.ts b/resources/js/i18n/messages/ja/platforms.ts index 0c4738e3..b59d539c 100644 --- a/resources/js/i18n/messages/ja/platforms.ts +++ b/resources/js/i18n/messages/ja/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "無料、アプリ内課金なし", "status": { "released": "利用可能", + "beta": "ベータ版", "prototype": "プロトタイプのみです。インストールできるものはなく、リリース日の予定もありません。", "none": "提供していません。リリース日の予定もありません。" }, diff --git a/resources/js/i18n/messages/ko/platforms.ts b/resources/js/i18n/messages/ko/platforms.ts index 2662a2f3..e1569fb4 100644 --- a/resources/js/i18n/messages/ko/platforms.ts +++ b/resources/js/i18n/messages/ko/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "무료, 앱 내 구입 없음", "status": { "released": "사용 가능", + "beta": "베타", "prototype": "프로토타입만 있습니다. 설치할 수 있는 앱과 출시 일정은 없습니다.", "none": "제공되지 않으며 출시 일정도 없습니다." }, diff --git a/resources/js/i18n/messages/pt-BR/platforms.ts b/resources/js/i18n/messages/pt-BR/platforms.ts index 22c13d16..c1d059d2 100644 --- a/resources/js/i18n/messages/pt-BR/platforms.ts +++ b/resources/js/i18n/messages/pt-BR/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "Grátis, sem compras no app", "status": { "released": "Disponível", + "beta": "Beta", "prototype": "Apenas um protótipo. Nada para instalar, sem data de lançamento.", "none": "Indisponível, sem data de lançamento." }, diff --git a/resources/js/i18n/messages/vi/platforms.ts b/resources/js/i18n/messages/vi/platforms.ts index 27244dd3..58cb26e3 100644 --- a/resources/js/i18n/messages/vi/platforms.ts +++ b/resources/js/i18n/messages/vi/platforms.ts @@ -22,6 +22,7 @@ export default { free: 'Miễn phí, không có mua hàng trong ứng dụng', status: { released: 'Đã phát hành', + beta: 'Beta', prototype: 'Chỉ có bản prototype. Không có gì để cài đặt và không có ngày phát hành.', none: 'Không có bản cài đặt, và không có ngày phát hành.', }, diff --git a/resources/js/i18n/messages/zh-Hans/platforms.ts b/resources/js/i18n/messages/zh-Hans/platforms.ts index 572a630d..645c0654 100644 --- a/resources/js/i18n/messages/zh-Hans/platforms.ts +++ b/resources/js/i18n/messages/zh-Hans/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "免费,无应用内购买", "status": { "released": "已推出", + "beta": "测试版", "prototype": "仅有原型。没有可安装的版本,也没有发布日期。", "none": "不提供,也没有发布日期。" }, diff --git a/resources/js/i18n/messages/zh-Hant/platforms.ts b/resources/js/i18n/messages/zh-Hant/platforms.ts index bb1202d0..8d1b6d81 100644 --- a/resources/js/i18n/messages/zh-Hant/platforms.ts +++ b/resources/js/i18n/messages/zh-Hant/platforms.ts @@ -22,6 +22,7 @@ export default { "free": "免費,無 App 內購買", "status": { "released": "已推出", + "beta": "測試版", "prototype": "僅有原型。沒有可安裝的版本,也沒有發佈日期。", "none": "不提供,也沒有發佈日期。" }, diff --git a/resources/js/lib/data/platforms.ts b/resources/js/lib/data/platforms.ts index 91626bfc..5a5fd20f 100644 --- a/resources/js/lib/data/platforms.ts +++ b/resources/js/lib/data/platforms.ts @@ -3,8 +3,9 @@ * needs, and where to get it. * * Only a `released` platform carries requirements, destinations and a - * release. Linux and Windows are listed with their status and nothing else, - * so no component can render a requirement, a button or a date for them. + * release. A `beta` platform (Linux) carries its page, packages and engines + * but no release or date. Any other platform is listed with its status and + * nothing else, so no component can render a button for it. * Every phrase around these values (the "or later" sentence, "Apple silicon", * "Mac app") is a `platforms` catalog entry; this module joins them. * @@ -18,7 +19,7 @@ import { joinList, type ListStyle } from '../../i18n/format.ts'; export type PlatformId = 'mac' | 'ios' | 'linux' | 'windows'; -export type PlatformStatus = 'released' | 'prototype' | 'none'; +export type PlatformStatus = 'released' | 'beta' | 'prototype' | 'none'; export type MacArchitecture = 'arm64' | 'x86_64'; @@ -83,6 +84,29 @@ export interface IosPlatform extends ReleasedPlatformBase { price: { amount: number; inAppPurchases: boolean }; } +export interface LinuxRepository { + kind: 'apt' | 'dnf'; + /** The distribution's name, never translated: `Ubuntu`. */ + system: string; + versions: string[]; + /** `Fedora 44 or later` rather than `Ubuntu 26.04 and 26.10`. */ + orLater: boolean; + beta: string[]; + stable: string[]; +} + +export interface LinuxPlatform { + id: 'linux'; + status: 'beta'; + deviceNames: string[]; + page: string; + architectures: string[]; + destinations: (LinuxRepository | { kind: 'releases'; url: string })[]; + /** Engine ids the Linux app connects to, in its order. Name them; never count them. */ + linuxEngines: string[]; + appLanguages: string[]; +} + export interface UnreleasedPlatform { id: 'linux' | 'windows'; status: 'prototype' | 'none'; @@ -90,7 +114,10 @@ export interface UnreleasedPlatform { export type ReleasedPlatform = MacPlatform | IosPlatform; -export type Platform = ReleasedPlatform | UnreleasedPlatform; +/** A platform with something to install, a beta included. */ +export type AvailablePlatform = ReleasedPlatform | LinuxPlatform; + +export type Platform = AvailablePlatform | UnreleasedPlatform; export interface PlatformsData { verifiedAt: string; @@ -115,11 +142,40 @@ export function isReleased(platform: Platform): platform is ReleasedPlatform { return platform.status === 'released'; } +export function isAvailable(platform: Platform): platform is AvailablePlatform { + return platform.status === 'released' || platform.status === 'beta'; +} + /** Every platform with something to install, in data order. */ +export function availablePlatforms(): AvailablePlatform[] { + return PLATFORMS.platforms.filter(isAvailable); +} + +/** Released platforms with version metadata. */ export function releasedPlatforms(): ReleasedPlatform[] { return PLATFORMS.platforms.filter(isReleased); } +/** The Linux app while it has something to install, else null. */ +export function linuxPlatform(): LinuxPlatform | null { + const linux = PLATFORMS.platforms.find((platform) => platform.id === 'linux'); + + return linux !== undefined && isAvailable(linux) ? (linux as LinuxPlatform) : null; +} + +export function linuxRepositories(linux: LinuxPlatform): LinuxRepository[] { + return linux.destinations.filter((entry): entry is LinuxRepository => entry.kind === 'apt' || entry.kind === 'dnf'); +} + +/** `Ubuntu 26.04 and 26.10`, `Fedora 44 or later`. */ +export function distributionText(repository: LinuxRepository, strings: PlatformStrings, style: ListStyle): string { + if (repository.orLater) { + return interpolate(strings.requirement.unnamed, { systems: repository.system, version: repository.versions[0] ?? '' }); + } + + return `${repository.system} ${joinList(repository.versions, style)}`; +} + export function macPlatform(): MacPlatform { return find('mac') as MacPlatform; } @@ -172,7 +228,7 @@ export function architecturesText(strings: PlatformStrings): string { ); } -/** `Mac, iPhone and iPad`: every released platform's devices, joined with the locale's list style. */ +/** The released Apple apps used by the existing engine and feature pages. */ export function deviceList(style: ListStyle): string { return joinList( releasedPlatforms().flatMap((platform) => platform.deviceNames), @@ -181,7 +237,7 @@ export function deviceList(style: ListStyle): string { } /** One platform's devices: `iPhone and iPad`, or `iPhone & iPad` with the short list style. */ -export function devicesOf(platform: ReleasedPlatform, style: ListStyle): string { +export function devicesOf(platform: AvailablePlatform, style: ListStyle): string { return joinList(platform.deviceNames, style); } diff --git a/resources/js/pages/Download.tsx b/resources/js/pages/Download.tsx index 44cf0c64..f0f5d4f1 100644 --- a/resources/js/pages/Download.tsx +++ b/resources/js/pages/Download.tsx @@ -10,12 +10,13 @@ import PageHeader from '@/components/ui/page-header'; import Section from '@/components/ui/section'; import TextLink, { textLinkClasses } from '@/components/ui/text-link'; import { requirementLine } from '@/components/download/format'; +import Badge from '@/components/ui/badge'; import IosCard from '@/components/download/ios-card'; import MacCard, { UI_TAGS } from '@/components/download/mac-card'; import type { DownloadPageProps } from '@/components/download/types'; import { LOCALES, Trans, useI18n, type Messages } from '@/i18n'; import { joinList, keepTogether } from '@/i18n/format'; -import { architecturesText } from '@/lib/data/platforms'; +import { architecturesText, linuxPlatform } from '@/lib/data/platforms'; import { PRICING } from '@/lib/data/pricing'; import { appStoreFirst, classifyDevice, type DeviceKind } from '@/lib/device'; import { absoluteUrl, graph, iosAppNode, macAppId, macAppNode, webPageNode, type JsonLdGraph } from '@/lib/structured-data'; @@ -180,6 +181,16 @@ export default function Download({ content, release, mac, ios, unreleased, links + {linuxPlatform() !== null && ( +
+ {m.platforms.status.beta} +

{content.linux.body}

+ + {content.linux.link} + +
+ )} + {/* What to do after the download: one section each, so the page frame's joins separate them (design-system §4.7). */}
diff --git a/resources/js/pages/Linux.tsx b/resources/js/pages/Linux.tsx new file mode 100644 index 00000000..fecdb281 --- /dev/null +++ b/resources/js/pages/Linux.tsx @@ -0,0 +1,138 @@ +import { usePage } from '@inertiajs/react'; +import CommandBlock from '@/components/download/command-block'; +import type { SiteLinks } from '@/components/faq/content-links'; +import SEOHead from '@/components/seo/seo-head'; +import Badge from '@/components/ui/badge'; +import LocaleLink from '@/components/ui/locale-link'; +import PageHeader from '@/components/ui/page-header'; +import Section from '@/components/ui/section'; +import TextLink, { textLinkClasses } from '@/components/ui/text-link'; +import { LOCALES, Trans, useI18n } from '@/i18n'; +import { joinList } from '@/i18n/format'; +import { PUBLISHER } from '@/lib/data/facts'; +import { distributionText, linuxPlatform, linuxRepositories } from '@/lib/data/platforms'; +import { absoluteUrl, graph, organizationNode, webPageNode } from '@/lib/structured-data'; +import LandingLayout from '@/layouts/landing-layout'; + +type LinuxContent = typeof import('@data/content/en/linux.json'); + +interface LinuxProps { + content: LinuxContent; + /** The engines the Linux app connects to, empty while it has nothing to install. */ + engines: { id: string; name: string; href: string | null }[]; + links: SiteLinks; + organizationProfiles: string[]; +} + +export default function Linux({ content, engines, links, organizationProfiles }: LinuxProps) { + const { canonicalBaseUrl } = usePage().props; + const { locale, m, fmt, path } = useI18n(); + const linux = linuxPlatform(); + const repositories = linux !== null ? linuxRepositories(linux) : []; + const releases = linux?.destinations.find((entry) => entry.kind === 'releases') ?? null; + const context = { baseUrl: canonicalBaseUrl, inLanguage: LOCALES.supported[locale].hreflang }; + + const jsonLd = graph([ + organizationNode(canonicalBaseUrl, { description: m.seo.product.short, sameAs: organizationProfiles, publisher: PUBLISHER }), + webPageNode(context, { + url: absoluteUrl(canonicalBaseUrl, path('/linux')), + name: content.seo.title, + description: content.seo.description, + }), + ]); + + return ( + + + + +
+ {linux !== null && {m.platforms.status.beta}} +
+
+ + {linux !== null && ( +
+
+

+ {fmt(content.install.lead, { architectures: joinList(linux.architectures, m.common.list) })} +

+ + {repositories.map((repository) => ( +
+

{distributionText(repository, m.platforms, m.common.list)}

+
+ +
+
+ ))} + +
+

{content.install.stable.title}

+

{content.install.stable.body}

+
+ {repositories.map((repository) => ( + + ))} +
+
+ + {releases !== null && 'url' in releases && ( +
+

{content.install.releases.title}

+

+ ( + + {text} + + ), + }} + /> +

+
+ )} + + {links.docs !== null && ( +

+ + {content.install.guide.label} + +

+ )} + +
+
+ )} + + {engines.length > 0 && ( +
+
    + {engines.map((engine) => ( +
  • + {engine.href !== null ? ( + + {engine.name} + + ) : ( + engine.name + )} +
  • + ))} +
+
+ )} +
+ ); +} diff --git a/routes/localized.php b/routes/localized.php index 95259c6b..85443246 100644 --- a/routes/localized.php +++ b/routes/localized.php @@ -12,6 +12,7 @@ use App\Http\Controllers\IntegrationController; use App\Http\Controllers\IosController; use App\Http\Controllers\LegalController; +use App\Http\Controllers\LinuxController; use App\Http\Controllers\PricingController; use App\Http\Controllers\SecurityController; use App\Http\Controllers\SponsorsController; @@ -38,7 +39,7 @@ | app/Support/Content/Slugs, never from a content directory read here. | `route:cache` rebuilds only when PHP changes, so a slug that existed only | as a file would ship without a route. -| 2. No root-level path may equal a locale prefix (`vi`), and `ios`, `features`, +| 2. No root-level path may equal a locale prefix (`vi`), and `ios`, `linux`, `features`, | `databases`, `compare`, `integrations`, `pricing` and `brand` must never | join the database slugs. LocaleRoutingTest and SiteDataTest guard both. | 3. The blog and integration slugs stay patterns: whether a post or an @@ -57,6 +58,7 @@ Route::get('/', HomeController::class)->name('landing.home'); Route::get('/download', DownloadController::class)->name('landing.download'); Route::get('/ios', IosController::class)->name('landing.ios'); +Route::get('/linux', LinuxController::class)->name('landing.linux'); Route::get('/pricing', PricingController::class)->name('landing.pricing'); Route::get('/faq', FaqController::class)->name('landing.faq'); Route::get('/about', AboutController::class)->name('landing.about'); diff --git a/tests/Feature/Data/PlatformsDataTest.php b/tests/Feature/Data/PlatformsDataTest.php index 40a4388d..e66c9e0f 100644 --- a/tests/Feature/Data/PlatformsDataTest.php +++ b/tests/Feature/Data/PlatformsDataTest.php @@ -22,12 +22,19 @@ function platformsEntry(string $id): array ->and(platformsEntry('mac')['status'])->toBe('released'); foreach (platformsJson()['platforms'] as $platform) { - expect($platform['status'])->toBeIn(['released', 'prototype', 'none']); + expect($platform['status'])->toBeIn(['released', 'beta', 'prototype', 'none']); } }); it('gives a released platform everything a page needs and an unreleased one nothing', function (): void { foreach (platformsJson()['platforms'] as $platform) { + if ($platform['status'] === 'beta') { + expect($platform)->toHaveKeys(['deviceNames', 'page', 'destinations', 'appLanguages']) + ->not->toHaveKeys(['release', 'requirements']); + + continue; + } + if ($platform['status'] !== 'released') { expect(array_keys($platform))->toBe(['id', 'status'], "{$platform['id']} is not released, so it carries nothing else"); diff --git a/tests/Feature/Pages/PagesTest.php b/tests/Feature/Pages/PagesTest.php index 064b5064..4246ae2a 100644 --- a/tests/Feature/Pages/PagesTest.php +++ b/tests/Feature/Pages/PagesTest.php @@ -20,6 +20,7 @@ function pageFamilies(): array 'landing.home' => ['Home', ['content.hero.title', 'engines.0.path', 'apiOrigin', 'iosEngines']], 'landing.download' => ['Download', ['content', 'mac', 'release', 'unreleased']], 'landing.ios' => ['Ios', ['content', 'ios', 'engines']], + 'landing.linux' => ['Linux', ['content', 'engines', 'links']], 'landing.pricing' => ['Pricing', ['content', 'apiOrigin', 'paidFeatures']], 'landing.teams' => ['Teams', ['content.header.title', 'content.seats.items', 'organizationProfiles']], 'landing.faq' => ['Faq', ['content', 'facts', 'platforms']],