feat: implement native subdomain routing (*.hub.yesminedor.tn) for seamless absolute assets resolution across all universes
This commit is contained in:
+25
-14
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Hermes Hub — Client-side Workspace Switcher & Context Manager
|
||||
* Garantit l'isolation stricte du state front-end entre univers
|
||||
* Intègre le sélecteur toggle DSH (Session vs Explorateur de fichiers)
|
||||
* Routage natif par sous-domaine (tt.hub.yesminedor.tn, nyora.hub..., perso.hub..., nabil.hub..., dsh.hub...)
|
||||
* Résout à 100% le chargement des assets absolus sans réécriture fragile
|
||||
*/
|
||||
|
||||
(function () {
|
||||
@@ -40,6 +40,26 @@
|
||||
}
|
||||
|
||||
function getTargetUrl(universeId, mode) {
|
||||
const hostname = window.location.hostname;
|
||||
|
||||
// 1. Production *.hub.yesminedor.tn (Routage par sous-domaine natif)
|
||||
if (hostname === "hub.yesminedor.tn" || hostname.endsWith(".hub.yesminedor.tn")) {
|
||||
if (universeId === "nabil" && mode === "files") {
|
||||
return "https://dsh.hub.yesminedor.tn/";
|
||||
}
|
||||
return `https://${universeId}.hub.yesminedor.tn/`;
|
||||
}
|
||||
|
||||
// 2. Test local *.localhost
|
||||
if (hostname.endsWith(".localhost") || hostname === "localhost") {
|
||||
const port = window.location.port ? `:${window.location.port}` : "";
|
||||
if (universeId === "nabil" && mode === "files") {
|
||||
return `${window.location.protocol}//dsh.localhost${port}/`;
|
||||
}
|
||||
return `${window.location.protocol}//${universeId}.localhost${port}/`;
|
||||
}
|
||||
|
||||
// 3. Fallback IP direct / chemin relatif (pour tests curl/SSH)
|
||||
if (universeId === "nabil" && mode === "files") {
|
||||
return "/u/nabil/files/";
|
||||
}
|
||||
@@ -77,13 +97,12 @@
|
||||
if (!btn) return;
|
||||
|
||||
// 1. ISOLATION TOTALE DU STATE CLIENT
|
||||
// Décharger immédiatement l'iframe précédente pour purger la mémoire JS
|
||||
loader.classList.remove("hidden");
|
||||
iframe.src = "about:blank";
|
||||
|
||||
// 2. Mettre à jour l'univers actif
|
||||
activeUniverse = universeId;
|
||||
activeMode = "session"; // Réinitialiser le mode à session par défaut
|
||||
activeMode = "session";
|
||||
|
||||
// 3. Mettre à jour la classe active sur la sidebar
|
||||
document.querySelectorAll(".hub-universe-btn").forEach((el) => el.classList.remove("active"));
|
||||
@@ -106,7 +125,6 @@
|
||||
if (nabilModeToggle) {
|
||||
if (supportsFiles) {
|
||||
nabilModeToggle.classList.add("visible");
|
||||
// Reset tabs visual state
|
||||
if (tabSession && tabFiles) {
|
||||
tabSession.classList.add("active");
|
||||
tabSession.setAttribute("aria-selected", "true");
|
||||
@@ -118,7 +136,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Charger le nouvel univers via le proxy dédié
|
||||
// 7. Charger le nouvel univers via son sous-domaine dédié
|
||||
setTimeout(() => {
|
||||
iframe.src = getTargetUrl(activeUniverse, activeMode);
|
||||
}, 50);
|
||||
@@ -143,7 +161,7 @@
|
||||
data.forEach((u) => {
|
||||
const dot = document.getElementById(`status-dot-${u.id}`);
|
||||
if (dot) {
|
||||
if (u.health && u.health.status === "online") {
|
||||
if (u.health && (u.health.status === "online" || u.health.status_code === 200 || u.health.status_code === 302)) {
|
||||
dot.className = "hub-status-dot online";
|
||||
dot.title = `En ligne (${u.health.latency_ms}ms)`;
|
||||
} else {
|
||||
@@ -234,7 +252,6 @@
|
||||
|
||||
// Setup Event Listeners
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Boutons de changement d'univers
|
||||
document.querySelectorAll(".hub-universe-btn").forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
const uId = btn.dataset.universe;
|
||||
@@ -242,17 +259,14 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Toggle Mode DSH (Session vs Files)
|
||||
tabSession?.addEventListener("click", () => setMode("session"));
|
||||
tabFiles?.addEventListener("click", () => setMode("files"));
|
||||
|
||||
// Outils Footer
|
||||
document.getElementById("btn-edit-persona")?.addEventListener("click", openPersonaModal);
|
||||
document.getElementById("btn-clone-universe")?.addEventListener("click", openCloneModal);
|
||||
document.getElementById("btn-save-persona")?.addEventListener("click", savePersona);
|
||||
document.getElementById("btn-submit-clone")?.addEventListener("click", submitClone);
|
||||
|
||||
// Boutons fermer modales
|
||||
document.querySelectorAll(".hub-modal-close").forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
personaModal.classList.remove("open");
|
||||
@@ -260,10 +274,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Démarrage : activer le premier univers (TT)
|
||||
switchUniverse("tt");
|
||||
|
||||
// Lancer la vérification de santé
|
||||
refreshHealthStatus();
|
||||
setInterval(refreshHealthStatus, 15000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user