mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-04-27 06:25:41 +00:00
feat(docs): update Reticulum documentation links to use dynamic URLs based on locale
This commit is contained in:
@@ -11687,9 +11687,9 @@ class ReticulumMeshChat:
|
||||
dm = self.current_context.docs_manager
|
||||
|
||||
async def reticulum_docs_handler(request):
|
||||
path = request.match_info.get("filename", "index.html")
|
||||
path = request.match_info.get("filename", "manual/index.html")
|
||||
if not path:
|
||||
path = "index.html"
|
||||
path = "manual/index.html"
|
||||
if path.endswith("/"):
|
||||
path += "index.html"
|
||||
|
||||
|
||||
@@ -511,7 +511,7 @@
|
||||
{{ $t("tutorial.meshchatx_docs") }}
|
||||
</a>
|
||||
<a
|
||||
href="/reticulum-docs/index.html"
|
||||
:href="reticulumBundledDocsUrl"
|
||||
target="_blank"
|
||||
class="px-3 py-1 text-[10px] rounded-xl border border-gray-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300 font-semibold shadow-sm transition-all hover:bg-gray-50 dark:hover:bg-zinc-700 hover:border-blue-400 dark:hover:border-blue-500 inline-block"
|
||||
>
|
||||
@@ -1180,7 +1180,7 @@
|
||||
{{ $t("tutorial.read_meshchatx_docs") }}
|
||||
</a>
|
||||
<a
|
||||
href="/reticulum-docs/index.html"
|
||||
:href="reticulumBundledDocsUrl"
|
||||
target="_blank"
|
||||
class="h-12 rounded-xl border border-gray-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300 font-semibold shadow-sm transition-all hover:bg-gray-50 dark:hover:bg-zinc-700 hover:border-blue-400 dark:hover:border-blue-500 inline-flex items-center justify-center px-6"
|
||||
>
|
||||
@@ -1358,6 +1358,7 @@ import logoUrl from "../assets/images/logo.png";
|
||||
import ToastUtils from "../js/ToastUtils";
|
||||
import DialogUtils from "../js/DialogUtils";
|
||||
import GlobalState from "../js/GlobalState";
|
||||
import { bundledReticulumDocsUrl } from "../js/reticulumDocsEntryUrl.js";
|
||||
import LanguageSelector from "./LanguageSelector.vue";
|
||||
import MaterialDesignIcon from "./MaterialDesignIcon.vue";
|
||||
|
||||
@@ -1420,6 +1421,9 @@ export default {
|
||||
selectedBootstrapCount() {
|
||||
return this.selectedBootstrapKeys.length;
|
||||
},
|
||||
reticulumBundledDocsUrl() {
|
||||
return bundledReticulumDocsUrl(this.$i18n.locale);
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.onWindowResize) {
|
||||
|
||||
@@ -488,6 +488,7 @@
|
||||
<!-- Reticulum Docs View -->
|
||||
<iframe
|
||||
v-if="activeTab === 'reticulum' && status.has_docs && !searchQuery"
|
||||
:key="localDocsUrl"
|
||||
ref="docsFrame"
|
||||
:src="localDocsUrl"
|
||||
class="w-full h-full border-none opacity-0 transition-opacity duration-1000"
|
||||
@@ -522,6 +523,8 @@
|
||||
<script>
|
||||
import MaterialDesignIcon from "../MaterialDesignIcon.vue";
|
||||
import ToastUtils from "../../js/ToastUtils";
|
||||
import GlobalState from "../../js/GlobalState";
|
||||
import { bundledReticulumDocsUrl } from "../../js/reticulumDocsEntryUrl.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -572,12 +575,7 @@ export default {
|
||||
if (this.selectedReticulumPath) {
|
||||
return `/reticulum-docs/${this.selectedReticulumPath}`;
|
||||
}
|
||||
const lang = this.currentLang;
|
||||
if (lang === "en") return "/reticulum-docs/index.html";
|
||||
if (Object.keys(this.languages).includes(lang)) {
|
||||
return `/reticulum-docs/index_${lang}.html`;
|
||||
}
|
||||
return "/reticulum-docs/index.html";
|
||||
return bundledReticulumDocsUrl(this.currentLang);
|
||||
},
|
||||
allLanguages() {
|
||||
return Object.entries(this.languages).map(([code, name]) => ({
|
||||
@@ -723,7 +721,8 @@ export default {
|
||||
await window.api.patch("/api/v1/config", {
|
||||
language: langCode,
|
||||
});
|
||||
// The app will update automatically via websocket config sync
|
||||
this.$i18n.locale = langCode;
|
||||
GlobalState.config.language = langCode;
|
||||
} catch (error) {
|
||||
console.error("Failed to update language:", error);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Locales that ship a localized root index (index_<locale>.html) in the
|
||||
* Reticulum website bundle. The Sphinx manual itself is English-only under
|
||||
* manual/; other locales use these pages like the public site.
|
||||
*/
|
||||
const BUNDLED_RETICULUM_SITE_INDEX_LOCALES = new Set(["de", "es", "jp", "nl", "pl", "pt-br", "tr", "uk", "zh-cn"]);
|
||||
|
||||
/**
|
||||
* @param {string | undefined} locale
|
||||
* @returns {string} path relative to /reticulum-docs/ (no leading slash)
|
||||
*/
|
||||
export function bundledReticulumDocsEntryPath(locale) {
|
||||
const lang = (locale || "en").toLowerCase();
|
||||
if (lang === "en") {
|
||||
return "manual/index.html";
|
||||
}
|
||||
if (BUNDLED_RETICULUM_SITE_INDEX_LOCALES.has(lang)) {
|
||||
return `index_${lang}.html`;
|
||||
}
|
||||
return "manual/index.html";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} locale
|
||||
* @returns {string} absolute app path for the default bundled Reticulum docs view
|
||||
*/
|
||||
export function bundledReticulumDocsUrl(locale) {
|
||||
return `/reticulum-docs/${bundledReticulumDocsEntryPath(locale)}`;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ describe("DocsPage.vue", () => {
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.find("iframe").exists()).toBe(true);
|
||||
expect(wrapper.find("iframe").attributes("src")).toBe("/reticulum-docs/index.html");
|
||||
expect(wrapper.find("iframe").attributes("src")).toBe("/reticulum-docs/manual/index.html");
|
||||
});
|
||||
|
||||
it("shows progress bar while extracting an upload", async () => {
|
||||
@@ -197,7 +197,7 @@ describe("DocsPage.vue", () => {
|
||||
expect(wrapper.vm.status.last_error).toBeNull();
|
||||
});
|
||||
|
||||
it("changes localDocsUrl based on locale", async () => {
|
||||
it("opens the Sphinx manual for English and localized site index for other locales", async () => {
|
||||
const wrapper = mountDocsPage();
|
||||
await nextTick();
|
||||
|
||||
@@ -207,7 +207,7 @@ describe("DocsPage.vue", () => {
|
||||
|
||||
i18nMock.locale = "en";
|
||||
await nextTick();
|
||||
expect(wrapper.vm.localDocsUrl).toBe("/reticulum-docs/index.html");
|
||||
expect(wrapper.vm.localDocsUrl).toBe("/reticulum-docs/manual/index.html");
|
||||
});
|
||||
|
||||
it("handles extremely long error messages in the UI", async () => {
|
||||
|
||||
Reference in New Issue
Block a user